盒子
盒子
文章目录
  1. ArgbEvaluator

探索Drawable

Drawable

Drawable的分类:

Drawable的分类

  • BitmapDrawable
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="utf-8"?>
    <bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="center"
    android:mipMap="true"
    android:src="@drawable/drawable_test"
    android:tileMode="clamp"/>

    antialias: 是否开启抗锯齿,若开启则会使图片更平滑,但图片清晰度会有所下降,建议开启

    dither:是否开启防抖动,当手机像素和屏幕像素不一致时,开启防抖动可以保持较好的显示效果,建议开启

    filter: 是否开启过滤,当图片被拉伸或者被压缩时,开启过滤会有较好的显示效果,建议开启

    mipMap:是否开启纹理映射,不常被用到,默认为false

    gravity:用于定位图片,具体属性可查看api文档:gravity

    tileMode: 平铺模式,包括disable,clamp,repeat,mirror四种,其中disable是正常平铺,repeat是重复平铺,mirror是特殊的重复平铺,新的一行会反向显示类似于镜子

  • ShapeDrawable
  • shape有五个形状,包括:rectangle(矩形), oval(圆形), line(横线), ring(圆环),其中line和ring要通过stroke标签来指定宽度和颜色。

    stroke

    常用属性为:width(宽度), color(颜色), dashWidth(虚线宽度,0则为实现), dashGap(虚线间隔)

    gradient

    与sodlid互相排斥,用于实现渐变效果

    type:渐变类别,有linear(线性),radius(径向),sweep(扫描)

    angle: 渐变角度,默认为0(表示从左到右,90表示从上到下),值必须是45的倍数,只有在type为linear(线性)才有效

    centX,centY:渐变中心点的横纵坐标,如:0.5表示在中间

    startColor,centerColor,endColor:渐变颜色

    gradientRadius:渐变半径,只有在type为radius(径向渐变)才有效

    userLevel:一般为false,当Drawable作为StateListDrawable使用时才为true

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8"?>
    <shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <gradient
    android:angle="90"
    android:startColor="@color/colorPrimary"
    android:centerColor="@color/colorAccent"
    android:endColor="@android:color/holo_red_dark"
    android:centerX="0.5"
    android:centerY="0.5"
    android:type="radial"
    android:gradientRadius="500"/>
    </shape>

    gradient效果展示

    solid

    color:指要填充的颜色

    pading

    包含的属性为:left, top, right, bottom

    size

    指shape的固有宽高,但当作为View的背景时仍然会被拉伸或缩小为View的大小,但getIntrinsicWidth和getIntrinsicHeight会得到这两个固定大小,若没有设置size则这两个方法会返回-1

    corner

    表示四个角的角度,适用于shap为rectangle时

    radius:为四个角设置相同的角度,优先级低,会被以下四个属性覆盖

    topLeftRadius: 设置左上角的角度

    topRightRadius: 设置右上角的角度

    bottomLeftRadius: 设置左下角的角度

    bottomRightRadius: 设置右下角的角度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="utf-8"?>
    <shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
    android:radius="50dp" />
    <solid
    android:color="@android:color/holo_red_dark"/>
    <stroke
    android:width="1dp"
    android:color="@android:color/black"/>

    </shape>

  • LayerDrawable
  • 将不同的Drawable防止在不同的层上面,产生一种叠加效果,eg:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
    <shape android:shape="rectangle">
    <solid android:color="@android:color/black"/>
    </shape>
    </item>
    <item android:bottom="6dp">
    <shape android:shape="rectangle">
    <solid android:color="@android:color/white"/>
    </shape>
    </item>
    <item
    android:bottom="1dp"
    android:left="1dp"
    android:right="1dp">
    <shape android:shape="rectangle">
    <solid android:color="#ffffff"/>
    </shape>
    </item>
    </layer-list>

    具体属性参见LayerDrawable的API文档

  • StateListDrawable
  • constantSize: 固有大小是否随着其状态的改变而改变,因为不同的drawable有不同的固有大小,true为随着改变而改变,默认为false

    variablePadding: StateListDrawable的padding是否随着状态的改变而改变,true为随着改变而改变,false表示StateListDrawable的padding的大小是内部Drawable的padding总和,默认为false,建议不开启

    其包含的item标签属性有:

    state_pressed: 按下状态

    state_focused: 获取焦点状态

    state_checked: 选择状态,常适用于CheckBox这类View

    state_enabled: 可用状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="true"
    android:variablePadding="false">
    <item android:state_selected="false">
    <shape>
    <solid android:color="@color/colorPrimary"/>
    </shape>
    </item>
    <item android:state_selected="true">
    <shape>
    <solid android:color="@color/colorAccent"/>
    </shape>
    </item>
    </selector>

  • LevelListDrawable
  • 通过设置level选择展示对应的Drawable

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="utf-8"?>
    <level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:maxLevel="2">
    <shape>
    <solid android:color="@color/colorAccent"/>
    </shape>
    </item>
    <item android:maxLevel="1">
    <shape>
    <solid android:color="@color/colorPrimary"/>
    </shape>
    </item>
    </level-list>

    minLevel,maxLevel分别指最小等级和最大等级,取值范围为0~10000,0为最小等级,同时也是默认值

    可通过Drawable的setLevel方法来设置等级大小,ImageView也可以通过setImageLevel来设置等级大小

  • TransitionDrawable
  • TransitionDrawable可实现渐变效果

    bitmap_test.xml和activity_main.xml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="utf-8"?>
    <transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/transition1"/>
    <item android:top="10dp" >
    <shape>
    <solid android:color="@android:color/holo_red_dark"/>
    </shape>
    </item>
    </transition>

    <TextView
    android:id="@+id/text_hello"
    android:background="@drawable/bitmap_test"/>

    MainActivity:

    1
    2
    3
    TextView textView=findViewById(R.id.text_hello);
    TransitionDrawable drawable=(TransitionDrawable) textView.getBackground();
    drawable.startTransition(3000);

    其中item标签的主要属性top,start等和之前的一样都是偏移量,需要注意的是不论添加多少个item有效的都只是前两个

  • InsetDrawable
  • 实现自身大小小于控件背景大小,通过layerDrawable也可以实现

    1
    2
    3
    4
    5
    6
    <inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="10dp"
    android:insetBottom="10dp"
    android:insetLeft="10dp"
    android:insetRight="10dp"
    android:drawable="@drawable/transition1"/>

  • ScaleDrawable
  • 根据设定的缩放等级实现按比例缩放

    1
    2
    3
    4
    5
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:scaleWidth="90%"
    android:scaleHeight="90%"
    android:scaleGravity="center"
    android:drawable="@drawable/drawable_test"/>

    需要在java代码中设置等级:

    1
    2
    3
    TextView textView=findViewById(R.id.text_hello);
    ScaleDrawable drawable=(ScaleDrawable)textView.getBackground();
    drawable.setLevel(5000);

    在ScaleDrawabel方法中的onBoundChange方法中有以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //MAX_LEVEL = 10000
    if (mState.mScaleWidth > 0) {
    final int iw = min ? d.getIntrinsicWidth() : 0;
    w -= (int) ((w - iw) * (MAX_LEVEL - level) * mState.mScaleWidth / MAX_LEVEL);
    }
    int h = bounds.height();
    if (mState.mScaleHeight > 0) {
    final int ih = min ? d.getIntrinsicHeight() : 0;
    h -= (int) ((h - ih) * (MAX_LEVEL - level) * mState.mScaleHeight / MAX_LEVEL);
    }

    由此可见level越大缩放程度就越低,而scaleWidth/scaleHeight越大则缩放程度越大,当level为10000即最大值时则不缩放

  • ClipDrawable
  • 实现对图片的裁剪,由level决定裁剪大小,以下为gravity的属性值:

    ClipDrawable的gravity属性值

    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="utf-8"?>
    <clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:gravity="bottom"
    android:drawable="@drawable/drawable_test"/>

    在java代码中设置level:

    1
    2
    3
    4
    TextView textView=findViewById(R.id.text_hello);
    ClipDrawable drawable=(ClipDrawable) textView.getBackground();
    Log.d(TAG,""+drawable.getIntrinsicWidth());
    drawable.setLevel(9000);

    其中level越小裁剪范围越大,内部规定等级范围为0~10000

    ArgbEvaluator

    用于计算颜色渐变值的类,使颜色更换不会太突兀

    1
    2
    3
    4
    ArgbEvaluator argbEvaluator=new ArgbEvaluator();
    int startColor=getColor(context,R.color.start);
    int endColor=getColor(context,R.color.circle);
    int colors=(int)argbEvaluator.evaluate(0.5f,startColor,endColor);

    第一个参数取0-1f即可

    支持一下
    扫一扫,支持Grooter
    • 微信扫一扫
    • 支付宝扫一扫