Список нескольких вариантов с пользовательским представлением?
Я видел пример 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
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 мне нужно только щелкнуть по строке элемента.
Итак, что мне нужно сделать, чтобы сделать список множественного выбора с моим пользовательским представлением для каждой строки? Большое спасибо.
Ответы
Ответ 1
Вы должны создать свой собственный RelativeLayout
, который реализует интерфейс Checkable
и ссылается на CheckBox
или на CheckedTextView
(или список, если он имеет режим множественного выбора).
Посмотрите на это сообщение:
http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
Ответ 2
Ответ 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
, потому что при вызове функции возникают странные вещи.
Чтобы получить список проверенных строк, вам нужно реализовать метод самостоятельно, вызов 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
}
}
Ответ 3
Каждый такой вид имеет TextView и CheckBox.
Нет, это не так. Он имеет CheckedTextView
.
Итак, что мне нужно сделать, чтобы сделать список с несколькими вариантами просмотреть для каждой строки?
Попробуйте сделать CheckBox
android:id
значение "@android:id/text1"
и посмотреть, поможет ли это. Это идентификатор, используемый Android для CheckedTextView
в simple_list_item_multiple_choice
.
Ответ 4
Решение состоит в создании пользовательского представления, которое реализует интерфейс 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>
Затем создайте новый пользовательский адаптер, используя вышеприведенный макет.
Ответ 5
Это возможно с помощью трюка
в вашем 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;
}
таким образом вы можете настроить представление в адаптере, когда элемент выбран в списке.
Ответ 6
Простой пример, как настроить пользовательский макет как пользовательский флажок:
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;
}
}
Ответ 7
Мне очень понравился этот маленький код: 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/.
Ответ 8
Получено решение... Вы можете получить клики по представлениям (например, флажки в пользовательских макетах строки), добавив слушатель к каждому из них в самом адаптере, когда вы возвращаете преобразованное представление в getView(). Возможно, вам придется передать ссылку на объект списка, если вы хотите получить информацию о конкретном списке. как идентификатор строки.
Ответ 9
Я хочу подтвердить правильность ответа Pritam. Вам нужно onClickListener
для каждого элемента списка (определите его в адаптере getView()
).
Вы можете создать новый onClickListener()
для каждого элемента или реализовать адаптер onClickListener()
- в этом случае элементы должны быть помечены для прослушивателя, чтобы знать, на каком элементе он работает.
Полагаясь на список onItemClickListener()
- как кто-то сообщил в другом потоке - не будет работать, так как CheckBox
перехватит событие click, чтобы список не получил его.
И наконец @Rahul и JVitella:
Ситуация заключается в том, что элемент CheckBox
в элементе списка должен быть доступен для кликов и независимо от самого элемента списка. Поэтому решение такое, как я только что описал выше.