12

Android自定义控件之自定义属性

 3 years ago
source link: https://blog.csdn.net/dmk877/article/details/108007322
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

自定义控件可以说是android里的一个门槛,对很多android开发者来说可能都会认为比较难,当然这也是成为一个高手的必经之路,因此我准备在定义控件上多下些功夫,多花点时间研究,多写博客,如果想一起学习自定义控件,欢迎大家关注,如有疑问欢迎留言,如有谬误欢迎批评指正。

format,png

通过本篇博客你将学到以下内容

1.自定义控件的步骤

2.自定义view中自定义属性的方法

3.自定义属性中format 10中类型的详解

一、自定义控件步骤

1.自定义View属性
2.重写onMeasure
3.重写onLayout
4.重写onDraw
今天这篇博客主要介绍第一步自定义属性,通过一个案例来进行讲解
案例的效果如下

format,png
即我们通过自定义View画一个圆,其中可以控制圆的半径大小和颜色,具体怎么做的呢?

二、自定义属性方法

1.首先在res/values/目录下创建attrs文件,如下所示

<declare-styleable name="CircleView">

      <attr name="circleRadius" format="dimension"/>
      <attr name="circleColor" format="color"/>
</declare-styleable>

WheelRecyclerView是自己起的名字,不要与系统的冲突就行,
<attr name="circleRadius" format="dimension"/>其中name就是自定义属性的名字(类似于系统控件的android:layout_width) format 就是属性的类型,这里支持10种类型,如下图所示

format,png
我们先把这个小案例的流程走完,大家对流程熟悉之后再对细节进行讲解。

2.编写自定义View,并在构造方法中获取我们自定义的属性


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

    public CircleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

	/**
     * 获取自定义属性
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

         TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.CircleView);
        /**
         * 获取圆的半径属性
         */
        circleRadius=ta.getDimension(R.styleable.CircleView_circleRadius,DEFAULT_RADIUS);
        /**
         * 获取圆的颜色属性
         */
        mColor=ta.getColor(R.styleable.CircleView_circleColor,DEFAULT_COLOR);
        ta.recycle();


        init();
    }

从上面可以看出,在一个参数的构造方法中,调用了两个参数的构造方法,然后在两个参数的构造方法中调用了三个参数的构造方法,然后通过context的obtainStyledAttributes方法可以得到一个TypedArray对象,这个对象里面封装了获取各个属性的方法,比如getDimension,getColor,getFloat等方法用来获取属性值。

3.重写onMeasure方法

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        /**
         * Extracts the mode from the supplied measure specification
         * 从提供的测量规范中获取模式
         */
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        /**
         * Extracts the size from the supplied measure specification
         * 从提供的测量规范中获取大小
         */
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);

        int heightMode=MeasureSpec.getMode(heightMeasureSpec);
        int heightSize=MeasureSpec.getSize(heightMeasureSpec);
        /**
         * 如果宽度的测量模式是AT_MOST
         * 则设置宽度
         */
        if(widthMode==MeasureSpec.AT_MOST){

            widthSize= (int) (circleRadius*2+getPaddingLeft()+getPaddingRight());
        }

        if(heightMode==MeasureSpec.AT_MOST){

            heightSize= (int) (circleRadius*2+getPaddingTop()+getPaddingBottom());
        }

        setMeasuredDimension(widthSize,heightSize);
    }

上面我们重写了onMeasure方法,获取测量模式、获取控价大小并且按照我们自己的要求制定规则调用setMeasuredDimension此方法设置最终的宽和高。

4.重写onDraw方法

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int paddingLeft=getPaddingLeft();
        int paddingTop=getPaddingTop();
        int paddingBottom=getPaddingBottom();
        int paddingRight=getPaddingRight();

        int width=getWidth()-paddingLeft-paddingRight;
        int height=getHeight()-paddingBottom-paddingTop;

        canvas.drawCircle(width/2+paddingLeft,height/2+paddingTop,circleRadius,mPaint);
    }

