Android自定义控件之自定义属性(二)

Android自定义控件之自定义属性(二)主要涉及到在自定义控件中自定义属性的使用方法,其完整攻略如下:

1. 前言

在Android中,自定义View是非常常见的需求,而自定义控件之一的自定义属性,也是比较重要的一部分,通过自定义属性,我们可以方便地在XML文件中设置控件的属性,这样可以大大提高我们的开发效率。在之前的博客中,我们已经学习了如何自定义属性,但是那次只是介绍了自定义属性的基本用法,这次我们会更深入地学习如何在自定义控件中使用自定义属性。

2. 自定义属性的使用

2.1 属性声明

在创建自定义属性之前,需要在res/values/attrs.xml文件中进行属性的声明。如:

<resources>
    <declare-styleable name="MyCustomView">
        <attr name="textColor" format="color"/>
        <attr name="textSize" format="dimension"/>
        <attr name="text" format="string"/>
    </declare-styleable>
</resources>

上面的代码中,我们定义了一个叫做MyCustomView的样式,其中包含了三个属性:

  1. textColor:字体颜色,属性类型为color。
  2. textSize:字体大小,属性类型为dimension。
  3. text:显示的文本,属性类型为string。

其中,name表示属性的名称,format表示属性的值类型。format主要有以下选择:

  1. reference:引用类型,用@符号指定资源ID,如@drawable/my_bg。

  2. color:颜色类型,用#符号指定颜色,如#FF0000。

  3. dimension:尺寸类型,如10dp, 20sp等。

  4. float:浮点数类型,如3.14。

  5. boolean:布尔类型,如true或false。

2.2 在布局文件中使用

在Activity的布局文件中使用自定义属性时,只需要加上自定义命名空间,例如:

<com.example.view.MyCustomView
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"   
    custom:textColor="#FF0000"
    custom:textSize="20sp"
    custom:text="hello, world!"/>

其中的xmlns:custom="http://schemas.android.com/apk/res-auto"是必须的,这样才能使用自定义命名空间。

2.3 在代码中获取属性值

在自定义控件中获取自定义属性的值,需要重写View的构造函数,如:

public class MyCustomView extends View {

    private int textColor;
    private float textSize;
    private String text;

    public MyCustomView(Context context) {
        this(context, null);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
        textColor = ta.getColor(R.styleable.MyCustomView_textColor, Color.BLACK);
        textSize = ta.getDimension(R.styleable.MyCustomView_textSize, 16);
        text = ta.hasValue(R.styleable.MyCustomView_text) ? ta.getString(R.styleable.MyCustomView_text) : "";
        ta.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        canvas.drawText(text, 50, 50, paint);
    }
}

在代码中,我们通过调用Context的obtainStyledAttributes方法获取TypedArray来获取属性值,这个方法的参数有两个:

  • AttributeSet attrs:继承View的子类一般都会有三个参数的构造方法,其中第二个参数就是AttributeSet类型的。这里的attrs指的就是我们在XML布局文件中添加的属性。
  • int[] attrsArray:一个int类型的数组,它保存我们需要获取的属性ID,也就是我们在res/values/attrs.xml中所声明的属性。

在获取属性值时,我们一般使用了三个方法:

  • getColor(int index, int defValue):获取颜色值,如果取出来的值为NULL,就用Entry的默认值(默认值一定要传入)
  • getDimension(int index, float defValue):获取尺寸值,参数同上
  • getString(int index):获取字符串值

2.4 示例

例如,我们自定义一个ProgressBar控件,它包含了两个属性:progressColor和progressHeight。属性的定义和使用如下:

<resources>
    <declare-styleable name="ProgressBar">
        <attr name="progressColor" format="color"/>
        <attr name="progressHeight" format="dimension"/>
    </declare-styleable>
</resources>

<com.example.view.ProgressBar
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    custom:progressColor="#FF0000"
    custom:progressHeight="10dp"/>

ProgressBar的具体实现如下:

public class ProgressBar extends View {
    private int progressColor = Color.RED;
    private float progressHeight = 5;

    private Paint mPaint;

    public ProgressBar(Context context) {
        super(context);
        init(context, null);
    }

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

    public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final float percentage = 0.5f;//计算出当前进度占总宽度的百分比
        final float progressWidth = getWidth() * percentage;
        mPaint.setColor(progressColor);
        mPaint.setStrokeWidth(progressHeight);
        canvas.drawLine(0, getHeight() / 2, progressWidth, getHeight() / 2, mPaint);
    }

    /**
     * 初始化
     */
    private void init(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressBar);
            progressColor = array.getColor(R.styleable.ProgressBar_progressColor, Color.RED);
            progressHeight = array.getDimension(R.styleable.ProgressBar_progressHeight, 5);
            array.recycle();
        }
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }
}

