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檔案進行分析,才知道程式碼錶達意圖)。這邊封裝了常用的複用屬性,如下:
屬性 | 屬性型別 | 說明 |
---|---|---|
| | 背景(是否可用) |
| reference|color(資源或者顏色) | 背景(是否按壓) |
| reference|color(資源或者顏色) | 背景(是否選擇) |
| reference|color(資源或者顏色) | 字型顏色(是否可用) |
| reference|color(資源或者顏色) | 字型顏色(是否按壓) |
| 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 | | |
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
ImageView | | |
|
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)
}
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) }
)
}