zoukankan      html  css  js  c++  java
  • 手把手教你自定义attr

          最近在学习的过程中遇到了自定义的attr和自定义的style。因此各种百度,各种博客的学习,算是有了一个系统的了解。在这里记录下自己的收获。

    一、为什么要使用自定义attr以及本文定位

        在android开发中,很多时候需要我们自定义view,这其中就包含了一个view的很多属性的设置。有时候会出现android本身提供的属性并不够用(比如它针对某些控件提供的text属性,color属性等),又或者我们想将android系统提供的属性集成到一起形成自己的一套属性集合。那么这个时候,就需要我们来自定义一套自己的属性,这就是自定义attr。因此自定义attr与自定义view是密切关联的。对于自定义attr更加深入的理解,在这里推荐我十分佩服的一位大神的博客文章http://blog.csdn.net/lmj623565791/article/details/45022631

        但是建议你还是阅读完本文,再去点击上面的链接。因为本文将手把手带你去实现一个自定义的attr,这样子你会了解整个自定义attr流程。既然是手把手,所以本文不会涉及到原理性的东西,而且代码十分简单易懂,因为我也是初学者,所以力求将一个初学者学习的过程展现出来,当然其中的某些疑问可能对于anroid老鸟来说是十分幼稚的。不过知识就是这样子一点点一步步收获起来的。好了,废话不多说,进入正文吧。

    二、你必须要了解的

        首先实现一个自定义attr的流程:

    (1)先有一个自定义的view(它是你所自定义attr的使用者)

    (2)然后在values文件夹下建立attrs.xml文件,编写你的自定义的属性。示例代码如下:

    1  <?xml version="1.0" encoding="utf-8"?>
    2 <resources>
    3 
    4     <declare-styleable name="test">
    5         <attr name="text" format="string" />
    6         <attr name="testAttr" format="integer" />
    7     </declare-styleable>
    8 
    9 </resources>

    (3)在xml文件中使用自定义属性,为它赋值

    (4)在自定义view中使用TypedArray获取你所赋的值,并用作其他用途。

          

         现在主要说明编写自定义属性的代码中,即上面的xml文件中,format的含义。其实format就是为自定义的属性设置一个格式。这根android给我们提供的属性是一样的道理,比如android给我们提供的text的属性格式就是string类型的,在我们为一个TextView设置text的时候可不就是写一个字符串嘛。那么上面的代码的意思就是自定义的属性text,格式是string类型,testAttr,类型是integer。下面来看一个format都可以指定为什么。如下:

    format还可以指定其他的类型比如;
    reference   表示引用,参考某一资源ID
    string   表示字符串
    color   表示颜色值
    dimension   表示尺寸值
    boolean   表示布尔值
    integer   表示整型值
    float   表示浮点值
    fraction   表示百分数
    enum   表示枚举值
    flag   表示位运算

          可能还还有其他的疑问,比如其他关键字的含义是什么,以及是怎么使用自定义attr的。甚至还有很细的说不清的疑问。如果没有实际代码的话,很难说明白这些疑问。所以跟着我来往下一步一步写一个例子出来吧,在这个过程中,相信你的疑问应该会被解开。

    三、实现自定义attr,同时解答细节上的疑问    

          在这个例子中,我们来实现超级简单的自定义view,在屏幕上写用画笔写出一个字符串出来。纯粹是为了说明自定义attr的实现过程的。而字符串的颜色以及字符串的内容,就采用自定义属性的方式来获取。我们心中已经有了这个自定义的view的大概了,下面就开始编写自定义attr吧。

          新建项目,然后在它的res/values下面新建attrs.xml文件,代码如下:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <resources>
    3      <declare-styleable name="MyView">  
    4         <attr name="myText" format="string"/>  
    5         <attr name="myColor" format="color"/>  
    6     </declare-styleable>  
    7 </resources>

          从代码中我们可以看到,自定义了两个属性,myText和myColor,类型分别为string何color。然后要说明两点:

    (1)你可以将declare-styleable看成一个集合的名称,而它里面的元素就是我们自定义的属性。它可以命名为任意名称,不过一般都命名为相应的自定义的view的名称,表示是为这个view定制的属性,也方便查阅。在这里我随便命名了一个名字,为MyView。通过这个名称就可以找到我们自定义的属性。resources标签下可以有多个declare-styleable的。
    (2)标签attr下的name就是自定义的属性名,可以任意命名,format为其格式类型。

         你肯定还在疑问,自定义的属性都自定义好了,怎么用呢?那么我们现在就来使用它。首先将与之相关的自定义的view先建出来。新建类CustomView继承自view,代码如下:

     1 package com.fuly.kun;
     2 
     3 import android.content.Context;
     4 
     5 import android.view.View;
     6 
     7 public class CustomView extends View {
     8     
     9     public CustomView(Context context, AttributeSet attrs) {
    10         super(context, attrs);
    11         
    12     }
    13     
    14 }

          代码很简单,在这个自定义的view中,我们什么都没有做。这个view肯定是要显示出来的,那么我就修改activity_main.xml的代码,将其显示出来。注意这个时候,就该为CustomView设定属性了,此时就开始使用自定义的attr了。好了,快看代码吧,代码:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     xmlns:fuly="http://schemas.android.com/apk/res/com.fuly.kun"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6    >
     7 
     8    <com.fuly.kun.CustomView
     9        android:layout_width="wrap_content"
    10        android:layout_height="wrap_content"
    11        fuly:myText="我是自定义attr"
    12        fuly:myColor="#00ff00"/>
    13 </RelativeLayout>

          代码很简单,我们给自定义的view赋了属性值。是不是发现了什么,有些代码跟你之前用的不一样!下面我们就来详细说明一下怎么就把自定义的属性给使用进来了。如下说明:

    (1)首先观察代码的第3行,这句话就是引入了我们项目中自定义的attr。是不是发现第三行和第一行的代码很像,其实你现在明白了吧,第一行其实就是因为android系统给出的属性,所以下面我们才能使用android:layout_width等。因为引入自定义attr,主要将后缀的android替换成为项目的包名即可,即替换为了Manifest.xml下的package标签下的包名。而我们将引入的自定义attr命名为了fuly,然后在使用自定义属性时就借助fuly来找到我们自定义的属性名称了。fuly这个名称可以随便指定,没有什么规则。
    (2)再观察第11行和第12行的代码,跟第9行和第10行的代码是不是很像,这就是在CustomView使用自定义的属性,并为其赋值(一定要注意和其格式类型要相同)。

          好了,现在要修改CustomView的代码了。获取到我们自定义的属性值,并使用它。这其实跟android获取自带的属性是一样的道理,比如我们给一个TextView的text赋了一个字符串,然后在代码中使用getText()方法就可以这个字符串,即给text所赋的属性值。好了,快看代码吧,如下:

     1 package com.fuly.kun;
     2 
     3 import android.content.Context;
     4 import android.content.res.TypedArray;
     5 import android.graphics.Canvas;
     6 import android.graphics.Paint;
     7 import android.util.AttributeSet;
     8 import android.view.View;
     9 
    10 public class CustomView extends View {
    11     
    12     private TypedArray ta;//用来获取自定义属性的
    13     
    14 
    15     public CustomView(Context context, AttributeSet attrs) {
    16         super(context, attrs);
    17         //获取到我们自定义的属性
    18         ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
    19     }
    20     
    21     protected void onDraw(Canvas canvas) {
    22 
    23         super.onDraw(canvas);
    24         //获取到我们为自定义的属性所赋的值
    25         String text = ta.getString(R.styleable.MyView_myText);
    26         int color = ta.getColor(R.styleable.MyView_myColor, 003300);
    27         
    28         Paint paint = new Paint();
    29         paint.setColor(color);
    30         paint.setTextSize(55);
    31         canvas.drawText(text, 100, 100, paint);
    32     }
    33 
    34 }

           代码很简单。只不过就牵涉了一个知识点,获取自定义属性的值,要使用TypedArray这个类而已。在代码的第18行,我们获取了一个TypedArray实例,而且这个实例是跟我们自定义的属性集合MyView相关联的。然后再代码的第25和26行,就可以用这个TypedArray对象获取自定义属性的值了。注意ta.getColor的第二个参数意思是如果该属性没有赋值,就返回颜色“#003300”。然后我们将获取到的文本和颜色作用到画笔和画布上即可。

          好了,MainActivtity中的代码已经加载了acitivty_main.xml布局,不需要更改。下面我们直接运行效果,如下:

    小结:

    主要是TypedArray的对象的获得,是通过Context的,如下:
     ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);

    关于它的一系列方法,可以翻看API文档,这里总结没有什么意义。

          好了,相信对自定义attr有了一个初步的了解了吧。以后程序开发中要比这个里复杂的多。学习进阶,不要怕难,贵在坚持!一起进步

     

  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/fuly550871915/p/4907048.html
Copyright © 2011-2022 走看看