我需要一个具有三种状态(基本上是“忽略”、“包含”和“排除”)的 CheckedTextView,所以我构建了自己的视图并且它可以工作。但是我想将我的 ThreeStateTextView 嵌入到 ListView 中,这不起作用。
ListView 回收视图并且状态丢失。所以我查看了 ListView 代码,看看它如何处理来自 CheckedTextView 的状态:
... setupChild(...) {
...
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
if (child instanceof Checkable) {
((Checkable) child).setChecked(mCheckStates.get(position));
}
}
....
所以看起来,ListView 存储了一个布尔数组,代表状态。孩子要么是新创建的孩子,要么是回收的孩子。
我的想法是在我自己的 listview 实现中重新实现这个方法,但是这个方法是私有的,所以我不能这样做。这是堆栈跟踪,从 BaseAdapter.getView(...) 开始:
xxxxxxAdapter.getView(int, View, ViewGroup) line: 50 (my own BaseAdapter implementation)
ListView(AbsListView).obtainView(int, boolean[]) line: 2159
ListView.makeAndAddView(int, int, boolean, int, boolean) line: 1831
ListView.fillDown(int, int) line: 674
ListView.fillFromTop(int) line: 735
ListView.layoutChildren() line: 1652
ListView(AbsListView).onLayout(boolean, int, int, int, int) line: 1994
ListView(View).layout(int, int, int, int) line: 14003
ListView(ViewGroup).layout(int, int, int, int) line: 4375
太糟糕了,重要的方法(obtainView 和 setupChild,在获取视图之后立即调用)是私有/默认访问修饰符。
我该怎么做才能使我的三种状态的已检查文本视图在 ListView 中工作?
// 编辑:也许我应该改写我的问题:你有一个 ListView 和你自己的 BaseAdapter 实现,但是你的适配器创建了复杂的视图或使用了 convertView 参数(例如,它创建了一个带有 TextView 和两个复选框的线性布局)。问题是 ListView 不保存复选框的状态。
这是示例布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView android:id="@+id/textview_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBox android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
你会如何解决这个问题?