引言

最近在做自定义的Flowlayout流式布局,发现在使用选择器的时候我们会走入误区,忘记单一职责原则,这一篇就来解释和解决这一误区。

效果展示

TextView选择后.jpeg

TextView未点击前.jpeg

布局文件(drawable资源文件夹下)

第一种:啥也不带,就一个描边框

android:width="0.5dp"

android:color="@color/color_84C6FA"/>

第二种:带填充色的描边框

android:width="0.5dp"

android:color="@color/color_84C6FA"/>

咋使用这两种布局呢?

简单:使用选择器,选中的时候填充背景颜色,不选中则为默认色(灰色)

我还想要点击后变drawable的同时改变字体颜色呢?

有没有思路?

你是不是想的在这行加上你的字体颜色?NONONO,如果你这样想就大错特错了!why?你肯定很疑惑,选择时设置不同的字体颜色在选择器上不就可以了吗,为什么不能呢?

这就不得不说一下我们的单一职责原则了,要知道你在引用选择器文件的时候它位于那个资源文件夹下,Drawable文件夹,那你引用它的时候怎么设置?android:drawable="xxx"对吧?设想一下,一个布局能同时做两个职责吗?既给你的控件背景刷漆,还要负责给你的字体变色?要知道给字体设置颜色,需要android:textColor="yyy",是不是有思路了?

那到底具体怎么做呢?(解决方法)

(1)首先你需要创建一个color资源文件夹(统一管理用来变色的文件),是创建文件夹,而不是去找value文件夹下的colors文件,这两者是有本质区别的!

(2)然后创建颜色选择器文件

它只负责给你的字体刷漆!!!

(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",目前已更新,而且还需要设置点击事件处理业务逻辑,才能达到循环点击切换状态的效果。