Android開發(fā)藝術(shù)探索(5) --- Drawable

Drawable表示的是一種可以在Canvas上進(jìn)行繪制的抽象概念,它的種類有很多,最常見的顏色和圖片都可以是一個Drawable

1. Drawable簡介

使用方式:

  1. 定義xml,然后通過@Drawable引入布局
  2. Java代碼:new一個所需Drawable并set相關(guān)屬性,最后加載到布局中。
  • 使用getIntrinsicWidth ,getIntrinsicHeight兩個方法能獲得Drawable的寬高
  • 但是并不是每一個Drawable都有內(nèi)部的寬高(eg:顏色)

2. Drawable分類

2.1 BitmapDrawable

  • 最簡單的Drawable,表示一張圖片
  • XML描述
<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@[package:]drawable/drawable_resource"
    android:antialias="[true | false]"
    android:dither="[true | false]"
    android:filter="[true | false]"
    android:gravity="[top | bottom | left | right |
     center_vertical | fill_vertical | center_horizontal |
      fill_horizontal | center | fill |
       clip_vertical | clip_horizontal]"
    android:mipMap="[true | false]"
    android:tileMode="[disabled | clamp | repeat | mirror]" />
  • 對應(yīng)<bitmap>標(biāo)簽
  • 基本使用

Drawable/bitmap.xml

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="top"
    android:tileMode="mirror"
    android:src="@drawable/enactus"/>

layout/activity_main.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/bitmap"/>
bitmap Demo

2.2 ShapeDrawable

  • 一種常見的Drawable,可以理解為通過顏色來構(gòu)造圖形,既可以是純色的圖形也可以是具有漸變效果的圖形
  • shape標(biāo)簽創(chuàng)建的Drawable,但實(shí)體類型是GradientDrawable
<?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:topLeftRaidus="integer"
        android:topRightRaidus="integer"
        android:bottomLeftRaidus="integer"
        android:bottomRightRaidus="integer" />
    <gradient
        android:angle="integer"
        android:centerX="integer"
        android:centerY="integer"
        android:centerColor="color"
        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>
  • 基本使用
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:type="radial" android:centerColor="@color/colorPrimaryDark"
        android:startColor="@color/colorPrimary"
        android:angle="45" android:centerY="0" android:centerX="0" android:endColor="@color/colorAccent" android:gradientRadius="200dp"/>
    <stroke android:width="2dp" android:color="#00FF00"
        android:dashGap="5dp" android:dashWidth="5dp"/>
</shape>
ShapeDrawable

2.3 LayerDrawable

  • 對應(yīng)的XML標(biāo)簽是<layer-list>,它表示一種層次化的Drawable集合
  • 一個layer-list可包含多個item,每個item表示一個Drawable??稍?code>android:drawable中引用一個現(xiàn)有的Drawable資源,也可在<item>中自定義Drawable。
  • 默認(rèn)情況下,layer-list中的所有Drawable都會被縮放至View的大小。可設(shè)置Drawable相對于View的上下左右偏移量。另外對于bitmap,需要使用其android:gravity來控制圖片的顯示效果。
  • layer-list有層次的概念,下面的item會覆蓋上面的item。通過合理的分層,可實(shí)現(xiàn)一些特殊的疊加效果。
  • 基本使用
<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:drawable="@drawable/shape"
    android:id="@+id/layer_drawable"
    android:top="10dp"
    android:right="10dp"
    android:left="10dp"
    android:bottom="10dp"/>
</layer-list>
LayerDrawable
  • 基本使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:id="@+id/remoteViews_content"
    android:orientation="vertical">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@drawable/layer_drwable"/>
</LinearLayout>
<?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="#0ac39e"/>
    </shape>
</item>

    <item android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff"/>
        </shape>
    </item>

    <item
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff"/>
        </shape>
    </item>
</layer-list>
LayerDrawable

2.4 StateListDrawable

  • 對應(yīng)于<selector>標(biāo)簽,它也表示Drawable集合
  • 每個Drawable都對應(yīng)著一個View的狀態(tài),這樣系統(tǒng)就會根據(jù)View的狀態(tài)來選擇合適的Drawable
  • 主要用于設(shè)置可單機(jī)的View的背景,最常見的是Button
  • 系統(tǒng)根據(jù)View的當(dāng)前狀態(tài)從selector中選擇對應(yīng)的item,每個item對應(yīng)著一個具體的Drawable,系統(tǒng)自下而上查找,直至匹配到第一條item,如果沒有找到,就會選擇默認(rèn)的item,因?yàn)槟J(rèn)的item不附帶狀態(tài),所以它可以匹配任何View的任何狀態(tài)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="[true | false]"
    android:dither="[true | false]"
    android:variablePadding="[true | false]">
    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:state_pressed="[true | false]"
        android:state_focused="[true | false]"
        android:state_hovered="[true | false]"
        android:state_selected="[true | false]"
        android:state_checkable="[true | false]"
        android:state_checked="[true | false]"
        android:state_enabled="[true | false]"
        android:state_activated="[true | false]"
        android:state_window_focused="[true | false]" />
    <!-- 其他item -->
</selector>

基本使用

StateListDrawable stateListDrawable = (StateListDrawable) getResources().getDrawable(R.drawable.state_list_drawable);
Button button = findViewById(R.id.btn);
button.setBackgroundDrawable(stateListDrawable);
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape" android:state_pressed="true"/>
</selector>
StateListDrawable

