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 called
AttributeSet
(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>
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(); }}
<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?
FirstAttributeSet
It 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.AttributeSet
The 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.AttributeSet
You 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? PassAttributeSet
The 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.
TypedArray
It 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 ),AttributeSet
To 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: IfAttributeSet
The 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:text
Nice. 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:text
Attribute.
<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.format
Attribute (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/values
The 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-styleable
The 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-styleable
Generally, the Class name of the custom View is written. This is mainly for intuitive expression.declare-styleable
Are 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 constructor
AttributeSet
To obtain the value of the custom attribute, but it is more difficult, andTypedArray
It 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)