前言
Android开发中有一些需求需要标记是否点击,是否选中等状态;同时不同状态对应的UI样式也不一样。有时可能布局里面的View非常多,遍历所有的view并去修改它们的状态就显得非常麻烦(感觉也很low)。本文介绍这种需求的通用方法。
Android官方支持
Android官方也有一些控件支持选中效果,例如:CheckedTextView(TextView和CheckBox的结合)。但是官方SDK没有给出ViewGroup的相关控件。现实中的很多需求往往是对一个ViewGroup选中,并且修改这个ViewGroup里面所有View的状态。
但是Android官网的Demo里给出了这样的例子。链接地址 。代码如下:
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
private boolean mChecked = false;
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean isChecked() {
return mChecked;
}
public void setChecked(boolean b) {
if (b != mChecked) {
mChecked = b;
refreshDrawableState();
}
}
public void toggle() {
setChecked(!mChecked);
}
@Override
public int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
}
上面代码对应的是LinearLayout,RelativeLayout的代码参照着仿写就行。
项目实际应用
在实际的项目中,用CheckableLinearLayout替换LinearLayout,其他布局不变。例如:
<?xml version="1.0" encoding="utf-8"?>
<com.youdao.reciteword.view.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="15dp"
android:paddingTop="15dp"
android:paddingLeft="@dimen/app_base_left_margin"
android:paddingRight="@dimen/app_base_right_margin"
android:background="@drawable/preivew_item_selector"
>
<TextView
android:id="@+id/word_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="good"
android:textColor="@drawable/preview_item_word_selector"
android:textSize="18sp"
android:layout_marginBottom="3dp"
android:duplicateParentState="true"/>
</com.youdao.reciteword.view.CheckableLinearLayout>
上面的实例中,CheckableLinearLayout内部包含了一个TextView,与常规写法基本一致;这里分别为CheckableLinearLayout和TextView设置了选中效果(background和textColor)。** 需要特别注意的是,TextView里有一行代码: **
android:duplicateParentState="true"
CheckableLinearLayout内部的View必须加上这行代码。意思是直接从父布局中获取绘图状态(点击,按下等)。必须加上这行代码,不然父布局的点击状态无法传达给子View。
网友评论