问题:当我清除并重新填充我的 ListView 时,如果以前检查过某个项目,那么也会检查同一索引处的项目。如果添加到适配器的元素数量 < 先前检查项目的索引,则不检查任何内容。
我已经尝试阻止使用 convertView 即使它存在但没有效果。奇怪的是,当我逐步通过调试器查看发生了什么时,我看到重新填充适配器会导致在 CheckableLinearLayout 中调用一次或多次 setChecked(true)。(我在下面包含了该堆栈跟踪)查看这些调用的调用堆栈表明它不是我编写的任何发起这些调用的代码。就好像 ListView 正在记住先前选择的索引并自行恢复它。
我的实现:我将 ListView 设置为 singleSelection 模式。我使用具有 getView(...) 的自定义 ArrayAdapter,它返回我的 CheckableListView 实现的实例:
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private boolean isChecked;
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
if(isChecked) {
setBackgroundColor(Color.DKGRAY);
} else {
setBackgroundColor(Color.BLACK);
}
}
@Override
public boolean isChecked() {
return isChecked;
}
@Override
public void toggle() {
setChecked(!isChecked);
}
}
我的 ArrayAdapter 的 getView 实现:
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
LayoutInflater inf = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
CheckableLinearLayout row = (CheckableLinearLayout) convertView;
if (row == null) {
row = (CheckableLinearLayout) inf.inflate(R.layout.file_explorer_item, parent, false);
}
// I explicitly set checked to false, in case this was a convertView:
row.setChecked(false);
// population various elements of the view is done here
return row;
}
}
有任何想法吗?
PS。这是对 setChecked(true) 的一个神秘调用的堆栈跟踪:
<1> main@830013232224, prio=5, in group 'main', status: 'RUNNING'
at my.package.CheckableLinearLayout.setChecked(CheckableLinearLayout.java:25)
at android.widget.ListView.setupChild(ListView.java:1834)
at android.widget.ListView.makeAndAddView(ListView.java:1765)
at android.widget.ListView.fillSpecific(ListView.java:1318)
at android.widget.ListView.layoutChildren(ListView.java:1636)
at android.widget.AbsListView.onLayout(AbsListView.java:1863)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1617)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1401)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11278)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1489)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Method.java:-1)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(NativeStart.java:-1)
<10> Binder Thread #2@830019920808, prio=5, in group 'main', status: 'RUNNING'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<9> Binder Thread #1@830019917952, prio=5, in group 'main', status: 'RUNNING'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<8> FinalizerWatchdogDaemon@830019904352 daemon, prio=5, in group 'main', status: 'SLEEPING'
at java.lang.VMThread.sleep(VMThread.java:-1)
at java.lang.Thread.sleep(Thread.java:1031)
at java.lang.Thread.sleep(Thread.java:1013)
at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:213)
at java.lang.Thread.run(Thread.java:856)
<7> FinalizerDaemon@830019904008 daemon, prio=5, in group 'main', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:401)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:102)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:73)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
at java.lang.Thread.run(Thread.java:856)
<6> ReferenceQueueDaemon@830019903648 daemon, prio=5, in group 'main', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:364)
at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:128)
at java.lang.Thread.run(Thread.java:856)
<5> Compiler@830019903408 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<3> Signal Catcher@830019902928 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<2> GC@830019902704 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)