两个属性的绑定在构造函数中实现。可以看到,ProgressBar的实现与TextView的类似,只需要重写onDraw方法即可。其中,获取自定义属性值的代码,就在构造方法中使用了TypedArray类实现。

3. 总结

自定义属性作为自定义控件的一部分是非常重要的,可以通过自定义属性方便地在XML文件中设置控件属性,提高我们的开发效率。同时,我们也需要了解如何在代码中获取属性值,这样才能发挥自定义属性的效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android自定义控件之自定义属性(二) - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 基于java servlet过滤器和监听器(详解)

    本篇攻略将详细讲解基于Java Servlet过滤器和监听器的实现方式及其用途。在开发Web应用程序时,过滤器和监听器是非常重要的工具,它们能够在服务器端引入一些自定义功能,这些功能可以在Web应用程序的运行时动态地进行处理,从而实现对请求和响应数据的过滤和处理。本篇攻略将分别介绍过滤器和监听器的具体实现方式及其应用场景。 过滤器 过滤器是一种可以拦截Web…

    other 2023年6月27日
    00
  • Educational Codeforces Round 84 (Div. 2)

    “Educational Codeforces Round 84(Div.2)”是Codeforces平台上的一场编程竞赛,本场比赛共有5道题目,难度从A到E不等。以下是本场比赛的完整攻略: 题目列表 本场比赛共有5道题目,分别为: A. Maximum Square B. Balanced Rating Changes C. Tile Painting D…

    other 2023年5月5日
    00
  • ntp服务和dns服务(week3_day3)–技术流ken

    以下是“NTP服务和DNS服务(Week3_Day3)–技术流Ken的完整攻略”的标准markdown格式文本,其中包含了两个示例说明: NTP服务和DNS NTP服务和DNS服务是计算机网络中的两个重要服务。本文将介绍NTP服务和DNS服务的概念、工作原理常见问题和两个示例说明。 1. NTP服务 NTP(Network Time Protocol)服务…

    other 2023年5月10日
    00
  • 详解SpringBoot之访问静态资源(webapp…)

    下面是详解SpringBoot之访问静态资源(webapp…)的完整攻略: 1. 在SpringBoot中访问静态资源 SpringBoot中默认的静态资源路径为classpath:/static/。 在该路径下,可以放置各种静态资源,例如HTML页面、CSS样式表、JavaScript脚本等等。 2. 访问HTML页面 要访问一个HTML页面,只需要将…

    other 2023年6月27日
    00
  • iOS开发验证判断语句之正则表达式小结

    iOS开发验证判断语句之正则表达式小结 正则表达式是什么 正则表达式就是由一些字符和符号组成的字符串,用来匹配文本内容的模式。在 iOS 开发中,正则表达式可以用于验证用户输入的合法性,比如验证手机号码、邮箱地址、身份证号码等。 正则表达式语法 在 iOS 开发中,可以使用 NSRegularExpression 类来创建正则表达式,并通过调用 firstM…

    other 2023年6月27日
    00
  • @ConfigurationProperties绑定配置信息至Array、List、Map、Bean的实现

    @ConfigurationProperties 是 Spring Boot 中的一个注解,它允许我们将应用程序中的配置文件绑定到 Bean 上。绑定后,我们就可以方便地将配置文件的配置值注入到 Bean 中了。除了一个普通的扩展 @ConfigurationProperties 的 Spring Boot Config 类之外,我们还可以将属性绑定到 Co…

    other 2023年6月25日
    00
  • Android App仿QQ制作Material Design风格沉浸式状态栏

    Android App仿QQ制作Material Design风格沉浸式状态栏攻略 1. 简介 在本攻略中,我们将学习如何制作一个仿QQ的Android应用,使用Material Design风格,并实现沉浸式状态栏效果。沉浸式状态栏是指将状态栏与应用界面融为一体,提供更加流畅的用户体验。 2. 实现步骤 2.1 添加依赖库 首先,我们需要在项目的build…

    other 2023年8月20日
    00
  • 深入JS函数中默认参数的使用详解

    当然!下面是关于\”深入JS函数中默认参数的使用详解\”的完整攻略,包含两个示例说明。 深入JS函数中默认参数的使用详解 在JavaScript中,函数的默认参数允许我们为函数的参数提供默认值。下面是关于默认参数的使用方法和注意事项: 基本用法 在函数定义时,可以为参数指定默认值。如果调用函数时没有提供对应的参数值,将使用默认值。 示例代码: functio…

    other 2023年8月20日
    00
合作推广
合作推广
分享本页
返回顶部