android佈局XML屬效能力增強(圓角、虛線、邊框等)

2020-09-22 15:01:51

概述

          android開發中,我們常常使用xml來寫佈局檔案,這種實現方式不僅簡單,而且表達能力更強。但是google提供的佈局屬性有限,有些功能的實現我們不得不使用程式碼,或者自定義控制元件的方式來實現。那有沒有一種方法,可以將屬性增強來實現額外的功能呢?例如我們常常使用background 來表示和設定背景,那是不是可以使用layout_radius來表示和設定圓角呢?

 

使用範例

  需要在專案build.gradle中參照依賴

 implementation 'com.zhangzheng.superxml:library:1.1.0'

 另外在Application註冊一行程式碼

  SuperXml.init(this)

  OVER

 

能力說明

 

屬性增強

   圓角:         

   <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:background="#FF0000"
        app:layout_radius="40dp" />

  說明

       app:layout_radius 支援將控制元件背景設定為圓角,背景支援純色背景或者圖片,另外對於ImageView 的src如果想設定成圓角需要使用app:layout_src_radius,例如 

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:src="@mipmap/order_ic_shipper_default"
    app:layout_src_radius="10dp" />

 

   複合屬性

       

  <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="asdasdasdasd"
        app:layout_textColor_pressedFalse="#00FF00"
        app:layout_textColor_pressedTrue="#FF0000" />

   說明

        一般情況下,我們要表示點選和普通狀態下不同的字型顏色,或者背景會使用selector來定義一個檔案,然後在佈局檔案中參照,一方面這樣的使用很麻煩,另外一方面可讀性也會降低(使用者需要進入selector檔案進行分析,才知道程式碼錶達意圖)。這邊封裝了常用的複用屬性,如下:

屬性屬性型別說明
layout_background_enableTrue
layout_background_enableFalse
reference|color(資源或者顏色)
背景(是否可用)
layout_background_pressedTrue
layout_background_pressedFalse
reference|color(資源或者顏色)背景(是否按壓)
layout_background_selectedTrue
layout_background_selectedTrue
reference|color(資源或者顏色)背景(是否選擇)
layout_textColor_enableTrue
layout_textColor_enableFalse
reference|color(資源或者顏色)字型顏色(是否可用)
layout_textColor_pressedTrue
layout_textColor_pressedFalse

 

reference|color(資源或者顏色)字型顏色(是否按壓)
layout_textColor_selectedTrue
layout_textColor_selectedFalse
reference|color(資源或者顏色)字型顏色(是否選擇)
   

 

邊框   

 <View
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="20dp"
        android:background="#FF0000"
        app:layout_border_color="#0000FF"
        app:layout_border_width="1dp"
        app:layout_radius="40dp" />

 

說明

      比較簡單,layout_border_color表示邊框顏色,layout_border_width表示邊框粗細,和radius一起使用表示邊框圓角。

 

 

虛線

 <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="20dp"
        android:background="#FF0000"
        app:layout_dash_gap="10dp"
        app:layout_dash_height="1dp"
        app:layout_dash_width="5dp" />

 

說明

     可以在任何檢視上使用(建議在View中定義),必須同時定義grap、dash_height、dash_width。支援橫虛線,和豎虛線,這裡會檢測檢視寬高來確定。屬性說明:dash_grap(虛線間距)、dash_width(單個小線的寬)、dash_height(單個小線的高)

 

 

檢視替換或增強

          這個能力可能會將佈局檔案中的檢視替換成其他控制元件、或者對其進行增強。

 

捲動檢視

      為了適配小屏手機,我們可能會在每一個佈局檔案中加上一層ScrollView,現在對容器控制元件進行能力增強。

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:gravity="center"
        android:orientation="vertical"
        android:scrollbars="none"
        app:layout_canScroll="true">

說明

     在需要捲動的檢視上新增屬性app:layout_canScroll="true",來使其獲得捲動的能力。另外所有scrollView的屬性,可以設定在該容器控制元件中。

 

 

