Добавление CheckBox в строку списка теряет мои события onItemClick?
У меня есть ListView с адаптером ArrayList. Строки не очень сложные (изображение слева, LinearLayout с TextViews внутри и CheckBox справа... макет скопирован ниже.) Цель состоит в том, чтобы панель QuickAction появлялась, если пользователь нажимает на изображении или тексте и иметь состояние изменения CheckBox, если пользователь нажимает на CheckBox. У меня каждая часть работает независимо, но не тогда, когда они вместе в макете - почему-то я теряю событие onItemClick.
Панель "QuickAction" активируется с помощью OnItemClickListener(), и она работает нормально - если у меня нет CheckBox в макете, в этом случае CheckBox работает нормально (с помощью onClick()), но onItemClickListener никогда не запускается, если пользователь нажимает в строка, но за пределами CheckBox. Макет (без некоторых стилевых вещей):
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/vw1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="@+id/img"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox android:id="@+id/ckb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_gravity="right"
android:checked="false" />
<!-- stack text in middle section of the row -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content""/>
<TextView android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>
Код этого не сложен:
public class ListGroupsActivity extends BaseActivityForList {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
// add QuickAction bar
ListView lv = getListView();
lv.setOnItemClickListener(new QAListener(this));
}
}
//inner classes of the ListGroupsActivity
class CbOnClickListener implements OnClickListener {
// ...
// test the checkbox isChecked() and keep state in 'selectedItems' array
class GroupListAdapter extends ArrayAdapter<Group> {
super(/*...*/)
CbOnClickListener cblistener = null; // common listener for all the CheckBoxes
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// here do normal testing for convertView being null etc
// heres the view inflation from the layout into the ViewHolder
holder.tv1 = (TextView) convertView.findViewById(R.id.text1);
holder.tv2 = (TextView) convertView.findViewById(R.id.text2);
holder.img = (ImageView) convertView.findViewById(R.id.img);
holder.ckb = (CheckBox) convertView.findViewById(R.id.ckb);
Group g = groups.get(position); // this is the data obj for the row
holder.tv1.setText(g.getName());
holder.tv2.setText("child groups");
Bitmap bm = BitmapFactory.decodeFile(g.getIconUri());
holder.img.setImageBitmap(bm);
Integer key = (Integer) g.getId();
holder.ckb.setChecked(selectedItems.contains(key));
holder.ckb.setOnClickListener(cblistener); // hook onClick to cblistener
return convertView;
}
QAListener находится в суперклассе для всех моих действий со списком:
public class BaseActivityForList extends
OrmLiteBaseListActivity<DatabaseHelper> {
// QAListener inner class, constructs new quick action bar when item clicked
class QAListener implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// has three ActionItem instances, 'copyAction', 'delAction', 'editAction'
ActionItem copyAction = new ActionItem();
copyAction.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// ... does some stuff
mQuickAction.dismiss();
}
}); // end setOnClickListener
} // end onItemClick
} // end QAListener
} end BaseActivityForList
Итак, как мне организовать, чтобы флажок забирал onClick, а остальная часть списка выбирала onItemClick()?
2 ответа
После нескольких часов отладки и исследований. Я получил его, установив следующие свойства на флажок:
android:focusable="false"
android:focusableInTouchMode="false"
Также может потребоваться настроить ImageView, как описано в http://blog.sachin.name/?p=62 (спасибо этому человеку)
Со своей стороны, я обнаружил, что представление элемента НЕ ДОЛЖНО быть кликабельным, а текстовые представления также не должны кликабельны Мне потребовалось некоторое время, чтобы понять, что я вызвал setClickable(true) в моем представлении элемента где-то в коде.
Просто для дополнения этого принятого ответа: в случае ImageButton
вместо CheckBox
недостаточно установить в xml focusable
а также focusableInTouchMode
в false, но во время выполнения фокусируемый должен быть установлен в false. Это означает, чтобы убедиться, onItemClick
будет обнаружено, что нужно сделать что-то вроде:
button.setFocusable(false);
так что все работает полностью.. Оригинальные кредиты для автора здесь. надеюсь, это кому-нибудь поможет.
Ура;)
Изменить: есть еще более элегантное решение, попробуйте добавить android:descendantFocusability="blocksDescendants"
в корневом макете элемента списка. Это сделает возможным клики по списку элементов и отдельно вы можете обрабатывать нажатия кнопок или Image Button