2.5 LevelListDrawable

  • 對應(yīng)于<level-list>,它同樣表示一個Drawable集合,集合中的每個Drawable都有一個等級的概念
  • 根據(jù)不同的等級,LevelListDrawable會切換成對應(yīng)的Drawable
  • 若作為View背景時,可通過DrawablesetLevel()來設(shè)置不同的等級來切換具體的Drawable。
  • 若作為ImageView的前景,可通過ImageViewsetImageLevel()來切換。

基本使用

final LevelListDrawable levelListDrawable = (LevelListDrawable) getResources().getDrawable(R.drawable.level_list_drawable);
        Button button = findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                levelListDrawable.setLevel(1);
            }
        });
        button.setBackgroundDrawable(levelListDrawable);
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/shape"
        android:maxLevel="1"
        android:minLevel="1"/>
    <item
        android:drawable="@drawable/layer_drwable"
        android:maxLevel="0"/>
</level-list>
LevelListDrawable

2.6 TransitionDrawable

  • 對應(yīng)于<transition>標(biāo)簽,用于實(shí)現(xiàn)兩個Drawable之間的淡入淡出效果

基本使用

TextView textView = findViewById(R.id.text);
TransitionDrawable transitionDrawable = (TransitionDrawable)textView.getBackground();
transitionDrawable.startTransition(1000);
<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:background="@drawable/transition_drawable"/>
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/shape"/>

    <item android:drawable="@color/colorPrimaryDark"/>
</transition>
TransitionDrawable

2.7 InsetDrawable

  • 對應(yīng)于<inset>標(biāo)簽,它可以將其他Drawable內(nèi)嵌到自己當(dāng)中,并可以在四周留出一定的間距
  • 使用場景:View希望自己的北京比自己的實(shí)際區(qū)域小
    基本使用
<?xml version="1.0" encoding="utf-8"?>
<inset 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@[package:]drawable/drawable_resource"
    android:inset="dimension"
    android:insetTop="dimension"
    android:insetRight="dimension"
    android:insetBottom="dimension"
    android:insetLeft="dimension" />
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="15dp"
    android:insetLeft="15dp"
    android:insetRight="15dp"
    android:insetTop="15dp">

    <shape>
        <solid android:color="@color/colorPrimaryDark"/>
    </shape>
<!--內(nèi)嵌到InsetView中-->
</inset>
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/inset_drawable"
        />
InsetView

2.8 ScaleDrawable

  • 對應(yīng)于<scale>標(biāo)簽,可以根據(jù)自己的等級將指定的Drawable縮放到一定的比例
  • 等級0表示ScaleDrawable不可見,為默認(rèn)值
<?xml version="1.0" encoding="utf-8"?>
<scale 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@[package:]drawable/drawable_resource"
    android:scaleGravity="[top | bottom | left | right |
        center_vertical | center_horizontal | center |
        fill_vertical | fill_horizontal | fill |
        clip_vertical | clip_horizontal]"
    android:scaleWidth="percentage"
    android:scaleHeight="percentage" />

基本使用

ImageView imageView = findViewById(R.id.imageView);
ScaleDrawable scaleDrawable = (ScaleDrawable) imageView.getBackground();
scaleDrawable.setLevel(1);
   <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/scale_drawable"
        />
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:scaleHeight="70%"
    android:scaleWidth="70%"
    android:scaleGravity="center"
    android:drawable="@drawable/enactus">
</scale>
ScaleDrawable

2.9 ClipDrawable

  • 對應(yīng)于<clip>標(biāo)簽,它可以根據(jù)自己當(dāng)前的等級來裁剪另一個Drawable
  • 通過android:clipOrientationandroid:gravity兩個屬性來控制裁剪
<?xml version="1.0" encoding="utf-8"?>
<clip 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@[package:]drawable/drawable_resource"
    android:clipOrientation="[vertical | horizontal]"
    android:gravity="[top | bottom | left | right |
        center_vertical | center_horizontal | center |
        fill_vertical | fill_horizontal | fill |
        clip_vertical | clip_horizontal]" />

基本使用

ImageView imageView = findViewById(R.id.imageView);
ClipDrawable clipDrawable = (ClipDrawable) imageView.getDrawable();
clipDrawable.setLevel(5000);
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/clip_drawable"
        />
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/enactus"
    android:gravity="bottom">

</clip>
clipDrawable

參考資料:
Android中常用的Drawable

3. 自定義Drawable

  • Drawable的使用范圍:一是作為ImageView中的圖箱來顯示,另外一個就是作為View的背景
  • 核心是Draw方法,可以通過重寫Drawable的Draw方法來自定義Drawable
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 日更220 此刻其實(shí)有點(diǎn)犯困,因?yàn)樽蛲戆疽怪?點(diǎn)才睡覺,不過今日活動還算圓滿。今天晚上爸媽來,于是回家陪他們吃飯。...
    暖心的自由書寫閱讀 224評論 0 1
  • 一、五險(xiǎn)二金指的是什么? 五險(xiǎn):養(yǎng)老保險(xiǎn)、醫(yī)療保險(xiǎn)、失業(yè)保險(xiǎn)、工傷保險(xiǎn)、生育保險(xiǎn),另外還有大病保險(xiǎn); 二金:住房公...
    紅塵佛心閱讀 16,784評論 2 3
  • 相看兩不厭 網(wǎng)上有段子說:教書是一場盛大的暗戀,你費(fèi)盡心思去愛一群人,結(jié)果只感動了自己;學(xué)生虐你千萬遍,你待學(xué)生如...
    籬下絮語閱讀 83評論 0 1
  • 當(dāng)抓取到的圖片Url后,如果一張一張的把圖片都緩存到本地會占用大量的空間,而且沒有什么太大的作用,還是把數(shù)據(jù)存到數(shù)...
    太二道士閱讀 2,967評論 0 2

友情鏈接更多精彩內(nèi)容