[英]Where should I place the onClickListener on a Custom ListView?
我正在制作包含CheckBox
和TextView
的行的自定義ListView
。 在我使用SimpleCursorAdapter自定義ListViews
之前,我的onListItemClick()
工作正常。
我已經閱讀過我必須在我的TextViews
添加一個onClickListener
但是在哪里? 為什么?
我仍然在擴展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);
}
編輯:我的問題是使自定義ListView
的整個項目可點擊,所以我發現最好的答案是@Luksprog給出的答案。 該onListItemClick
從我ListActivity
就足夠了。 我只需要設置android:focusable='false'
就可以了。
現在, ListView
每個項目上的CheckBox
應該“標記”該項目,這意味着訪問數據庫。
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()
引用了非final變量,如果我更改它v = vi.inflate(R.layout.puzzles_row, null)
則無法分配v = vi.inflate(R.layout.puzzles_row, null)
。 解決這個問題的最佳方法是什么? 我從未真正了解整個最終交易。
如果要從ListView
任何行單擊TextView
或/和CheckBox
時添加特殊操作,請在自定義Adapter
的getView
方法中為這些Views
添加OnCLickListener
:
@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;
}
如果要在單擊行時執行操作(無論單擊該行中的哪個View
(如果單擊了一個)),只需使用ListView
上的OnItemClickListener
(或者在onListItemClick
的情況下使用回調ListActivity
)。
另外,我希望你為CheckBox
設置android:focusable="false"
(在R.layout.puzzles_row
),因為我不認為onListItemClick
會起作用。
編輯:
你開始新的Activity
在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);
}
如果出於某種原因,當用戶僅單擊(例如) ListView
行中的TextView
時,您希望啟動新的Activity
,則從上面的代碼中啟動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
從列puzzlesCursor
光標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>);
}
您應該在ListView上實現onItemClickListener 。
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
});
僅在適配器中使用onClick Listner。 在您的適配器中,您將返回v,它是對象的視圖kiond。 把你的onCLickListener放在那里。
egvsetOnCLickListener。
我記住你想要點擊視圖打開一個活動。 是的,如果您的ListedPuzzle類是可序列化的或可分區的,您可以使用putextra intent來轉發整個對象。
如果您不清楚答案,請告訴我,我將為您提供一些小碼代碼段
lstviewemojis.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.