ListView设置选中状态
ListView设置选中状态
使⽤⽅法
通常在ListView的⼦View被选中时,希望给顶⼀个被选中的状态,⽐如,更改背景⾊。
为了使⼦View在选中时改变背景,可以⽤<selector/>标签实现。
<selector xmlns:android="schemas.android/apk/res/android">
<item android:state_activated="true"android:drawable="@color/yellow"/>
<item android:drawable="@color/black"/>
</selector>
注意:使⽤的是android:state_activated属性,⾮android:checked、android:selected。为什么使⽤这个属性,后⾯源码分析会介绍。
<TextView xmlns:android="schemas.android/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/activated"/>
要让ListView能够显⽰选中状态,只需给ListView设置选中模式即可。
getListView().setChoiceMode(ListView.ListView.CHOICE_MODE_SINGLE);
到这⾥,ListView设置选中状态就完成了。点击ListView的⼦View会发现选中的View背景颜⾊发⽣了改变。
源码分析
以下源码基于API 21。只针对单选模式,多选模式的实现也相类似。
⾸先,从ListView的performItemClick⽅法开始分析。
......
else if (mChoiceMode == CHOICE_MODE_SINGLE) {
boolean checked = !(position, false);
if (checked) {
mCheckStates.clear();
mCheckStates.put(position, true);
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
mCheckedIdStates.clear();
mCheckedIdStates.ItemId(position), position);
}
mCheckedItemCount = 1;
} else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
mCheckedItemCount = 0;
}
checkedStateChanged = true;
}
if (checkedStateChanged) {
updateOnScreenCheckedViews();
}
选择模式是单选模式下,点击位置由未选中状态变为选中状态,mCheckStates会清空之前选中position的状态,以当前position为
key,true为value存⼊mCheckStates,并且mCheckedItemCount设置为1;当选中的是同⼀position,mCheckStates不改
变,mCheckedItemCount不改变。之后会调⽤updateOnScreenCheckedViews⽅法。updateOnScreenCheckedViews⽅法的实现。
private void updateOnScreenCheckedViews() {
final int firstPos = mFirstPosition;
final int count = getChildCount();
final boolean useActivated = getContext().getApplicationInfo().targetSdkVersion
position标签属性
>= 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).(position));
} else if (useActivated) {
child.(position));
}
}
}
targetSdkVersion>=11(android3.0)使⽤activated作为选中状态,因此,targetSdkVersion>11时,⼦View使⽤android:activated属性的原因。getChildCount返回当前可见View数量,遍历当前可见children,根据mCheckState存储位置的状态来设置child的状态。如果child实现Checkable接⼝,child调⽤setChecked⽅法,否则,如果targetSdkVersion>=11,child调⽤setActivated⽅法。child背景就会根据设置的activated状态进⾏改变了。
注意:如果child是ViewGroup实例,那么activated状态会向children传递。selected状态也会向下传递。
setAdapter⽅法会清空mCheckStates。
@Override
public void setAdapter(ListAdapter adapter) {
if (adapter != null) {
mAdapterHasStableIds = mAdapter.hasStableIds();
if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds &&mCheckedIdStates == null) {        mCheckedIdStates = new LongSparseArray<Integer>();
}
}
if (mCheckStates != null) {
mCheckStates.clear();
}
if (mCheckedIdStates != null) {
mCheckedIdStates.clear();
}
}
实现过程⼗分简单,Demo就不贴了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。