The article directories

  • StateListDrawable
  • GradientDrawable
  • LayerDrawable
  • Tint that can dynamically change the color of pictures
  • Property button 3 state demo
  • getCompoundDrawables()
  • GetIntrinsicWidth () gets the width and height of the drawable image (device-dependent)

StateListDrawable

StateListDrawable is a subclass of Drawable. This class defines the image resources corresponding to different state values. We can use this class to save multiple state values, multiple image resources

For example, a button can be set to have a different background when clicked and released



XML implementation:

1. Create selector. XML under drawable


      
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/heart0" android:state_pressed="false"/>
    <item android:drawable="@mipmap/heart1" android:state_pressed="true"/>
</selector>
Copy the code

2. Use in layout

	<Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/selector"
        android:text="button"
        android:textColor="@android:color/white"/>
Copy the code

Code implementation: So selector. XML will be parsed into a StateListDrawable object, and what we’re going to do is we’re going to manually write a StateListDrawable in code, and do the same thing with XML that defines drawable, Why use code when you can do it in XML? There is a requirement in the project, the project has the main color system, this color value is specified in the background, so we will use code to dynamically implement this effect

The key code

 button.setBackground(initStateListDrawable());
 private StateListDrawable initStateListDrawable(a){
        // Initialize an empty object
        StateListDrawable stalistDrawable = new StateListDrawable();
        // Get the corresponding attribute value Android framework built-in attribute attr
        int pressed = android.R.attr.state_pressed;

        stalistDrawable.addState(new int []{-pressed}, getResources().getDrawable(R.mipmap.heart0));
        stalistDrawable.addState(new int []{pressed}, getResources().getDrawable(R.mipmap.heart1));

        // The image is displayed when there is no state, we set it to empty collection
        stalistDrawable.addState(new int []{}, getResources().getDrawable(R.mipmap.heart0));
        return stalistDrawable;
    }
Copy the code

Remove background from the layout

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button"
        android:textColor="@android:color/white"/>
Copy the code

The effect is the same as the one above

Where the “-” minus sign in the code indicates that the corresponding attribute value is false

GradientDrawable

Use of advantage

  1. Quick implementation of some basic shapes (lines, rectangles, circles, ellipses, rings)
  2. Quickly implement rounded corners, gradients, shadows, etc
  3. Instead of setting the image as the background of the View
  4. It can reduce the SIZE of APK and increase the willingness of users to download
  5. You can also reduce your memory footprint
  6. Easy to modify and maintain

Results 1



Create shape.xml under Drawable


      
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="270"
        android:endColor="#DB7093"
        android:startColor="#FFB6C1" />
    <padding
        android:left="20dp"
        android:top="10dp"
        android:right="20dp"
        android:bottom="50dp" />
    <corners android:radius="5dp" />
</shape>
Copy the code

Use in layout

<EditText
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Code party late into the night."
        android:textColor="@android:color/white"
        android:background="@drawable/shape"/>
Copy the code

Results 2


      
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#6495ED" />
    <stroke
        android:width="2dp"
        android:color="#0000ff"
        android:dashWidth="1dp"
        android:dashGap="3dp" />
    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />
    <corners android:radius="5dp" />
</shape>
Copy the code

XML definition description given in official documentation

<? The XML version = "1.0" encoding = "utf-8"? > <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>Copy the code

I’ll give you the perfect explanation

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] >... </shape>Copy the code


Shape shape, default is rectangle. Rectangle, oval, line, ring

When Android: Shape =”ring”, shape has the following properties available:

  • Android: innerRadius size. The radius of the inner ring. A dimension value (DIP, etc.) or a dimension resource
  • Android: The innerRadiusRatio Float type. This value represents the ratio of the inner ring, for example, if Android :innerRadiusRatio = “5 “, then the radius of the inner ring is equal to the width of the ring divided by 5. This value is overridden by Android :innerRadius. The default value is 9
  • Android: thickness size. Ring thickness is a size value or size resource
  • Android :thicknessRatio Float type. Ratio of thickness. For example, if Android :thicknessRatio= “2”, then the thickness equals the width of the ring divided by 2. This value is overridden by Android :innerRadius, and the default is 3
  • Android :useLevel Boolean Type. True if used in LevelListDrawable. False if it does not normally occur
< corners android: the radius = "integer" / / Dimension. The radius of the rounded corner. Android :topRightRadius=" INTEGER "Android :topLeftRadius=" INTEGER" Android :bottomLeftRadius=" INTEGER" android:bottomRightRadius="integer" />Copy the code


represents the four corners of a rectangle, which can only be used when Android: Shape = “Rectangle”

<gradient Android: Angle ="integer"// integer Gradient Angle. 0 is from left to right. 90 is for bottom to top. It must be a multiple of 45. The default value is 0. Android :centerX="integer"//Float The relative X-coordinate of the center of the gradient, between 0 and 1.0. Android :centerY="integer"//Float The relative Y coordinate of the center of the gradient, between 0 and 1.0. Android :centerColor="integer"//Color Optional Color value. Android :gradientRadius=" INTEGER "//Float Radius of the gradient Only available on Android: Type ="radial". Android :startColor="color"// color startColor value. Android: type = "linear" | "radial" | "sweep"] / / the gradient pattern. Android: useLevel = [" true "|" false "] / > / / gradient mode. If you want to use the LevelListDrawable object, set it to true. Set to true with no gradient. False has gradientCopy the code

Android: Type indicates the mode of gradient. Optional parameters include:

  • Linear gradient. This is also the default mode
  • Radial gradient. StartColor is the color of the radiation center
  • The sweep line changes gradually
< padding android: left = "integer" / / Dimension. Android :top="integer" Android :right="integer" Android :bottom="integer" />Copy the code

indicates the distance between the content and the view boundary

The < size android: width = "integer" / / Dimension. Shape height. Android: height = "integer" / > / / Dimension. Width of shape.Copy the code


represents the size of the Shape

< solid android: color = "color" / > / / color. A Color value, hexadecimal number, or a Color resourceCopy the code


represents the filling color of shape, which is the same as the gradient function of

except that it is filled with a solid color here. Therefore, in general, only one

and

should be used



< stroke android: width = "integer" / / Dimension. The thickness of strokes. Android: color = "color" / / color. Stroke color. Android: dashWidth = "integer" / / Dimension. The length of each line. This works only if Android :dashGap is also set. The style that represents the stroke is the width of the dotted line, and a value of 0 represents a solid line. Android :dashGap=" INTEGER "/>//Dimension. How far apart each line is drawn. This works only if Android :dashWidth is also set. When the stroke is dotted, the interval between dotted lines is - - - -.Copy the code


is used to represent shape’s border brush. This element must be set when Android: Shape =”line”

Practice a

Implement a custom numeric input keyboard with GradientDrawable. The circular numeric input button mimics the iPhone lock screen program. Under normal condition, it is a border, transparent ring in the middle, when pressed, the middle is filled with color

Create a normal keyboard style number_BUTTon_normal.xml


      
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@android:color/transparent" />
    <stroke
        android:width="1dp"
        android:color="#df1ea353" />
</shape>
Copy the code

Create the keyboard style number_BUTTon_pressed. XML when pressed


      
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#1ea353" />
    <stroke
        android:width="1dp"
        android:color="#df1ea353" />
</shape>
Copy the code

So we have both the normal state and the pressed state, and we’re going to combine those two states by creating a selector, number_button_selector. XML


      
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/number_button_pressed" android:state_pressed="true" />
    <item android:drawable="@drawable/number_button_normal" />
</selector>
Copy the code

Button layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_gravity="center_horizontal"
    android:gravity="center">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp">
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_1"
            android:text="1"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_2"
            android:text="2"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_3"
            android:text="3"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_4"
            android:text="4"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_5"
            android:text="5"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_6"
            android:text="6"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_7"
            android:text="Seven"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_8"
            android:text="8"/>
        <Button
            style="@style/number_button"
            android:id="@+id/nkb_9"
            android:text="9"/>
    </LinearLayout>
    <Button
        style="@style/number_button"
        android:id="@+id/nkb_0"
        android:text="0"/>
</LinearLayout>
Copy the code

Because there are 10 buttons, each of which has the same style, create a style for the button, using style=”@style/number_button” directly where you want to apply it. In the styles. In the XML

<style name="wrap_wrap"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> </style> <style name="number_button" parent="wrap_wrap"> <item name="android:background">@drawable/number_button_selector</item> <item name="android:textColor">#333333</item> <item name="android:textSize">30sp</item> <item name="android:minHeight">60dp</item> <item name="android:minWidth">60dp</item>  <item name="android:layout_marginLeft">8dp</item> <item name="android:layout_marginRight">8dp</item> <item name="android:layout_marginBottom">8dp</item> </style>Copy the code

rendering

Create GradientDrawable dynamically and use it

XML defined with shape tags is ultimately converted to GradientDrawable objects, not ShapeDrawable, not OvalShape, RoundRectShape, etc

Let’s switch to code to achieve the same effect as above, using a button as an example

<Button
        android:id="@+id/number_button"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:text="1"
        android:textColor="# 333"
        android:textSize="30sp"/>
Copy the code

The key code

if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
 {
    btn.setBackground(initStateListDrawable());
}else{
	btn.setBackgroundDrawable(initStateListDrawable());
}

private StateListDrawable initStateListDrawable(a){
        / / create the drawable
        GradientDrawable normalGb = new GradientDrawable();
        // Set the type
        normalGb.setShape(GradientDrawable.OVAL);
        // Fill the inner color
        normalGb.setColor(Color.TRANSPARENT);
        // Border parameters are I: border width, border color
        normalGb.setStroke(1,Color.parseColor("#df1ea353"));

        GradientDrawable pressedGb = new GradientDrawable();
        pressedGb.setShape(GradientDrawable.OVAL);
        pressedGb.setColor(Color.parseColor("#1ea353"));
        pressedGb.setStroke(1,Color.parseColor("#df1ea353"));

        StateListDrawable stalistDrawable = new StateListDrawable();
        int pressed = android.R.attr.state_pressed;
        stalistDrawable.addState(new int []{-pressed}, normalGb);
        stalistDrawable.addState(new int []{pressed}, pressedGb);
        stalistDrawable.addState(new int []{}, normalGb);
        return stalistDrawable;
    }
Copy the code

The effect



In addition, another method that is commonly used is

setCornerRadius(int px)
Copy the code

Used to set rounded corners, passed px, need to use the method to convert dp

GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GradientDrawable Android GRADIENT Shape Reduce memory good helper)

LayerDrawable

The root element of the XML corresponding to LayerDrawable is

, which represents a hierarchically displayed collection of Drawable. Different drawables are placed on different layers to achieve a superimposed effect

Official website of grammar

<? The XML version = "1.0" encoding = "utf-8"? > <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item Android :drawable="@[package:]drawable/drawable_resource"// We can reference an existing drawable resource directly by using the drawable attribute Android :id="@[+][package:]id/resource_name"//id Resource name Android :top="dimension" android:top=" bottom ",left,right,top Android :right="dimension" Android :bottom="dimension" Android :left="dimension" /> </layer-list>Copy the code

A layer-list can contain multiple items, and each item represents a Drawable. 2. Layer-list has a concept of hierarchy, in which the lower item overwrites the upper item. 4. By default, all the drawables in the layer-list are set to the size of the View. For bitmaps, the layer-list is set to the size of the View. You need to use Gravity to control how the image looks.

Effect of a



Create a layer_list.xml


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <! - solid - >
            <solid android:color="@android:color/black" />
        </shape>
    </item>
    <! -- Analog background padding size 6dp-->
    <item
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp">
        <! -- Original requirement area -->
        <shape>
            <! - solid - >
            <solid android:color="@android:color/holo_red_dark" />
            <! - frame - >
            <stroke
                android:width="2dp"
                android:color="@android:color/holo_green_dark" />
            <! - the rounded - >
            <corners android:radius="2dp" />
        </shape>
    </item>

</layer-list>
Copy the code

Use in code

<TextView
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:text="Text"
        android:textColor="@android:color/white"
        android:gravity="center"
        android:background="@drawable/layer_list"/>
Copy the code

Effects of two


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <bitmap
            android:gravity="left"
            android:src="@mipmap/heart0" />
    </item>
    <item
        android:left="10dp"
        android:top="10dp">
        <bitmap
            android:gravity="left"
            android:src="@mipmap/heart0" />
    </item>
    <item
        android:left="20dp"
        android:top="20dp">
        <bitmap
            android:gravity="left"
            android:src="@mipmap/heart0" />
    </item>
</layer-list>
Copy the code
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/layer_list" />
Copy the code

The effect of three


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/heart0" />
    <item
        android:drawable="@mipmap/heart0"
        android:left="10dp"
        android:top="10dp" />
    <item
        android:drawable="@mipmap/heart0"
        android:left="20dp"
        android:top="20dp" />
</layer-list>
Copy the code

rotating



Create a layer_list.xml


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <! -- Bottom image, rotate around the x and y coordinates, negative numbers rotate counterclockwise -->
        <rotate
            android:fromDegrees="To 10"
            android:pivotX="0"
            android:pivotY="0"
            android:toDegrees="To 10">
            <bitmap android:src="@mipmap/heart0" />
        </rotate>
    </item>

    <item>
        <rotate
            android:fromDegrees="10"
            android:pivotX="0"
            android:pivotY="0"
            android:toDegrees="10">
            <bitmap android:src="@mipmap/heart1" />
        </rotate>
    </item>

    <item>
        <rotate
            android:fromDegrees="35"
            android:pivotX="0"
            android:pivotY="0"
            android:toDegrees="55">
            <bitmap android:src="@mipmap/heart2" />
        </rotate>
    </item>
</layer-list>
Copy the code

Input field effect



Create a layer_list.xml


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <! -- Foreground layer -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#0ac39e" />
        </shape>
    </item>
    <! Second layer, the current drawable is a pure white, 6dp spacing relative to the bottom of the view. -->
    <item android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>
    </item>
    <! -- Layer 3, drawable is a pure white, relative to view, left and right 1dp outer spacing. -->
    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff" />
        </shape>
    </item>

</layer-list>
Copy the code

Use in layout

<EditText android:layout_width="match_parent" android:layout_height="50dp" android:background="@drawable/layer_list" Android :paddingLeft="5dp" Android :paddingRight="5dp" Android :text=" textBox "/>Copy the code

Button in the shadow

Create layer_list. XML


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <! -- item foreground layer -->
    <item
        android:left="2dp"
        android:top="2dp">
        <shape>
            <gradient
                android:angle="45"
                android:endColor="#F5F5F5"
                android:startColor="#D3D3D3"
                android:type="linear" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <! -- item preview layer -->
    <! This layer of items overlays the previous layer of items, resulting in a superposition effect. -->
    <item
        android:bottom="2dp"
        android:right="2dp">
        <shape>
            <stroke
                android:width="1dp"
                android:color="#F5F5F5"/>
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>
</layer-list>
Copy the code

Use in code

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/layer_list"
        android:text="Code party late into the night."
        android:padding="5dp"/>
Copy the code

The search box


      
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="50dip" />
            <solid android:color="@android:color/white" />
        </shape>
    </item>
    <item
        android:drawable="@mipmap/ic_search"
        android:gravity="left"
        android:left="10dp"
        android:top="5dp"
        android:right="10dp"
        android:bottom="5dp"
        />
</layer-list>
Copy the code

      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:orientation="vertical">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="48dip"
        android:layout_marginLeft="10dip"
        android:layout_marginTop="8dip"
        android:layout_marginRight="10dip"
        android:layout_marginBottom="8dip"
        android:background="@drawable/layer_list2"
        android:hint="Search"
        android:paddingLeft="55dp" />
</LinearLayout>
Copy the code

Code to achieve the last search effect learned so much, practice, with code to achieve the last search effect

public class MainActivity extends AppCompatActivity {
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.et);

        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.WHITE);
        gd.setCornerRadius(dpToPx(50));

        Drawable[] layers = {gd, getResources().getDrawable(R.mipmap.ic_search)};
        LayerDrawable layerDrawable = new LayerDrawable(layers);
        layerDrawable.setLayerGravity(1, Gravity.LEFT);
        layerDrawable.setLayerInset(1, dpToPx(10), dpToPx(5), dpToPx(10), dpToPx(5));

        editText.setBackground(layerDrawable);
    }

    public int dpToPx(float dpValue) {
        if (dpValue <= 0) {
            return 0;
        }
        final float scale = this.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5 f); }}Copy the code

Layout file


      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#DCDCDC"
    android:orientation="vertical">

     <EditText
         android:id="@+id/et"
         android:layout_width="match_parent"
         android:layout_height="48dip"
         android:layout_marginLeft="10dip"
         android:layout_marginTop="8dip"
         android:layout_marginRight="10dip"
         android:layout_marginBottom="8dip"
         android:hint="Search"
         android:paddingLeft="55dp" />
    
</LinearLayout>
Copy the code

When creating a LayerDrawable object, you pass in a Drawable array, which means that you place all layers in the Drawable array and provide a set of methods for manipulating the Drawable, using id or index:

public int addLayer(Drawable dr)
public Drawable findDrawableByLayerId(int id)
public void setId(int index, int id)
public int getId(int index)
public int getNumberOfLayers(a)
public boolean setDrawableByLayerId(int id, Drawable drawable)
public int findIndexByLayerId(int id) 
public void setDrawable(int index, Drawable drawable)
public Drawable getDrawable(int index) 
public void setLayerSize(int index, int w, int h)
public void setLayerWidth(int index, int w) 
public void setLayerHeight(int index, int h) 
public void setLayerGravity(int index, int gravity)
public void setLayerInset(int index, int l, int t, int r, int b) 
public void setLayerInsetRelative(int index, int s, int t, int e, int b)
public void setLayerInsetLeft(int index, int l)
public void setLayerInsetRight(int index, int r)
public void setLayerInsetTop(int index, int t)
public void setLayerInsetBottom(int index, int b)
public void setLayerInsetStart(int index, int s)
public void setLayerInsetEnd(int index, int e)
public void setPaddingMode(int mode)
public void setPadding(int left, int top, int right, int bottom)
Copy the code

The setLayerInset() function shifts a layer (counting from 0) inward from the previous layer. Of course, if the number passed in is negative, it is offset outwards, but then the upper layer overshadowing the lower layer, losing the meaning of using layer

It’s worth noting that all of the int values here are in px units and need to be converted to px units when passed in, so I call a dpToPx() method

Tint that can dynamically change the color of pictures

Tint can help us realize various color changes in a single image, that is to say, it is very easy to change the color of an icon, and also reduce the volume of our APK (we need multiple pictures originally, but now maybe only one is enough).

Tint effect:

XML implementation:

    <ImageView
        android:id="@+id/enable_cart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/btn_cart_list"/>

    <ImageView
        android:id="@+id/disable_cart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/btn_cart_list"
        android:tint="#cccccc"/>
Copy the code

Code implementation:

        ImageView imageView = findViewById(R.id.enable_cart);
        ImageView imageView1 = findViewById(R.id.disable_cart);

        Drawable drawable = ContextCompat.getDrawable(this,R.mipmap.btn_cart_list);
        imageView.setImageDrawable(drawable);

        Drawable.ConstantState state = drawable.getConstantState();
        Drawable drawable1 = DrawableCompat.wrap(state == null ? drawable : state.newDrawable()).mutate();
        drawable1.setBounds(0.0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        DrawableCompat.setTint(drawable1,ContextCompat.getColor(this,R.color.gray));

        imageView1.setImageDrawable(drawable1);
Copy the code

DrawableCompat: The DrawableCompat backward compatible class, which we used for tint compatibility in 6.0, is a very simple compatibility class

Wrap method: To use TINt, you must call this method to wrap Drawable once

Mutate method: If this method is not called, the drawable is the same as the drawable after coloring. All two ImageViews will display the drawable after coloring

Using the selector

XML code

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/image"
        android:clickable="true" />
Copy the code

Java code

ImageView imageView = (ImageView) findViewById(R.id.image);
        Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.btn_cart_list);
        int[] colors = new int[]{ContextCompat.getColor(this, R.color.gray), ContextCompat
                .getColor(this, R.color.colorAccent)};
        int[][] states = new int[2] []; states[0] = new int[]{android.R.attr.state_pressed};
        states[1] = new int[] {}; ColorStateList colorList =new ColorStateList(states, colors);
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(states[0], drawable);// Pay attention to the order
        stateListDrawable.addState(states[1], drawable);
        Drawable.ConstantState state = stateListDrawable.getConstantState();
        drawable = DrawableCompat.wrap(state == null ? stateListDrawable : state.newDrawable())
                .mutate();
        DrawableCompat.setTintList(drawable, colorList);
        imageView.setImageDrawable(drawable);
Copy the code

Android View(View) draw different state background picture principle in-depth analysis and StateListDrawable usage details

Property button 3 state demo



Properties checkboxes generally have three states: unselected, selected, and unavailable

This can be done using RadioButton, with the enabled attribute indicating availability and checked indicating availability

TextColor and background can set the textColor and button background color for each of the three states

Source code portal

getCompoundDrawables()

Drawable[] (Left, Top, Right, and Bottom); Drawable[] (Left, Top, Right, and Bottom)

For example, add images in EditText

<EditText
     android:id="@+id/et"
     android:layout_width="match_parent"
     android:layout_height="40dp"
     android:background="@color/white"
     android:padding="5dp"
     android:layout_margin="5dp"
     android:drawableRight="@mipmap/ic_search"/>
Copy the code
Drawable[] drawables = et.getCompoundDrawables();
        for (int i = 0; i < drawables.length; i++) {
            Drawable drawable = drawables[i];
            if(drawable ! =null) {
                Log.d("TTT"."The first" + i + "Width =" + drawable.getBounds().width() +
                        ",height=" + drawable.getBounds().height());
            } else {
                Log.d("TTT"."There is no picture in this location."); }}Copy the code

Width =73,height=73 there is no image in this position

GetIntrinsicWidth () gets the width and height of the drawable image (device-dependent)

Not for the

More: Android Image Drawable