一、前言

上节 讲解了旋转圆环基本的实现方法。本文将在此基础上进一步改进,在属性文件中自定义控件属性,避免代码中显式调用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. java的排序问题

    普通排序 对于基础数据类型的排序,基本只是调用一下方法 如java的 1 Arrays.sort(nums); 那么如何自定义排序规则呢? 自定义排序规则: 假设现在有这么个问题,有n个学生, 每个学 ...

  2. padding&margin

    margin是盒子的外边距,即盒子与盒子之间的距离,而padding是内边距,是盒子的边与盒子内部元素的距离. 鞋盒里面的鞋到 盒子的距离设置为 padding ,而 鞋盒到鞋架的距离设置为margi ...

  3. Cloud9 3.0 SDK安装

    Cloud9 IDE是一个基于Node.JS构建的JavaScript程序开发Web IDE.它拥有一个非常快的文本编辑器支持为JS, HTML, CSS和这几种的混合代码进行着色显示.Cloud9 ...

  4. FastReport 单元行自动换行 Table Object AutoSize

    FastReport 官方实例138.fr3 有关于单元行自动换行的描述.The table object can grow depends on cells content. Notes:- set ...

  5. fiddler 调试

    如果本地代理js发现跨域,需要手动修改自定义规则 1 static function OnBeforeResponse(oSession: Session) { 2 if (m_Hide304s &a ...

  6. Java-面向对象基础 this& 重载

    1.this表示当前对象 获取当前对象的属性 使用this调用当前属性 2.重载 如果两个方法的方法名相同,但参数不一致,那么可以说一个方法是另一个方法的重载

  7. 对于小白如何才能学好Java

    我们学习任何一种编程语言,不是去无目的的网上找太多的教程,而是首先从宏观了解它的基本思想方法定义概念,从宏观感受它的逻辑与抽象,然后是实践,不断的实践.今天我们看看网上给我们小白的一些学习建议. 一. ...

  8. Eureka服务端创建及服务注册

    一.Eureka服务端创建 1. 引入依赖:pom.xml <!-- eureka 服务端 --> <dependency> <groupId>org.spring ...

  9. svn批量忽略文件夹和批量忽略某种类型文件方法

    批量忽略文件夹: 最简单的方法:不勾选这个 1.在svn管理的根目录下点击右键---> TortoiseSVN --> properties 2.点击new-->other 3.在p ...

  10. python_列表和元组的转换

    1, 通过list函数将元组的数据获取到,保存到新定义的列表里面.备注:元组的数据不会更改. info_tuple = ("小明", 24, 1.75) info_list = l ...