onDraw方法很简单就是调用canvas的drawCircle方法,设置好圆的位置、半径和画笔画一个圆

到这里一个简单的自定义控件以及完成了,在布局中声明我们自定义的View如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.example.video.CircleView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:padding="5dp"
        app:circleRadius="50dp"
        app:circleColor="#FF0000"/>

</LinearLayout>

运行即可看到文章开头的效果。

三、自定义属性format类型详解

接下来咱们对自定义属性时的format的类型做一下说明,format的类型一共10中分别为:
string、boolean、color、dimension、enum、flags、float、fraction、integer、reference。

1.string

即字符串这个很好理解,类似于系统的textview设置text内容,在attrs中声明如下

<declare-styleable name="名称">
    <attr name="text" format="string"/>
</declare-styleable>

在布局中设置如下

app:text="Hello World!"

系统textview的text设置如下

android:text="hello world!!!"

2.boolean

布尔类型,有两个值true和false,类似于系统Button的clickable属性,在attrs中声明如下

<declare-styleable name="名称">
    <attr name="clickable" format="boolean"/>
</declare-styleable>

在布局中设置如下

app:clickable="true"

系统button的clickable设置如下

android:clickable="false"

3.color

设置颜色即设置16进制的颜色,在attrs中声明如下

<declare-styleable name="名称">
    <attr name="color" format="color"/>
</declare-styleable>

在布局中有如下两种设置方式

app:color="#FFFFFF"
app:color="@color/id"

系统中给TextView设置字体颜色

android:textColor="@color/colorPrimary"

4.dimension

设置尺寸值,一般用来设置dp值,在attrs中声明如下

<declare-styleable name="名称">
    <attr name="circleRadius" format="dimension" />
</declare-styleable>

在布局中可以进行如下设置

 app:circleRadius="50dp"

系统textview设置宽度的方法

 android:layout_width="50dp"

5.enum

设置枚举,一般有几个选项,用来选择,可以参考LinearLayout的orientation属性,在attrs中声明如下

<attr name="orientation">
    <enum name="horizontal" value="0"/>
    <enum name="vertical" value="1"/>
</attr>

在布局中可以进行如下的属性设置

enum

可以看到当我们输入orientation的时候会有两个选项就是我们上述xml中所声明的horizontal和vertical

系统中的LinearLayout与之同理。

6.flags

位或运算即可以进行多个选择,在atts中声明如下

<declare-styleable name="CircleView">
     <attr name="gravity" format="flags">
         <flag name="top" value="0"/>
         <flag name="center" value="1"/>
         <flag name="right" value="2"/>
         <flag name="left" value="3"/>
     </attr>
</declare-styleable>

在布局中可以进行如下的属性设置

app:gravity="right|left|top"

7.float

浮点类型,在attr中声明如下

<declare-styleable name="CircleView"> 
   <attr name = "alpha" format="float" />
</declare-styleable>

在布局中可以对属性进行如下设置

app:alpha="0.8"

8.fraction

百分数,一般有两种

  • 100% 表示相对于对象自身的百分比
  • 100%p 表示相对于父容器的百分比,percent of parent
<declare-styleable name="CircleView">
   <attr name="progress" format="fraction"/>
</declare-styleable>

在布局中可以属性进行如下设置

app:progress="50%"

9.integer

整形,这个很简单,就不说了

10.reference

某一资源ID,在attr中声明如下

<declare-styleable name="CircleView">
	<attr name="pic" format="reference"/>
</declare-styleable>

在布局中可以对属性进行如下设置

app:pic="@mipmap/ic_launcher"

好了以上就是对自定义属性内容的学习比较简单,但是也必须要从简单的学起,后续会逐步更新自定义View相关的内容,如有谬误欢迎批评指正,如果觉得本篇博客对你有帮助,就点个赞呗。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK