一、前言

上节 讲解了旋转圆环基本的实现方法。本文将在此基础上进一步改进,在属性文件中自定义控件属性,避免代码中显式调用setXXX() 方法。

二、流程

首先,在资源文件 values 中新建一个 attr.xml,其中定义了我们即将使用的几个旋转环的属性,如下所示

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RotatingRing">
<attr name="width" format="integer"/>
<attr name="radius" format="integer"/>
<attr name="start_angle" format="integer"/>
<attr name="sweep_angle" format="integer"/>
<attr name="start_color" format="color"/>
<attr name="end_color" format="color"/>
<attr name="color" format="color"/>
<attr name="duration" format="integer"/>
</declare-styleable>
</resources>

在 RotatingRing 类中,添加第三个构造函数 (含3个参数的),如下所示

public RotatingRing(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

根据属性清单获取属性值

public RotatingRing(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotatingRing);
radius = typedArray.getInt(R.styleable.RotatingRing_radius, 100);
width = typedArray.getInt(R.styleable.RotatingRing_width, 20);
startAngle = typedArray.getInt(R.styleable.RotatingRing_start_angle, 0);
sweepAngle = typedArray.getInt(R.styleable.RotatingRing_sweep_angle, 270);
startColor = typedArray.getColor(R.styleable.RotatingRing_start_color, Color.WHITE);
endColor = typedArray.getColor(R.styleable.RotatingRing_end_color, typedArray.getColor(R.styleable.RotatingRing_color, Color.BLUE));
duration = typedArray.getColor(R.styleable.RotatingRing_duration, 1000);
typedArray.recycle();
}

由上所述,默认值可以被第三个构造函数所定义,故可以去除第一个构造函数里定义的的默认值,改进后的构造函数如下所示

public RotatingRing(Context context) {
this(context, null);
} public RotatingRing(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public RotatingRing(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotatingRing);
radius = typedArray.getInt(R.styleable.RotatingRing_radius, 100);
width = typedArray.getInt(R.styleable.RotatingRing_width, 20);
startAngle = typedArray.getInt(R.styleable.RotatingRing_start_angle, 0);
sweepAngle = typedArray.getInt(R.styleable.RotatingRing_sweep_angle, 270);
startColor = typedArray.getColor(R.styleable.RotatingRing_start_color, Color.WHITE);
endColor = typedArray.getColor(R.styleable.RotatingRing_end_color, typedArray.getColor(R.styleable.RotatingRing_color, Color.BLUE));
duration = typedArray.getColor(R.styleable.RotatingRing_duration, 1000);
typedArray.recycle();
}

到此,可以去除 MainActivity 中的 RotatingRing.setXXX()方法,而在 activity_main.xml 里定义属性

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"> <draw.bitmap.canvas.RotatingRing
android:id="@+id/rotating_ring"
android:layout_width="400dp"
android:layout_height="400dp" app:width="30"
app:radius="150"
app:start_angle="0"
app:sweep_angle="270"
app:duration="1500"
app:start_color="@color/colorWhite"
app:end_color="@color/colorRed" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>

其中‘app’为原布局文件里定义好的命名空间,这里我直接拿来用了,也可以自己定义命名空间,只须在布局文件头加上

xmlns:命名空间="http://schemas.android.com/apk/res-auto"

这里我为区分定义了一个红色的圆环,而其他参数与原先 MainActivity 里setXXX() 方法里的参数一致,修改后的代码为

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { RotatingRing rotatingRing; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rotatingRing = findViewById(R.id.rotating_ring);
rotatingRing.startAnim();
}
}

运行效果

到此已经初步掌握了自定义view的一些必要性质,下一节将深入了解一些高级属性以及绘制相关源码等。

Android 自定义View (三)的更多相关文章

  1. Android 自定义View (三) 圆环交替 等待效果

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24500107 一个朋友今天有这么个需求(下图),我觉得那自定义View来做还是很 ...

  2. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  3. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  4. Android自定义View(三、深入解析控件测量onMeasure)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51490283 本文出自:[openXu的博客] 目录: onMeasure什么时候会被调用 ...

  5. 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...

  6. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  7. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  8. Android 自定义View (五)——实践

    前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...

  9. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  10. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

随机推荐

  1. D_GLIBCXX_USE_CXX11_ABI

    gcc ABI兼容 设置=0,表示使用C++11之前的ABI 反之,使用C++11的ABI

  2. 关于sql时间方面的处理

    查询大于时间两小时(例:订单设置两小时后过期 $res = Order::where(['status'=>0,'sid'=>1])->whereRaw("created_ ...

  3. Demo of canvas, canvas optimization and svg

    It used the canvas to draw the curves in the old project, and the client felt that it was vague, so ...

  4. @JsonSerialize(using = ToStringSerializer.class) 转换失败

    解决方案 但实际开发过程中,数据库的bigint,Java的Long都是比较常用的数据类型,为了避免精度丢失,针对这种比较大的数值 全局配置,将数值类型转换为文本如果需要将所有的数值类型全部转换成文本 ...

  5. pgsql 查询结果转换为json数组

    select array_to_json(array_agg(row_to_json(t))) from (SELECT * FROM test) t

  6. 【1】java之类与对象

    一.前言 面向对象就是一种组件化的设计思想. 面向对象特性 封装性:保护内部的定义结构安全性: 继承性:在已有的程序结构上继续扩充新的功能: 多态性:在某一个概念范围内的满足. 二.类与对象的定义和使 ...

  7. std::string实现split和trim方法

    void split(const std::string& str, const std::string& strDelimiter, std::vector<std::stri ...

  8. 用python3操作mysql数据库实现企业级产品参数查询

    Python3 MySQL 数据库连接 - PyMySQL 驱动 一.什么是 PyMySQL? PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则 ...

  9. Java流程控制之顺序结构+选择结构

    顺序结构 Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行. 顺序结构是最简单的算法结构. 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是有若干个依次执行的处理步骤组 ...

  10. navicat 远程连接不上mysql

    1 查看是否开启远程连接(拿root用户举例) use mysql; select host, user from user; 以上便是开启远程连接,如果依旧不能连接,参考如下: grant all ...