Android自定义ListView无法点击项目

所以我有一个自定义的ListView对象。 列表项目有两个文本视图堆叠在一起,另外还有一个水平进度条,我想保持隐藏状态,直到我真的做了一些事情。 到最右边是一个checkbox,我只想在用户需要下载更新到他们的数据库时显示。 当通过将可见性设置为Visibility.GONE来禁用checkbox时,我可以单击列表项目。 当checkbox可见时,除了checkbox之外,我无法点击列表中的任何内容。 我做了一些search,但没有发现任何与我目前的情况相关的东西。 我发现这个问题,但我使用重写的ArrayAdapter,因为我使用ArrayLists来包含内部数据库的列表。 我只需要得到LinearLayout视图并像Tom那样添加一个onClickListener? 我不确定。

这里是列表视图行布局XML:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:padding="6dip"> <LinearLayout android:orientation="vertical" android:layout_width="0dip" android:layout_weight="1" android:layout_height="fill_parent"> <TextView android:id="@+id/UpdateNameText" android:layout_width="wrap_content" android:layout_height="0dip" android:layout_weight="1" android:textSize="18sp" android:gravity="center_vertical" /> <TextView android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:id="@+id/UpdateStatusText" android:singleLine="true" android:ellipsize="marquee" /> <ProgressBar android:id="@+id/UpdateProgress" android:layout_width="fill_parent" android:layout_height="wrap_content" android:indeterminateOnly="false" android:progressDrawable="@android:drawable/progress_horizontal" android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal" android:minHeight="10dip" android:maxHeight="10dip" /> </LinearLayout> <CheckBox android:text="" android:id="@+id/UpdateCheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 

这里是扩展ListActivity的类。 显然它还在发展之中,所以原谅那些遗漏或可能留下的东西:

 public class UpdateActivity extends ListActivity { AccountManager lookupDb; boolean allSelected; UpdateListAdapter list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); lookupDb = new AccountManager(this); lookupDb.loadUpdates(); setContentView(R.layout.update); allSelected = false; list = new UpdateListAdapter(this, R.layout.update_row, lookupDb.getUpdateItems()); setListAdapter(list); Button btnEnterRegCode = (Button)findViewById(R.id.btnUpdateRegister); btnEnterRegCode.setVisibility(View.GONE); Button btnSelectAll = (Button)findViewById(R.id.btnSelectAll); btnSelectAll.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { allSelected = !allSelected; for(int i=0; i < lookupDb.getUpdateItems().size(); i++) { lookupDb.getUpdateItem(i).setSelected(!lookupDb.getUpdateItem(i).isSelected()); } list.notifyDataSetChanged(); // loop through each UpdateItem and set the selected attribute to the inverse } // end onClick }); // end setOnClickListener Button btnUpdate = (Button)findViewById(R.id.btnUpdate); btnUpdate.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { } // end onClick }); // end setOnClickListener lookupDb.close(); } // end onCreate @Override protected void onDestroy() { super.onDestroy(); for (UpdateItem item : lookupDb.getUpdateItems()) { item.getDatabase().close(); } } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); UpdateItem item = lookupDb.getUpdateItem(position); if (item != null) { item.setSelected(!item.isSelected()); list.notifyDataSetChanged(); } } private class UpdateListAdapter extends ArrayAdapter<UpdateItem> { private List<UpdateItem> items; public UpdateListAdapter(Context context, int textViewResourceId, List<UpdateItem> items) { super(context, textViewResourceId, items); this.items = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row = null; if (convertView == null) { LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = li.inflate(R.layout.update_row, null); } else { row = convertView; } UpdateItem item = items.get(position); if (item != null) { TextView upper = (TextView)row.findViewById(R.id.UpdateNameText); TextView lower = (TextView)row.findViewById(R.id.UpdateStatusText); CheckBox cb = (CheckBox)row.findViewById(R.id.UpdateCheckBox); upper.setText(item.getName()); lower.setText(item.getStatusText()); if (item.getStatusCode() == UpdateItem.UP_TO_DATE) { cb.setVisibility(View.GONE); } else { cb.setVisibility(View.VISIBLE); cb.setChecked(item.isSelected()); } ProgressBar pb = (ProgressBar)row.findViewById(R.id.UpdateProgress); pb.setVisibility(View.GONE); } return row; } } // end inner class UpdateListAdapter } 

编辑:我仍然有这个问题。 我在作弊,并将onClick处理程序添加到textviews中,但是当我没有点击我的checkbox时,我的onListItemClick()函数根本没有被调用,这似乎是非常愚蠢的。

问题在于Android不允许您select具有可聚焦元素的列表项目。 我修改了列表项上的checkbox,使其具有如下所示的属性:

 android:focusable="false" 

现在我的包含checkbox(也适用于button)的列表项是传统意义上的“可选”(它们点亮,可以单击列表项中的任意位置,“onListItemClick”处理程序将触发等)。

编辑:作为更新,一个评论者提到“只是一个笔记,更改button的可见性后,我不得不以编程方式禁用焦点了。”

如果在列表项中有ImageButton,则应该在根列表项元素中将descendantFocusability值设置为'blocksDescendants'。

 android:descendantFocusability="blocksDescendants" 

并且在ImageButton视图中focusableInTouchMode标志为true

 android:focusableInTouchMode="true" 

我有一个类似的问题发生,并发现CheckBox在ListView中相当挑剔。 会发生什么,它强加在整个ListItem上,并重写onListItemClick。 你可能想要实现一个点击处理程序,并设置CheckBox的文本属性,而不是使用TextViews。

我会说,看看这个视图对象,它可能比CheckBox更好

选中文本视图

在列表项的根视图中使用此行

机器人:descendantFocusability = “blocksDescendants”