Список нескольких вариантов с пользовательским представлением?

Я видел пример com.example.android.apis.view.List11 из ApiDemos. В этом примере каждая строка принимает вид android.R.simple_list_item_multiple_choice . Каждый такой вид имеет TextView и CheckBox .

Теперь я хочу, чтобы у каждого представления было 2 TextView и 1 CheckBox , несколько похожие на пример List3 . Я попытался создать собственный файл макета row.xml следующим образом:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <CheckBox android:id="@+id/checkbox" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="fill_parent" /> <TextView android:id="@+id/text_name" android:textSize="13px" android:textStyle="bold" android:layout_toLeftOf="@id/checkbox" android:layout_alignParentLeft="true" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_phone" android:textSize="9px" android:layout_toLeftOf="@id/checkbox" android:layout_below="@id/text_name" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </RelativeLayout> 

Затем в Activity 's onCreate() мне нравится следующее:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Query the contacts mCursor = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); startManagingCursor(mCursor); ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.row, mCursor, new String[] { Phones.NAME, Phones.NUMBER}, new int[] { R.id.text_name, R.id.text_phone }); setListAdapter(adapter); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } 

Результат выглядит так, как я хочу, но похоже, что список не знает, какой элемент его выбран. Кроме того, мне нужно щелкнуть именно на CheckBox . В примере List11 мне нужно только щелкнуть по строке элемента.

Итак, что мне нужно сделать, чтобы сделать список с несколькими вариантами с моим пользовательским представлением для каждой строки? Большое спасибо.

Solutions Collecting From Web of "Список нескольких вариантов с пользовательским представлением?"

Вы должны создать свой собственный RelativeLayout который реализует интерфейс Checkable и ссылается на CheckBox или на CheckedTextView (или список, если он используется в режиме множественного выбора).

Посмотрите на это сообщение: http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/

Ответ Rahul Garg хорош в первый раз, когда список загружен, если вы хотите, чтобы некоторые строки проверялись в зависимости от данных модели, но после этого вам придется самостоятельно обрабатывать события check / uncheck.

Вы можете переопределить onListItemCLick() ListActivity чтобы проверить / снять флажки

 @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); ViewGroup row = (ViewGroup)v; CheckBox check = (CheckBox) row.findViewById(R.id.checkbox); check.toggle(); } 

Если вы это сделаете, не устанавливайте ListView в CHOICE_MODE_MULTIPLE , потому что при вызове функции CHOICE_MODE_MULTIPLE странные вещи.

Чтобы получить список проверенных строк, вам необходимо реализовать метод самостоятельно, вызов getCheckItemIds() в ListView не работает:

 ListView l = getListView(); int count = l.getCount(); for(int i=0; i<count; ++i) { ViewGroup row = (ViewGroup)l.getChildAt(i); CheckBox check = (Checked) row.findViewById(R.id.ck1); if( check.isChecked() ) { // do something } } 

Каждый такой вид имеет TextView и CheckBox.

Нет, нет. Он имеет CheckedTextView .

Итак, что мне нужно сделать, чтобы сделать список с несколькими вариантами с моим пользовательским представлением для каждой строки?

Попробуйте установить значение CheckBox android:id "@android:id/text1" и посмотреть, поможет ли это. Это идентификатор, используемый Android для CheckedTextView в simple_list_item_multiple_choice .

Решение заключается в создании пользовательского представления, реализующего интерфейс Clickable.

 public class OneLineCheckableListItem extends LinearLayout implements Checkable { public OneLineCheckableListItem(Context context, AttributeSet attrs) { super(context, attrs); } private boolean checked; @Override public boolean isChecked() { return checked; } @Override public void setChecked(boolean checked) { this.checked = checked; ImageView iv = (ImageView) findViewById(R.id.SelectImageView); iv.setImageResource(checked ? R.drawable.button_up : R.drawable.button_down); } @Override public void toggle() { this.checked = !this.checked; } } 

Создайте собственный макет для элементов списка с помощью нового виджета.

 <?xml version="1.0" encoding="utf-8"?> <ax.wordster.OneLineCheckableListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:background="@drawable/selector_listitem" android:orientation="horizontal" > <ImageView android:id="@+id/SelectImageView" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/button_friends_down" /> <TextView android:id="@+id/ItemTextView" android:layout_width="fill_parent" android:layout_height="60dp" android:gravity="center" android:text="@string/___" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="@color/text_item" /> </ax.wordster.OneLineCheckableListItem> 

Затем создайте новый пользовательский адаптер, используя вышеприведенный макет.

Это возможно с помощью некоторого трюка

В методе ListActivtyClass

 protected void onListItemClick(ListView l, View v, int position, long id) { //just set <your_model>.setSelected(true); } 

Теперь в вашем пользовательском адаптере

 public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(textViewResourceId, parent, false); } if (<your_model>.isSelected()) { convertView.setBackgroundColor(Color.BLUE); } else { convertView.setBackgroundColor(Color.BLACK); } return convertView; } 

Таким образом вы можете настроить представление в адаптере, когда элемент выбран в списке.

Простой пример того, как настроить пользовательский макет как пользовательский флажок:

 private class FriendsAdapter extends ArrayAdapter<WordsterUser> { private Context context; public FriendsAdapter(Context context) { super(context, R.layout.listitem_oneline); this.context = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int pos = position; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rv = inflater.inflate(R.layout.listitem_oneline, parent, false); rv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean checked = friendsListView.isItemChecked(pos); friendsListView.setItemChecked(pos, !checked); } }); WordsterUser u = getItem(position); TextView itw = (TextView) rv.findViewById(R.id.ItemTextView); itw.setText(u.userName + " (" + u.loginName + ")"); ImageView iv = (ImageView) rv.findViewById(R.id.SelectButton); if (friendsListView.isItemChecked(position)) { iv.setImageResource(R.drawable.downbutton); } else { iv.setImageResource(R.drawable.upbutton); } return rv; } } 

Мне очень понравился этот маленький код: http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml

Это отличное дополнение к сайту @ ferdy182 http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/ .

Получил решение … Вы можете получить клики по представлениям (например, флажки в пользовательских макетах строки), добавив слушателя к каждому из них в самом адаптере, когда вы возвращаете преобразованное представление в getView (). Возможно, вам придется передать ссылку на объект списка, если вы хотите получить информацию о конкретном списке. Как идентификатор строки.

Я хочу подтвердить, что ответ Притама верен. onClickListener каждого элемента списка необходимо установить onClickListener (определить его в getView() ) адаптера.

Вы можете создать новый onClickListener() для каждого элемента или реализовать адаптер onClickListener() – в этом случае элементы должны быть помечены для прослушивателя, чтобы знать, на какой элемент он работает.

Опираясь на список onItemClickListener() как кто-то советовал в другом потоке, не будет работать, так как CheckBox перехватит событие click, чтобы список не получил его.

И наконец @Rahul и JVitella:

Ситуация заключается в том, что CheckBox в элементе списка должен быть доступен для кликов и независимо от самого элемента списка. Поэтому решение такое, как я только что описал выше.