ListView的setItemChecked方法有时无效?
2016-12-21 本文已影响0人
laxus
有时候想着使用ListView自带的setItemChecked(position, value)来实现item的选中,却发现不管怎么点,选中的item都没有出现预期的高亮效果,但是通过isItemChecked(position)方法查询却显示该item已经怎么选中,为什么?
如下
private void updateOnScreenCheckedViews() {
final int firstPos = mFirstPosition;
final int count = getChildCount();
final boolean useActivated = getContext().getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.HONEYCOMB;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
final int position = firstPos + i;
if (child instanceof Checkable) {
((Checkable) child).setChecked(mCheckStates.get(position));
} else if (useActivated) {
child.setActivated(mCheckStates.get(position));
}
}
}
这里只是列出了关键代码,可以看到ListView在设置Item的选中状态时会有一个判断Item类型的逻辑,也就是ListView会使用两种方式来设置View的选中状态。如果View是Checkable的子类,那么ListView才会使用check属性,这就导致一些看到ListView.setItemChecked方法名的朋友直接就写了如下的drawable.xml,并将其设置为TextView的drawableXXX结果就是怎么都看不到View选中状态时的UI变化.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/checked"/>
<item android:drawable="@drawable/unchecked"/>
</selector>
原因就是TextView并非Checkable的子类,也就不会有checked状态。如果ItemView是非Checkable的,比如TextView,则需如下设置(TargetSdk>=11), 使用activated属性。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="@drawable/checked"/>
<item android:drawable="@drawable/unchecked"/>
</selector>
这里关于ListView在sdk-11之前是如何实现Item的选中状态的,我没有去看,并不想去下载这么早期的源码, 毕竟现在多数应用的minSDK都是15以上了,不过有兴趣的朋友可以去看看。
另有一点是ListView只有通过setChoiceMode()设置ChioceMode为除CHOICE_MODE_NONE(default)以外的mode,ListView的Item才会变成可选中,不过这一点在setItemCheck()方法说明中描述的很清楚了,一般不会忘记这一步。
以上基于sdk-24,测试手机为5.0