Android Development Tips-custom properties for custom controls

Source: Internet
Author: User

Android Development Tips-custom properties for custom controls

It is important to master custom controls, because with custom controls, you can: solve UI problems, optimize layout performance, and simplify layout code .

The previous article talked about how to organize several controls through XML and inherit some ViewGroup subclasses and encapsulate them for use. This is the simplest kind of custom control we've ever come into contact with. But many times we also need to use them in layout files to influence the final display by passing in some values through attributes.

One of the things we often encounter in a project: A picture plus a combination of text. For example, the top-up account after the successful display of an interface, which is a successful icon, the following is the corresponding text: "Top-up success." Or in the Account entry box on the login screen, the left side of the input box needs to display an icon representing the account. As shown below:

Bulky implementation of icon text combinations

In the first case, we may adopt a ImageView plus TextView approach. Later through the tips of the lint tool, or the other way, you may be aware of several properties of TextView, drawableLeft drawableRight drawableTop as well as drawableBottom can be done. However, when used, you will find that these properties are set in the image, according to their own size to display.
It doesn't matter, let the designer cut the picture. But the heart is not the end. Because the Android phone, your company's test machine is only those two or three, perhaps replaced by a large screen of a low-resolution thousand-yuan machine, the icon is big. So you still want to set the size of the picture.

Using a TextView implementation

To set a TextView drawable size, you can set its bounds by invoking the Drawable method in the Java code setBounds(int left, int top, int right, int bottom) , and then invoke the setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) method to set our Drawable object in.
But it's too cumbersome to set up each call, so we can inherit to TextView write one DrawableTextView , rewrite the setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) method, or setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable start, Drawable top, Drawable end, Drawable bottom) , if you are drawableStart setting the picture through and drawableEnd properties. The effect can also be achieved by doing the drawable here setBounds() .
Now we have achieved the above effect with a TextView TextView+ImageView , and achieved our goal: optimizing layout performance and simplifying layout code.
However, for such a control, we may use it in multiple areas of the project, or in other projects. So I hope to make it more generic. At this point we cannot write the width and height of the dead drawable, but want to be able to control the external XML when it is used, that is----custom attributes.

Custom properties

First res/values/attrs.xml , define one in the file (if not created) declare-styleable , and then define two attributes in it, representing the width and height of the drawable, respectively:

<declare-styleable name="DrawableTextView">    <attr name="drawableHeight" format="dimension"/>    <attr name="drawableWidth" format="dimension"/></declare-styleable>

declare-styleableThe name name is usually written as the class name of our control, so that in the write layout code, Android Studio can give us a corresponding property hint.
In the attr definition is our property, is the name name of the property, format is the type of the property, here we define the type as dimension .

The properties are defined, or can be used in the layout code. But we also need to read the properties in our custom DrawableTextView . First rewrite the construction method:

    publicDrawableTextView(Context context) {        super(context);    }    publicDrawableTextView(Context context, AttributeSet attrs) {        super(context, attrs);        applyAttributes(context, attrs);    }    publicDrawableTextViewint defStyleAttr) {        super(context, attrs, defStyleAttr);        applyAttributes(context, attrs);    }

We then call our custom applyAttributes() method inside, where we will read the property. We need to declare two properties in our class:

    privateint mDrawableWidth;    privateint mDrawableHeight;

Then in the applyAttributes() method, get the property value through Typedarray:

 TypedArray TypedArray = Context.obtainstyledattributes  (attrs, R.styleable  ) ;  Mdrawablewidth = Typedarray.getdimensionpixelsize  (R.styleable   _drawablewidth, 0 ) ;  Mdrawableheight = Typedarray.getdimensionpixelsize  (R.styleable   _drawableheight, 0 ) ;  Typedarray.recycle  () ;   

To illustrate, Attrs is the associated set of properties that we define in XML. By calling context.obtainStyledAttributes(attrs, R.styleable.DrawableButton); , we are able to receive our style attributes in the theme corresponding to the context, that is, the property values we can also set in theme. About specifying attribute values in theme, the following blog will be described in detail, and here is a brief discussion. The second argument is the one we define. declare-styleable
After getting the TypedArray object, we can get the value of each property through the GetXXX method inside it, for example, getDimensionPixelSize(int index, int defValue) the pixel size corresponding to the attribute size is obtained by means of the method. The first parameter is the index of the property, and the second is the default value. After the property has been obtained, it must be called typedArray.recycle() to be recycled so that subsequent callers can reuse it. Because some typedarray data is cached in the resources object, it is typedarray used to optimize memory utilization.

After we get the attribute value and assign it to our member variable, we can set it in the following way. Since this article focuses on custom attributes, the subsequent implementation of this project can be referred to my project Drawablewidget on GitHub.

In the above example, attrs there is a problem with defining attributes. Because we define drawableWidth and drawableHeight attribute directly, if I have a project to use it, and use another library at the same time, that library also defines these two attributes, it will create a conflict. So one thing to emphasize: for custom attributes, we have to add our own prefixes . For example, the attribute is defined as nbDrawableWidth and so on. (My project is not mature when writing, and I am a little lazy, do not encounter problems always do not want to change, for the time being a counter-example bar. )

Common Properties

There is one more situation. We will often encounter such a situation in the layout:

Each entry in the layout is separated by a split line. And these conditions will be divided into groups, the group inside the split line has a left margin. This kind of situation is very good realization, rewrite this layout, in the OnDraw inside draw the line to be possible. We think of each item on the right as: a full split line above or without a split line, the following is a split line with margins, or a full split line. This allows us to define a Pwborder attribute, which defines the <flag name="TOP" value="1"/>``<flag name="BOTTOM" value="2"/> token bit. Then in the code to get the value of Pwborder, with 1 do & operation, more than 0 means to draw the above the split line, otherwise do not draw, and 2 do & operation, greater than 0 is to represent the complete split line, otherwise draw with margin of the split line. If you need a left or right split line, you can also define a flag bit with a value of 4 or 8.
When XML references it, the property is this:

app:pwBorder="TOP|BOTTOM"

However, other controls that we are writing may include this property as well as other properties, except that this relativelayout requires this property. At this point we can pull out attr the definition and write it out of the declare-styleable node. As follows:

    <!--layout properties with Borders-    <attr name="Pwborder">        <flag Name="TOP" value="1"/>        <flag Name="BOTTOM" value="2"/>    </attr>    <attr name="pwborderwidth" format="Dimension"/>    <attr name="Pwbordercolor" format="Color"/>

Then use this again:

    <declare-styleable name="Borderlinearlayout">        <attr name="Pwborder"/>        <attr name="Pwborderwidth"/>        <attr name="Pwbordercolor"/>    </declare-styleable>    <declare-styleable name="Textfieldview">        <attr name="Pwborder"/>        <attr name="Pwborderwidth"/>        <attr name="Pwbordercolor"/>        <attr name="Pwlabel"/>        <attr name="Pwvalue" format="string"/>        <attr name="Pwicon" format="Reference"/>    </declare-styleable>

I recommend that you use this method to define attributes. Because this is true when our properties have exactly the same name as the properties of other libraries, if the defined format is the same, it can be merged and compiled.

This article original, reproduced please indicate the source: http://blog.csdn.net/maosidiaoxian/article/details/50009725

[1]https://github.com/msdx/drawablewidget

Android Development Tips-custom properties for custom controls

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.