屬性覆蓋

          有一種很常見的業務場景,在一個條目中有多個控制元件,控制元件大多數屬性是相同的(例如TextView的字型顏色、大小等),一般我們會給每一個控制元件加上相同的屬性(冗餘)、或者定義公共樣式(太麻煩)。現在參考html的佈局方式,在父控制元件中設定公共樣式,給子控制元件當預設值。

  <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:textColor="#FF0000"
        android:textSize="20sp"
        android:textStyle="italic"
        android:scaleType="center"
        app:layout_cover_children="true">

        <ImageView

            android:layout_width="50dp"
            android:src="@mipmap/ic_launcher"
            android:layout_height="50dp"/>

        <TextView
            android:capitalize="none"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FF00FF"
            android:textStyle="italic"
            android:text="11111" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:textSize="13dp"
            android:text="22222" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:textSize="14dp"
            android:text="333333" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:textSize="15dp"
            android:text="444444" />

    </LinearLayout>

 

支援的屬性

       

控制元件型別屬性 
TextView
textColor
 
textSize
 
text
 
maxLines
 
maxEms
 
textColorHint
 
hint
 
textDirection
 
textStyle
 
capitalize
 
ImageView
src
 
scaleType
 

 

擴充套件

 

屬性擴充套件

  SuperXml.addDecorate(object : IDecorateView() {
            override fun initExtraInfo(typedArray: TypedArray): Boolean {
            }

            override fun decorate(view: View) {
            }
        })

實現參考

internal class RadiusDecorate(var radius: Float = 0f) : IDecorateView() {

    override fun initExtraInfo(typedArray: TypedArray): Boolean {
        radius = typedArray.getDimension(R.styleable.decorate_view_layout_radius,0f)
        return radius > 0
    }

    override fun decorate(view: View)= view.setRadius(radius)

}

 

控制元件替換 OR 增強

 SuperXml.addDecorate(object :IWrapDecorateView(){
            override fun decorateView(view: View): View {
            }

            override fun initExtraInfo(typedArray: TypedArray): Boolean {
            }
        })

實現參考

internal class ScrollWrapDecorate(var canScroll: Boolean = false) : IWrapDecorateView() {

    override fun initExtraInfo(typedArray: TypedArray): Boolean {
        canScroll = typedArray.getBoolean(R.styleable.decorate_view_layout_canScroll, false)
        return canScroll
    }

    override fun decorateView(view: View): View {
        return ScrollViewProxy(
            view,
            attributeSet
        )
    }


}

 

屬性覆蓋

  SuperXml.addCoverAttributeParse(object : AbsChildViewParse<TextView>(){
            override fun createInfoView(context: Context, attributeSet: AttributeSet?): TextView {
            }

            override fun coverAttribute(): MutableList<*> {
            }
        })

實現參考

class TextViewCoverParse : AbsChildViewParse<TextView>() {

    override fun createInfoView(context: Context, attributeSet: AttributeSet?): TextView =
        TextView(context, attributeSet)

    override fun coverAttribute(): MutableList<*> = mutableListOf(
        AttributeInfo("textSize",{ textSize }) { value -> textSize = value },
        AttributeInfo("textColor",{ textColors }) { value -> setTextColor(value) },
        AttributeInfo("text",{ text }) { text -> setText(text) },
        AttributeInfo("maxLines",{ maxLines }) { maxLines -> setMaxLines(maxLines) },
        AttributeInfo("maxEms",{ maxEms }) { maxEms -> setMaxEms(maxEms) },
        AttributeInfo("textColorHint",{ hintTextColors }) { hintTextColors -> setHintTextColor(hintTextColors) },
        AttributeInfo("hint",{ hint }) { hint -> setHint(hint) },
        AttributeInfo("textDirection",{ textDirection }) { textDirection -> setTextDirection(textDirection) },
        AttributeInfo("textStyle",{ typeface }) { typeface -> setTypeface(typeface) },
        AttributeInfo("capitalize",{ inputType }) { inputType -> setInputType(inputType) }
    )



}

 

程式碼:github

https://github.com/long8313002/SuperXml