Где я должен разместить onClickListener в пользовательском ListView?

Я создаю пользовательский ListView строк, содержащих CheckBox и TextView . До того, как я использовал пользовательские ListViews с SimpleCursorAdapter, мой onListItemClick() работал отлично.

Я читал, что мне нужно добавить onClickListener в мои onClickListener но WHERE? И почему?

Я все еще расширяю ListActivity и ListActivity Adapter для setListAdapter(listedPuzzleAdapter); , разве я не?

 public class PuzzleListActivity extends ListActivity { private PuzzlesDbAdapter mDbHelper; private Cursor puzzlesCursor; private ArrayList<ListedPuzzle> listedPuzzles = null; private ListedPuzzleAdapter listedPuzzleAdapter; private class ListedPuzzleAdapter extends ArrayAdapter<ListedPuzzle> { private ArrayList<ListedPuzzle> items; public ListedPuzzleAdapter(Context context, int textViewResourceId, ArrayList<ListedPuzzle> items) { super(context, textViewResourceId, items); this.items = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); } return v; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.puzzles_list); // Create database helper to open connection mDbHelper = new PuzzlesDbAdapter(this); mDbHelper.open(); fetchData(); } private void fetchData() { puzzlesCursor = mDbHelper.fetchAllPuzzles(); startManagingCursor(puzzlesCursor); listedPuzzles = new ArrayList<ListedPuzzle>(); ListedPuzzle lp; puzzlesCursor.moveToFirst(); while (!puzzlesCursor.isAfterLast()) { lp = new ListedPuzzle(); lp.setTitle(puzzlesCursor.getString(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_TITLE))); lp.setStarred(puzzlesCursor.getInt(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_STARRED)) > 0); listedPuzzles.add(lp); puzzlesCursor.moveToNext(); } listedPuzzleAdapter = new ListedPuzzleAdapter(this, R.layout.puzzles_row, listedPuzzles); setListAdapter(listedPuzzleAdapter); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, id); startActivity(i); } 

EDIT: Мой вопрос состоял в том, чтобы сделать весь элемент пользовательского ListView кликабельным, поэтому я нашел, что лучшим ответом является тот, который задан @Luksprog. onListItemClick из моего ListActivity . Мне просто нужно было установить android:focusable='false' чтобы он работал.

Теперь CheckBox для каждого элемента ListView должен «занести» этот элемент, а это значит, что доступ к БД.

 public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); star.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Integer realPosition = (Integer) v.getTag(); ListedPuzzle obj = items.get(realPosition); obj.getId(); } }); } return v; } 

Но v.getTag() ссылается на не конечную переменную, и если я ее изменю, то v = vi.inflate(R.layout.puzzles_row, null) не может быть назначено. Каков наилучший способ решить эту проблему? Я никогда не понимал всей последней сделки.

Solutions Collecting From Web of "Где я должен разместить onClickListener в пользовательском ListView?"

Если вы хотите добавить специальное действие, когда вы нажимаете TextView или / или CheckBox из любой из строк в ListView добавьте OnCLickListener для этих Views в метод getView вашего настраиваемого Adapter :

  @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); //set as the tag the position parameter title.setTag(new Integer(position)); title.setOnclickListener(new OnCLickListener(){ @Override public void onClick(View v) { // Do the stuff you want for the case when the row TextView is clicked // you may want to set as the tag for the TextView the position paremeter of the `getView` method and then retrieve it here Integer realPosition = (Integer) v.getTag(); // using realPosition , now you know the row where this TextView was clicked } }); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); } return v; } 

Если вы хотите выполнить действие при щелчке по строке (независимо от того, какой OnItemClickListener из этой строки (если был нажат)) просто используйте OnItemClickListener в ListView (или обратный вызов onListItemClick в случае ListActivity ).

Кроме того, я надеюсь, что вы установите android:focusable="false" для CheckBoxR.layout.puzzles_row ), потому что я не думаю, что onListItemClick будет работать иначе.

Редактировать :

Вы начинаете новое действие в onListItemClick (в случае ListActivity ), если хотите начать новое действие независимо от того, где пользователь нажимает на строку :

 @Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, id); startActivity(i); } 

Если по какой-то причине вы хотите запустить новое действие, когда пользователь нажимает только (например) TextView в строке ListView затем запускает новое действие в методе onClick из моего кода выше:

 //... title.setOnclickListener(new OnCLickListener(){ @Override public void onClick(View v) { Integer realPosition = (Integer) v.getTag(); ListedPuzzle obj = items.get(realPosition); Intent i = new Intent(this, PuzzleQuestionActivity.class); i.putExtra(PuzzlesDbAdapter.KEY_ROWID, obj.getTheId());//see below startActivity(i); } //... 

Для этого вам придется изменить ListedPuzzle чтобы добавить столбец PuzzlesDbAdapter.KEY_ROWID из курсора курсора курсора в fetchData() :

 //... while (!puzzlesCursor.isAfterLast()) { lp = new ListedPuzzle(); lp.setTitle(puzzlesCursor.getString(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_TITLE))); lp.setStarred(puzzlesCursor.getInt(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_STARRED)) > 0); lp.setTheId(puzzlesCursor.getLong(puzzlesCursor .getColumnIndex(PuzzlesDbAdapter.KEY_ROWID))); listedPuzzles.add(lp); //... 

Вы можете назначить onClickListener в адаптере, но это плохая практика.

Что вы должны сделать, это реализовать onItemClick следующим образом:

 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TextView text = parent.getItemAtPosition(position); // DO SOMETHING or in your case //startActivity(new Intent(<the correct intent>); } 

Вы должны реализовать onItemClickListener в своем ListView.

 ListView lv = getListView(); lv.setOnItemClickListener(new OnItemClickListener() { }); 

Используйте onClick Listner только в своем адаптере. В вашем адаптере вы возвращаете v, который представляет объект kiond объекта. Поместите туда свой onCLickListener.

egvsetOnCLickListener.

Я помню, что вы хотите открыть мероприятие по щелчку. И да, если ваш класс ListedPuzzle является сериализуемым или разборчивым, вы можете перенаправить весь объект, используя метод putextra намерения от такого же.

Если вам не ясно, ответьте мне, я дам вам фрагмент кода samll

  lstviewemojis.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { }