Where should I place the onClickListener in a custom ListView?

I am creating a custom ListView rows containing a CheckBox and a TextView . Before I used custom ListViews with SimpleCursorAdapter, my onListItemClick() worked fine.

I read that I need to add onClickListener to my TextViews , but WHERE? AND WHY?

I am still continuing with ListActivity and passing the Adapter to setListAdapter(listedPuzzleAdapter); , I do not?

 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: My question was to make the whole element of a custom ListView clickable, so I found that the best answer was the one given by @Luksprog. onListItemClick from my ListActivity was enough. I just needed to set android:focusable='false' for it to work.

Now the CheckBox for each ListView item should โ€œshowโ€ this item, which means access to the database.

 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; } 

But v.getTag() refers to a non-final variable, and if I change it, then v = vi.inflate(R.layout.puzzles_row, null) cannot be assigned. What is the best way to solve this problem? I never understood the whole final deal.

+4
source share
5 answers

If you want to add a special action when you click a TextView or / and CheckBox from any of the lines in the ListView , then add an OnCLickListener for these Views to the getView your custom 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; } 

If you want to do an action when a row is clicked (regardless of what View clicked from that row (if it was clicked)) just use OnItemClickListener on the ListView (or onListItemClick in case of a ListActivity ).

In addition, I hope that you set android:focusable="false" for CheckBox (in R.layout.puzzles_row ), because I do not think that onListItemClick will work differently.

Edit:

You start a new Activity in onListItemClick (in the case of a ListActivity ) if you want to start a new action no matter where the user clicks on the line :

 @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); } 

If for some reason you want to start a new Activity when the user clicks only (for example) TextView on the ListView line, then run the new action in the onClick method from my code above:

 //... 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); } //... 

To do this, you will need to modify the ListedPuzzle to add the PuzzlesDbAdapter.KEY_ROWID column from the puzzlesCursor cursor in the fetchData() method:

 //... 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); //... 
+3
source

you can assign onClickListener in the adapter, but this is bad practice.

what you have to do is implement onItemClick as follows:

 @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>); } 
+2
source

You must implement onItemClickListener in your ListView.

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

Use onClick Listner only in the adapter. In your adapter, you return v, which is the view kiond of the object. Put your onCLickListener there.

eg. v.setOnCLickListener.

I remember that you want to open an event by clicking. And yes, if your ListedPuzzle class is serializable or picky, you can redirect the entire object using the putextra method of intent from the same.

If itโ€™s not clear to you, answer me, I will give you a piece of samll code

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

Source: https://habr.com/ru/post/1412763/


All Articles