引言
最近在做自定义的Flowlayout流式布局,发现在使用选择器的时候我们会走入误区,忘记单一职责原则,这一篇就来解释和解决这一误区。
效果展示
TextView选择后.jpegTextView未点击前.jpeg
布局文件(drawable资源文件夹下)
第一种:啥也不带,就一个描边框
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="0.5dp"
android:color="@color/color_84C6FA"/>
<corners android:radius="4dp"/>
</shape>
第二种:带填充色的描边框
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue"/>
<stroke
android:width="0.5dp"
android:color="@color/color_84C6FA"/>
<corners android:radius="4dp"/>
</shape>
咋使用这两种布局呢?
简单:使用选择器,选中的时候填充背景颜色,不选中则为默认色(灰色)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--TagFlowLayout封装好的状态改变回调-->
<item android:drawable="@drawable/flow_tv_select_shape" android:state_checked="true" />
<!--普通点击状态改变-->
<item android:drawable="@drawable/flow_tv_select_shape" android:state_selected="true" />
<item android:drawable="@drawable/flow_tv_shape" />
</selector>
</selector>
我还想要点击后变drawable的同时改变字体颜色呢?
有没有思路?
<item android:drawable="@drawable/flow_tv_select_shape" android:state_selected="true" />
你是不是想的在这行加上你的字体颜色?NONONO,如果你这样想就大错特错了!why?你肯定很疑惑,选择时设置不同的字体颜色在选择器上不就可以了吗,为什么不能呢?
这就不得不说一下我们的单一职责原则了,要知道你在引用选择器文件的时候它位于那个资源文件夹下,Drawable文件夹,那你引用它的时候怎么设置?android:drawable="xxx"对吧?设想一下,一个布局能同时做两个职责吗?既给你的控件背景刷漆,还要负责给你的字体变色?要知道给字体设置颜色,需要android:textColor="yyy",是不是有思路了?
那到底具体怎么做呢?(解决方法)
(1)首先你需要创建一个color资源文件夹(统一管理用来变色的文件),是创建文件夹,而不是去找value文件夹下的colors文件,这两者是有本质区别的!
(2)然后创建颜色选择器文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--TagFlowLayout封装好的状态改变回调-->
<item android:color="@color/white" android:state_checked="true" />
<!--普通点击状态改变-->
<item android:color="@color/white" android:state_selected="true" />
<item android:color="@color/dimgray" />
</selector>
它只负责给你的字体刷漆!!!
(3)重点给你的控件设置选择器
android:background="@drawable/tagflow_tv_bg_selector"
android:textColor="@color/tagflow_tv_tc_selector"
(4)最后进行业务逻辑的处理(进行无限点击切换状态)
// 点击触发控件的状态切换效果(不做处理无法触发效果)
TextView tvTest = findViewById(R.id.tvTest);
tvTest.setOnClickListener((View)->{
tvTest.setSelected(!tvTest.isSelected()); // 状态取反
if (tvTest.getText() == "已关注"){
tvTest.setText("加关注");
}else {
tvTest.setText("已关注");
}
});
大功告成!
Tips:
因为之前我使用的泓洋大神的库TagFlowLayout实现的流式布局+选择器功能,他内部将setSelected方法转成了自定义过的回调方法setChecked,然后通过内部业务逻辑再次进行转换回去,所以转换器selector的状态切换使用了android:state_checked="true",其实如果不用TagFlowLayout,这个方法是不能调用的!(我的错!)
我后来再次看这篇博客才发现了问题,普通的TextView切换状态,选择器中的状态选择需要使用android:state_selected="true",目前已更新,而且还需要设置点击事件处理业务逻辑,才能达到循环点击切换状态的效果。
网友评论