设置从Adapter中选中的ListView项

我有一个ListView,显示2种项目。 其中一种包含CheckedTextView。 作为一个适配器,我正在使用自定义适配器扩展ArrayAdapter,其数据结构包含有关内部已检查/未检查状态的信息。

有些项目被标记为已选中(在我的数据结构中),所以我当然希望在创建ListView时标记checkbox。 我尝试使用CheckedTextView的setChecked()方法在适配器中的getView()方法上执行此操作,但它不起作用。 我发现它应该在ListView级别上使用setItemChecked()来完成它并且它确实有效,但它对我来说没有意义,因为要使它工作,我必须循环活动的onCreate()中的所有项目调用setItemChecked()对于那些被选中 项目列表可能很长,只选择了一些,所以这是浪费。

为什么在getView()中调用setChecked()不起作用? 有没有更好的方法(我是一个Android新手)。

下面是我的选中项目布局和适配器。

布局:

  

适配器:

 package com.melog.re.droid.search; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.TextView; import com.melog.re.droid.core.R; import com.melog.re.droid.search.MultiCriterionValue.MultiCriterionSingleValue; import com.melog.re.droid.search.MultiListAdapter.MultiChoiceItem; public class MultiListAdapter extends ArrayAdapter { private static final int VIEW_TYPES_COUNT = 2; public static final int VIEW_TYPE_GROUP = 0; public static final int VIEW_TYPE_ITEM = 1; private LayoutInflater mInflater; public MultiListAdapter(Context context, int textViewResourceId, List objects) { super(context, textViewResourceId, objects); mInflater = LayoutInflater.from(context); } @Override public int getItemViewType(int position) { MultiChoiceItem item = getItem(position); return (item.children.size() == 0) ? VIEW_TYPE_ITEM : VIEW_TYPE_GROUP; } @Override public int getViewTypeCount() { return VIEW_TYPES_COUNT; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO: optymalizacja ViewHolder MultiChoiceItem item = getItem(position); int viewType = getItemViewType(position); switch (viewType) { case VIEW_TYPE_GROUP: if (convertView == null) { convertView = mInflater.inflate(R.layout.multi_choice_group_item, parent, false); } TextView groupLabel = (TextView) convertView.findViewById(android.R.id.text1); groupLabel.setText(item.toString()); break; case VIEW_TYPE_ITEM: if (convertView == null) { convertView = mInflater.inflate(R.layout.multi_choice_child_item, parent, false); } CheckedTextView itemLabel = (CheckedTextView) convertView.findViewById(android.R.id.text1); itemLabel.setText(item.toString()); itemLabel.setChecked(item.selected); break; } return convertView; } public static class MultiChoiceItem implements Parcelable { public static final int CONTENTS_DESCR = 1; public String label; public String value; public boolean selected = false; public ArrayList children = new ArrayList(); public MultiChoiceItem(String l, String v, boolean sel) { label = l; value = v; selected = sel; } public MultiChoiceItem(MultiCriterionSingleValue v) { label = v.toString(); value = v.value; } public MultiChoiceItem(Parcel in) { label = in.readString(); value = in.readString(); selected = (in.readInt() == 1); } @Override public String toString() { return label; } @Override public int describeContents() { return CONTENTS_DESCR; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(label); dest.writeString(value); dest.writeInt(selected ? 1 : 0); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public MultiChoiceItem createFromParcel(Parcel in) { return new MultiChoiceItem(in); } public MultiChoiceItem[] newArray(int size) { return new MultiChoiceItem[size]; } }; } } 

还有一件活动onCreate()

 ... mAdapter = new MultiListAdapter(this, R.id.head, mItems); setListAdapter(mAdapter); final ListView listView = getListView(); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setItemsCanFocus(false); ... 

编辑:

在find更好的解决方案之前,我在Activity中实现了检查:

 ... int len = mListView.getCount(); for (int i = 0; i < len; i++) { if (((MultiChoiceItem) mListView.getItemAtPosition(i)).selected) { mListView.setItemChecked(i, true); } } ... 

我认为性能将是唯一的潜在问题,但我find了另一个 – 更严重。 该列表启用了文本filter(mListView.setTextFilterEnabled(true))。 这是失败的情况:

  1. 我正在打开新名单
  2. 我检查让我们说第二项
  3. 我开始打字来过滤一些物品
  4. 当过滤完成后,即使它不是我检查过的第二项仍然被检查

我假设setItemChecked()在我检查的列表上标记了一个固定的位置,而我需要一些标记该位置的东西 – 即使列表上的位置发生变化也能保持状态。

虽然性能问题可能(在某些方面)被忽略 – 这个新问题确实阻止了我,所以我真的很感激任何帮助。

  • 刷新当前片段(ListView数据)保留在同一活动中
  • 如何重叠LinearLayoutManager中的项目 - RecyclerView(如堆叠卡)
  • 需要帮助来实现47degree Android的SwipeListView
  • 如何使用listview的overscrollfunction?
  • android:listview项目宽度fill_parent不起作用
  • ListView和倒数计时器的项目
  • Android系统。 将联系人显示为列表视图
  • Android:是否可以刷新列表视图中的一个项目?
  • 如果使用ListView.CHOICE_MODE_MULTIPLECHOICE_MODE_SINGLE ,则在调用getView后,ListView将覆盖项目的检查状态。 您必须使用以下构造:

     @Override public View getView(int position, View convertView, ViewGroup parent) { ((ListView)parent).setItemChecked(position, true); } 

    另一种可能性是使用ListView.CHOICE_MODE_NONE并自己管理检查状态。

    查看步骤xml中的第一步使更改在checkbox中添加单行

     `android:onClick="chatWithFriend"` 

    所以当点击cheackbox然后在活动名称中创建一个方法

      public void chatWithFriend(View view){} here you will get the view of check box, 

    现在在返回转换视图之前在getView中添加该行

    holder.checkbox.setTag(位置);

    现在你将获得checkbox的位置

    我希望这能帮到您。