I am making a custom ListView of rows containing a CheckBox and a TextView. Before I used custom ListViews with SimpleCursorAdapter, my onListItemClick() worked fine.
I’ve read I have to add an onClickListener to my TextViews but WHERE? And WHY?
I am still extending ListActivity and passing an Adapter to setListAdapter(listedPuzzleAdapter);, am I 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 towards making the whole item of a custom ListView clickable so I found the best answer was the one given by @Luksprog. The onListItemClick from my ListActivity was enough. I just needed to set the android:focusable='false' to make it work.
Now, the CheckBox on each item of the ListView should “star” that item, which means, accesing the DB.
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 the v.getTag() refers to a non-final variable and if I change it the v = vi.inflate(R.layout.puzzles_row, null) cannot be assigned.
What’s the best way to solve this? I never really understood the whole final deal.
If you want to add a special action for when you click the
TextViewor/andCheckBoxfrom any of the rows in yourListViewthen add aOnCLickListenerfor thoseViewsin thegetViewmethod of your customAdapter:If you want to do an action when a row is clicked(no matter what
Viewfrom that row was clicked(if one was clicked)) just use theOnItemClickListeneron yourListView(or the callbackonListItemClickin the case of aListActivity).Also, I hope you set
android:focusable="false"for theCheckBox(inR.layout.puzzles_row) because I don’t thinkonListItemClickwill work otherwise.Edit :
You start the new
Activityin theonListItemClick(in the case of theListActivity) callback if you want to start the new activity no matter where the user clicks a row:If, for some reason, you want to start the new
Activitywhen the user clicks only(for example) theTextViewin aListViewrow then start the new activity in theonClickmethod from my code above:For this to work you’ll have to modify
ListedPuzzleto also add thePuzzlesDbAdapter.KEY_ROWIDcolumn from thepuzzlesCursorcursor in thefetchData()method: