Android 自定义背景点击 自定义StateListDrawable

前言

        以按钮点击效果举例,点击前后颜色变化,按钮形状可方可圆。

效果图

Android10以上调用相机 相册选择

这个视频的选择照片按钮就是用自定义Drawable设置背景的。


方法一:新增xml文件 

编写Drawable目录下的xml文件,引入到组件中使用。

1、按钮形状、颜色

2、按钮点击变化

这种方法大多应该都会,后续补上两篇博客。


方法二:自定义Drawable资源

题外话:如上这样一个按钮需要三个xml文件。就当点击后默认颜色文件可以共用,后续每添加一种不同按钮,就需要添加两个xml文件;再好比按钮形状变了,此时要添加三个xml文件。以此类推,只要项目是需要那么多不同样式的组件,所需的xml文件越多。

于是,想着能不能自定义组件,传几个可变的参数来达到目的,这样子不就不需要创建xml文件。

1、设置背景资源

        设置默认背景及点击背景,使用到GradientDrawable类

// 默认背景
GradientDrawable drawableDefault= new GradientDrawable();
drawableDefault.setShape(shape); // 设置形状
drawableDefault.setColor(colorDefault);// 设置颜色
drawableDefault.setCornerRadius(radius);// 设置弧度

// 点击背景
GradientDrawable drawableClick = new GradientDrawable();
drawableClick.setShape(shape); // 设置形状
drawableClick.setColor(Color.GRAY);// 设置颜色
drawableClick.setCornerRadius(radius);// 设置弧度

可以看出形状是共用的,弧度是共用的,点击背景设置默认灰色,那么要使用的参数也就是:

shape - 形状,例如: GradientDrawable.RECTANGLE

colorDefault - 颜色,组件默认颜色

这里有一点需要注意,drawableEnd.setColor(),这个方法里的参数是int型,可以看到点击背景的传入的是Color.GRAY,使用Color类的颜色是int型,像平常都是引用color.xml文件里设置好的颜色,也就是R.color.white这种形式,但是它是不可取的,只是引用了R类,不是int型,会报错。

radius - 弧度, 根据需要自行调整

要使用到的参数就这么多,可能有人会想,既然两个Drawable类都共用shape、radius,为啥不直接创建一个Drawable对象,这里前后两个对象Drawable是不能共用的,后一个会覆盖掉前一个对象,也就是最终只会显示一个Drawable对象,点击无效果的。

2、设置点击资源

        设置点击操作,要使用到StateListDrawable类

// 创建StateListDrawable
StateListDrawable stateListDrawable = new StateListDrawale();
// 默认状态
stateListDrawable.addState(new int[]{-android.R.attr.state_pressed}, drawableDefault);
// 按下状态
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, drawableClick);

把之前创建的两个Drawable对象添加到StateListDrawable对象里,这样就构成了同选择器xml文件功能。

到此为止,自定义的代码就写好了,把他们放在一个方法里,返回stateListDrawable对象,需要用的时候进行调用就OK了。

3、颜色转换

上文提到只能使用int型,也就是Color类的颜色,肯定是不方便的。

第一种方式:使用Color.parseColor(),将颜色值字符串用Color类进行转换成int型。

Color.parseColor("#FFFFFF");

第二种方式:使用ContextCompat.getColor(context, color),这种方式就可以把R.color.white传入color这种参数,然后ContextCompat就可以帮我们拿到这个颜色,得到的就是int型。

// 鼠标放在getColor上可以看到返回的是int类型, 传入的参数是上下文和资源id
ContextCompat.getColor(mContext,R.color.white);

tips: 我个人喜欢第二种方式,方便在color.xml文件中维护。

使用示例
// 首先建立一个方法,建议放在一个类里
public class DrawableUtil{

    public static StateListDrawable setDrawable(int shape, int colorDefault, int radius){

        // 把上文的代码放进来
        return stateListDrawable;
    }
}


// 在某个页面对某个按钮使用
public class MainActivity extends Activity{

    // 我这里就简写onCreate方法了哈
    onCreate(){
        
        Button confrim_btn = findViewById(R.id.confirm_btn);
        confrim_btn.setBackground(DrawableUtil.setDrawable(GradientDrawable.RECTANGLE,
            ContextCompat.getColor(this, R.color.blue), 30);        
    }
}

自定义标题:后续放上

自定义列表:后续放上

Android Studio在创建Activity时,会默认继承AppCompatActivity,但这个类是默认使用了主题样式,会与自定义Drawable冲突,组件设置背景不会生效,所以要继承Activity类。


方法对比 

【个人感受】

我在学习自定义Drawable资源这一块,最终目的就是不想创建过多xml文件,用一个方法搞定更简单化。

但在写这篇博客过程中,发现xml文件有一些优点是自定义没有的:

比如现在Android Studio是可以预览xml文件的图像的,eclipse不能,这样子的话,在使用xml文件时,文件过多,也可以去找出想要的样式;

再比如,一旦跟UI界面有关联,不必在逻辑代码中找,都在res目录下控制UI界面,相反写在逻辑代码里会混合逻辑与界面。

本来是想推荐使用自定义Drawable,避免使用xml文件,但现在看来,视情况而定吧,根据实际需求来选择使用哪一种方式作为资源。

【方法对比】

自定义xml文件与自定义drawale资源对比
类型优点缺点
自定义xml文件

1、逻辑代码与界面布局分离,提高代码可读性和可维护性

2、在AS中可以预览和编辑,方便快速调整样式

3、Android系统在加载xml布局时,会进行一定的优化处理

4、对于不需要动态改变的资源,使用xml文件更直观和方便。

1、缺乏灵活性,一旦被定义,除非重新加载布局,否则资源不能再运行时动态改变

2、代码量增加,需要在多个地方使用相同的资源,就需要复制粘贴xml代码,创建文件

自定义drawable资源

1、通过java代码可以动态设置和调整资源,灵活性高

2、代码复用,避免多个地方重复定义相同的资源

3、可以根据逻辑条件来决定使用那种资源

1、会混合逻辑和界面,降低代码可读性和维护性

2、相比xml文件,java代码设置资源会有一定的开销,特别是需要频繁改变资源情况下

3、不易预览和编辑,只能运行时看

总结

  • 静态与动态
  • XML文件更适合定义静态的、不常改变的背景资源;
  • Java代码则更适合动态地、根据应用状态或用户交互来改变背景资源。
  • 可读性与可维护性
  • XML文件在描述UI界面时具有更好的可读性和可维护性;
  • Java代码则可能在处理复杂逻辑和动态交互时更加灵活。
  • 性能
  • 对于静态的背景资源,XML文件可能具有更好的性能;
  • 对于需要频繁改变的背景资源,Java代码可能会带来一定的性能开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值