Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the Android shader Tint

2025-03-04 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "how to use Android shader Tint". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Tint is mainly used to reduce the volume of apk. For example, I now have a textview. There are two kinds of background images, one is the an image displayed when the focus is obtained, and the other is the b image displayed when the focus is lost.

I believe that this requirement has been done many times when we are developing, and we will generally find that this kind of a map and b map are the same except for different colors, but when we do it, we usually ask ui for two pictures.

If you want to adapt to the resolution, it is very likely that there will be more pictures, and the efficiency will be much lower because the bitmap is reloaded when switching. So Google gave us a solution and this is tint.

His goal is that when you find this need, just put a picture in apk, and use Tint when you need to change the color of the background image.

First, let's define a simple layout file:

We found that both imageview references the same drawable resource, and in the xml editing interface of studio, we can obviously see that the color of this image is black, right?

So now we want to change the background color of iv1 imageview to green! We take it for granted that it will be written like this:

Iv1 = (ImageView) this.findViewById (R.id.iv1); iv2 = (ImageView) this.findViewById (R.id.iv2); final Drawable originBitmapDrawable = getResources (). GetDrawable (R.drawable.ic_account_circle_black_18dp); iv1.setImageDrawable (tintDrawable (originBitmapDrawable, ColorStateList.valueOf (Color.GREEN)

It should be easy to understand, right? the code doesn't explain. But after running it, we found that:

Shit, how come they both turn green!

Looking back at our code, we should be able to understand that both imageview references the same drawable. Since it is a drawable, the system must have made a copy of the two drawable in memory in order to optimize resources.

Remember the bitmap optimization article we talked about before? http://www.cnblogs.com/punkisnotdead/p/4881771.html is similar to the inBitmap attribute in this one, if you don't understand it, you can understand it by looking at the figure below:

That's why it caused the above situation. You modify the common variable, so both graphs are affected.

The solution is actually very simple:

Final Drawable originBitmapDrawable = getResources (). GetDrawable (R.drawable. Ic_account_circle_black_18dp) .mutate ()

After the revision, we will see:

You see, everything will be fine by doing so.

Well, someone is about to ask, shit, are you not doing this to damage the picture memory optimization scheme that Google has done for us? in fact, this worry is superfluous, this http://android-developers.blogspot.hk/2009/05/drawable-mutations.html.

This address will tell you that we are only taking out the affected part of the memory separately, and the other things that are not affected are the shared data! In other words, what we will store in our memory are pure flag bits and things like status values.

Most of the memory is public!

And then, let's take a look at the next example about editext.

You see the color of this edittext is like this. Now let's modify the background color of this edittext.

Et1 = (EditText) this.findViewById (R.id.et); final Drawable originBitmapDrawable = et1.getBackground (); et1.setBackgroundDrawable (tintDrawable (originBitmapDrawable, ColorStateList.valueOf (Color.GREEN)

The background color has been modified successfully, but the color of this cursor has not changed very incongruously, and someone is going to say that we can use it:

This xml attribute to modify ah, of course, this method is indeed possible, but you think if you do so, you will have to add resource files, isn't it contrary to our tint?

So we have to find a way to break through this place. In fact, many people can think of a way, for the api that android does not provide to us, such as those private functions.

We usually call it through reflective methods. It's the same here. If we think about it for a moment, we can understand that in this place, we first get this cursorDrawable through reflection.

Then color him, and then call the method in the reflection to give him set to go in, right?

First of all, we all know that editext is actually textview, so let's take a look at the source code of textview to see what this attribute is called. After a lot of hard work, I found here:

/ / Although these fields are specific to editable text, they are not added to Editor because / / they are defined by the TextView's style and are theme-dependent. Int mCursorDrawableRes

And we need to take a look at the source code of editor, which is closely related to edittext:

/ * EditText specific data, created on demand when one of the Editor fields is used. * See {@ link # createEditorIfNeeded ()}. * / private Editor mEditor; / / Note this code belongs to editor final Drawable [] mCursorDrawable = new Drawable [2]

With this code, we will know how to write the rest of the reflection code.

/ / the parameter is to reflect the edittext object private void invokeEditTextCallCursorDrawable (EditText et) {try {Field fCursorDrawableRes = TextView.class.getDeclaredField ("mCursorDrawableRes") that modifies the cursor; / / look at the source code to know that this variable is not public, so set the accessible property fCursorDrawableRes.setAccessible (true). / / to get the value of the mCursorDrawableRes attribute in the editext object, look at the source code to know that this is an int value int mCursorDrawableRes = fCursorDrawableRes.getInt (et); / / the following code is to get the drawable Field fEditor = TextView.class.getDeclaredField ("mEditor") of our mCursorDrawable cursor by getting the mEditor object and then through the obtained mEditor object; fEditor.setAccessible (true) Object editor = fEditor.get (et); Class clazz = editor.getClass (); Field fCursorDrawable = clazz.getDeclaredField ("mCursorDrawable"); fCursorDrawable.setAccessible (true); if (mCursorDrawableRes)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report