美文网首页Android知识Android开发Android技术知识
如何给布局内的所有view添加点击效果

如何给布局内的所有view添加点击效果

作者: 三十二蝉 | 来源:发表于2017-04-25 10:06 被阅读671次

前言

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。

相关文章