Android has a deep understanding of Custom Attributes in Android and android

Source: Internet
Author: User

Android has a deep understanding of Custom Attributes in Android and android

Reprinted please indicate the source:
Http://blog.csdn.net/lmj623565791/article/details/41022631;
This article is from: [Zhang Hongyang's blog]

1. Introduction

For custom attributes, you must be familiar with the following steps:

Ps: if you are not familiar with the above steps, we recommend that you familiarize yourself with them before continuing ~

So, I have several questions:

  • How did the above steps work?
  • What does styleable mean? Can I leave it alone? I can declare a custom attribute. Why must I write a styleable?
  • If the system already has attributes with clear semantics, can I directly use them?
  • There is a parameter in the constructor calledAttributeSet
    (Eg: MyTextView (Context context, AttributeSet attrs) the parameter can be used to obtain an array of parameters?
  • What is TypedArray? Where should I use it?

Well, how can we answer these questions? Or: Lao Tzu will carry back the above four steps ~~

2. Common examples

Next, we will use examples to answer the above questions. The answer order of the questions is not fixed ~~ Let's take a look at a common example, that is, the code of the above steps.

  • Custom attribute declaration File
    <?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="test">        <attr name="text" format="string" />        <attr name="testAttr" format="integer" />    </declare-styleable></resources>
  • Custom View class
package com.example.test;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.util.Log;import android.view.View;public class MyTextView extends View {    private static final String TAG = MyTextView.class.getSimpleName();    public MyTextView(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);        String text = ta.getString(R.styleable.test_testAttr);        int textAttr = ta.getInteger(R.styleable.test_text, -1);        Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);        ta.recycle();    }}
  • Layout File
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:zhy="http://schemas.android.com/apk/res/com.example.test"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.example.test.MyTextView        android:layout_width="100dp"        android:layout_height="200dp"        zhy:testAttr="520"        zhy:text="helloworld" /></RelativeLayout>

OK. Let's take a 3 s scan. The running result is:

 MyTextView: text = helloworld , textAttr = 520

It should not be surprising. Note that my styleable name is test, so it is not necessarily the name of the custom View.

3. AttributeSet and TypedArray

Consider the following:

There is a parameter in the constructor calledAttributeSet(Eg: MyTextView (Context context, AttributeSet attrs) the parameter can be used to obtain the set of parameters?

FirstAttributeSetIt does save all the attributes of the View declaration, and it can be used to obtain (custom) attributes. How can this problem be solved?
Actually, let's take a look.AttributeSetThe method is clear. Let's look at the code below.

public MyTextView(Context context, AttributeSet attrs) {        super(context, attrs);        int count = attrs.getAttributeCount();        for (int i = 0; i < count; i++) {            String attrName = attrs.getAttributeName(i);            String attrVal = attrs.getAttributeValue(i);            Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);        }        // ==>use typedarray ...    }

Output:

MyTextView(4136): attrName = layout_width , attrVal = 100.0dipMyTextView(4136): attrName = layout_height , attrVal = 200.0dipMyTextView(4136): attrName = text , attrVal = helloworldMyTextView(4136): attrName = testAttr , attrVal = 520

Combined with the layout File above, what did you find?
I wiped it. It was amazing. I really got all the attributes. Well, that's right.AttributeSetYou can get the keys and values of all attributes defined in the layout file (there are some ways to try them by yourself). Does it mean that the TypedArray ghost can be discarded? The answer is:NO!.

Now pay attention to the next question:

What is TypedArray? Where should I use it?

Let's simply modify the attributes of MyTextView in the layout file.

<com.example.test.MyTextView        android:layout_width="@dimen/dp100"        android:layout_height="@dimen/dp200"        zhy:testAttr="520"        zhy:text="@string/hello_world" />

The result of running again is:

MyTextView(4692): attrName = layout_width , attrVal = @2131165234MyTextView(4692): attrName = layout_height , attrVal = @2131165235MyTextView(4692): attrName = text , attrVal = @2131361809MyTextView(4692): attrName = testAttr , attrVal = 520>>use typedarrayMyTextView(4692): text = Hello world! , textAttr = 520

What have you found? PassAttributeSetThe value obtained. If the reference is a string of @ + numbers. You said, can you understand this? Then you can see if the value obtained using TypedArray in the last row instantly understands something.

TypedArrayIt is actually used to simplify our work. For example, if the attribute value in the layout is of the reference type (for example, @ dimen/dp100 ),AttributeSetTo obtain the final pixel value, you need to get the id in the first step, and then parse the id in the second step. TypedArray helps us simplify this process.

Post: IfAttributeSetThe process of obtaining the final pixel value:

int widthDimensionId =  attrs.getAttributeResourceValue(0, -1);        Log.e(TAG, "layout_width= "+getResources().getDimension(widthDimensionId));

Okay. Now, if someone asks you about the meaning of TypedArray, you can tell him.

4. declare-styleable

We have solved two problems. Next, let's look at the layout file. We have a property called:zhy:text.
In general, the system provides the following attributes:android:text, So I think the direct useandroid:textNice. In this case, consider the following:

If the system already has attributes with clear semantics, can I directly use them?

The answer is yes. How can this problem be solved?
Directly in attrs. xmlandroid:textAttribute.

    <declare-styleable name="test">        <attr name="android:text" />        <attr name="testAttr" format="integer" />    </declare-styleable>

Note: here we use defined attributes and do not need to add them.formatAttribute (note the difference between the Declaration and usage. The difference is that there is no format ).
Then obtain the following information in the class:ta.getString(R.styleable.test_android_text)Layout file directlyandroid:text="@string/hello_world"You can.

The attributes defined in the system are similar to the custom attributes.sdk/platforms/android-xx/data/res/valuesThe System-defined attributes are displayed in this directory. Then, you can find the code for TypedArray to obtain the attribute in the system's View (eg: TextView) constructor (you can check it yourself ).

OK. Next, I'm thinking, sincedeclare-styleableThe name of this label can be written at will. If you are so casual, consider the following:

What does styleable mean? Can I leave it alone? I can declare a custom attribute. Why must I write a styleable?

In fact, it can be left empty. How can this problem be solved?

  • First, delete the declare-styleable label.

Now the attrs. xml is:

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="testAttr" format="integer" /></resources>

Xianxi, so refreshing ~
* MyTextView implementation

Package com. example. test; import android. content. context; import android. content. res. typedArray; import android. util. attributeSet; import android. util. log; import android. view. view; public class MyTextView extends View {private static final String TAG = MyTextView. class. getSimpleName (); private static final int [] mAttr = {android. r. attr. text, R. attr. testAttr}; private static final int ATTR_ANDROID_TEX T = 0; private static final int ATTR_TESTATTR = 1; public MyTextView (Context context, AttributeSet attrs) {super (context, attrs ); // ==> use typedarray TypedArray ta = context. obtainStyledAttributes (attrs, mAttr); String text = ta. getString (ATTR_ANDROID_TEXT); int textAttr = ta. getInteger (ATTR_TESTATTR,-1); // output text = Hello world! , TextAttr = 520 Log. e (TAG, "text =" + text + ", textAttr =" + textAttr); ta. recycle ();}}

It seems that there is more code. We can see that we have declared an int array, and the elements in the array are the id of the attr we want to obtain. In addition, according to the position of the element in the array, we define some Integer constants to represent their subscript, and thenTypedArray.
We can see that our original:

R.styleable.test => mAttrR.styleable.test_text => ATTR_ANDROID_TEXT(0)R.styleable.test_testAttr => ATTR_TESTATTR(1)

So what? Android will do the same internally. According to the traditional writing method, it will generate the following code in R. java:

public static final class attr {    public static final int testAttr=0x7f0100a9;    }public static final class styleable {     public static final int test_android_text = 0;     public static final int test_testAttr = 1;      public static final int[] test = {            0x0101014f, 0x7f0100a9        };    }

OK, based on what you should find above. The emergence of styleale allows us to write a lot of constants (int [] array, subscript constant) and so on, simplifying our development work (think about writing constants if there are a bunch of attributes, what code do you need to write ). So you must knowdeclare-styleableGenerally, the Class name of the custom View is written. This is mainly for intuitive expression.declare-styleableAre used to change the View attributes.

In fact, it is useful to understand this principle. For details, see: Android custom controls elegantly implement the separation line between elements.

Okay. Now I have five questions and answered four. The first question is:

How can the steps for Custom Attributes work?

Well, the above and basically cover the answer to this question. You can summarize it yourself, so: omitted.

Summarize today's blog.

  • Attrs. declare-styleable and item in xml. android will. java generates some constants for ease of use (aapt). Essentially, we can declare only the required attributes without declaring declare-styleable.
  • In the View constructorAttributeSetTo obtain the value of the custom attribute, but it is more difficult, andTypedArrayIt is convenient for us to obtain.
  • When customizing a View, you can use the attributes that have been defined by the system.

Recent update plan: Blog related to some details of the custom View (focusing on interaction), articles related to Android best practices, and articles related to framework are coming soon.

GROUP: 423372824

Public Account: hongyangAndroid
(Please pay attention to it and push blog information as soon as possible)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.