处理自定义列表项单击导航抽屉 ListView 内
Posted
技术标签:
【中文标题】处理自定义列表项单击导航抽屉 ListView 内【英文标题】:Handling custom list items click inside a navigation drawer ListView 【发布时间】:2014-09-29 15:49:20 【问题描述】:我的导航抽屉中托管了 ListView 的自定义行,当我每行只有一个简单的 TextView 时,一切正常。
然后我决定为每一行添加两个ImageButtons,显示EDIT和DISCARD ImageButtons,在这种情况下的问题是ImageButtons窃取焦点并且ListView适配器onItemClickListener不再接收onItemClick事件,所以主片段的内容可以' t 根据我在抽屉上单击的元素进行相应更改。
我使用自定义 CursorAdapter 来填充抽屉的 ListView,因此我决定为行的每个元素创建一个 OnClickListener。现在,该行的每个项目都会对单击事件做出正确反应...现在的问题是我无法将 onClick 事件从 TextView 元素传输到 ListView 以正确选择 ListView 中的项目。
custom_list_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="horizontal"
android:clickable="true">
<ImageButton
android:id="@+id/drawer_list_item_discard"
android:layout_
android:layout_
android:src="@drawable/ic_discard"
android:scaleType="centerCrop"
android:layout_alignParentRight="true"
android:background="@null"
android:padding="0dp"/>
<ImageButton
android:id="@+id/drawer_list_item_edit"
android:layout_
android:layout_
android:src="@drawable/ic_edit"
android:scaleType="centerCrop"
android:padding="0dp"
android:background="@null"
android:layout_toLeftOf="@id/drawer_list_item_discard"/>
<TextView
android:id="@+id/drawer_list_item_text"
android:layout_
android:layout_
android:padding="5dp"
android:layout_centerInParent="true"
android:textColor="#000000"
android:textSize="20dp"
android:layout_toLeftOf="@id/drawer_list_item_edit"
android:layout_alignParentLeft="true" />
</RelativeLayout>
ProgramsCursorAdapter.java 中的bindView(...):
@Override
public void bindView(View v, Context context, Cursor c)
if (mContext == null) return;
// Instances of the Views
TextView tv_name = (TextView) v.findViewById(R.id.drawer_list_item_text);
// Override fonts
Typeface robotoLight = Typeface.createFromAsset(mContext.getAssets(), "fonts/Roboto-Light.ttf");
if (tv_name != null) tv_name.setTypeface(robotoLight);
// Retrieve values of the row
String name = c.getString(c.getColumnIndex(DBHelper.TB_PROGRAM_NAME));
// Assign retrieved value to the row
tv_name.setText(name);
tv_name.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
System.out.println("Program click!");
);
//Set up imagebuttons
ImageButton edit = (ImageButton) v.findViewById(R.id.drawer_list_item_edit);
edit.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
System.out.println("Edit onclick!");
);
ImageButton discard = (ImageButton) v.findViewById(R.id.drawer_list_item_discard);
discard.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
System.out.println("Discard onclick!");
);
我在 SO 中也看到了一些关于我此刻面临的问题的帖子,但没有人能弄清楚如何解决它,我想我正在走上好路,但我仍然无法得到它做得对。提前致谢。
【问题讨论】:
【参考方案1】:终于让它工作了,以防其他人需要这个。我认为这是唯一可能的解决方法...
我添加了一个界面
public interface NavigationDrawerListHandler
/**
* Called when an item in the navigation drawer is selected.
*/
void selectItem(int position);
NavigationDrawerFragment
和 ProgramsCursorAdapter
实现 NavigationDrawerListHandler
。
ProgramsCursorAdapter
还保留了由方法传递给它的 NavigationDrawerListHandler
类型的引用
ProgramsCursorAdapter.java
public void attach(NavigationDrawerFragment f)
try
mCallbacks = (NavigationDrawerListHandler) f;
catch (ClassCastException e)
throw new ClassCastException(
"Fragment must implement NavigationDrawerListHandler.");
当ProgramsCursorAdapter
的新实例绑定到抽屉的 ListView 时调用,如下所示:
NavigationDrawerFragment.java
// Set up adapter and bind it to the list
ProgramsCursorAdapter adapter = new ProgramsCursorAdapter(getActionBar()
.getThemedContext(), database.getPrograms(), CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
mDrawerListView.setAdapter(adapter);
// Attach this fragment to the adapter
adapter.attach(this);
这样适配器可以直接访问属于 NavigationDrawerFragment 的 setItem(int position) 方法,并且可以像这样从 onClick(View v) 调用 setItem(int position):
ProgramsCursorAdapter.java
@Override
public void bindView(View v, Context context, Cursor c)
/* ... */
// Get the position of the clicked view
final int p = c.getPosition();
tv_name.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
System.out.println("Program click!");
selectItem(p);
);
/* ... */
@Override
public void selectItem(int position)
mCallbacks.selectItem(position);
希望这会有所帮助!
【讨论】:
以上是关于处理自定义列表项单击导航抽屉 ListView 内的主要内容,如果未能解决你的问题,请参考以下文章