欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android RelativeLayout点击切换背景

程序员文章站 2022-05-14 21:18:28
...

我们的目标是日月星辰

为什么要写这篇博客?

很常见的一个需求就是点击一个布局,切换布局的显示状态,对于TextView和ImageView来说这是很容易实现的,想着RelativeLayout应该也很简单,确实也有setBackground()这个属性,然而。。。
Android RelativeLayout点击切换背景
没办法,只能想别的办法,无意间想到洋神有一篇博客,我这篇博客充其量就算是对洋神博客的整理,大家也可以直接去看洋神的博客

效果预览

Android RelativeLayout点击切换背景

步骤

第一步 在res/values/attrs写如下内容

<declare-styleable name="LayoutState">
        <attr name="state_click" format="boolean"/>
</declare-styleable>

第二步 自定义RelativeStateLayout

public class RelativeStateLayout extends RelativeLayout {

    private static final int[] STATE_CLICK = { R.attr.state_click };
    private boolean isLayoutClick = false;


    public boolean isLayoutClick() {
        return isLayoutClick;
    }

    public void setLayoutClick(boolean layoutClick) {
        if (this.isLayoutClick != layoutClick) {
            isLayoutClick = layoutClick;
            refreshDrawableState();
        }
    }


    public RelativeStateLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace)
    {
        if (isLayoutClick) {
            final int[] drawableState = super
                    .onCreateDrawableState(extraSpace + 1);
            mergeDrawableStates(drawableState, STATE_CLICK);
            return drawableState;
        }
        return super.onCreateDrawableState(extraSpace);
    }

}

第三步代替常规的RelativeLayout使用

<com.example.zy.androidgithubuse.RelativeStateLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/message"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@drawable/item_background">

    <ImageView
        android:id="@+id/id_msg_item_icon"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginLeft="15dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:duplicateParentState="true"
        android:src="@mipmap/ic_launcher"
    />

    <TextView
        android:id="@+id/id_msg_item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/id_msg_item_icon"
        android:layout_marginLeft="15dp"
        android:text="@string/change_relativelayout_drawable"
        android:textColor="@color/colorPrimary"/>

</com.example.zy.androidgithubuse.RelativeStateLayout>

第四步 定义@drawable/item_background

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">

    <!--未点击的颜色-->
    <item app:state_click="false"
          android:drawable="@android:color/transparent"/>

    <!--点击后的颜色-->
    <item app:state_click="true"
          android:drawable="@color/colorAccent"/>

</selector>

看这写法是不是特眼熟,没错,之前玩的都是自定义View,这里是自定义Drawable,不仅说一句,原来如此

第五步 应用于RecyclerView

我使用的框架是BRVAH

public class MyAdapter extends BaseQuickAdapter<User, BaseViewHolder> {
    public MyAdapter(int layoutResId, @Nullable List<User> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(final BaseViewHolder helper, final User item) {
        RelativeStateLayout relativeStateLayout = helper.getView(R.id.relative);
        if (item.isClick()) {
            relativeStateLayout.setLayoutClick(true);
        }else {
            relativeStateLayout.setLayoutClick(false);
        }
    }
}

LinearLayout等其他布局

其他布局的做法基本一样,这里就不一一列出了,有兴趣的话,自己去尝试吧!

注意

由于RecyclerView布局的回收复用特征,所以可能要侵入的你的数据Bean中,通过数据Bean来判断是否点击了Item,具体使用请参考我的GitHub项目的使用。

GitHub地址

参考

谢谢