亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中drawable.xml替代方案的示例分析

發布時間:2021-08-11 14:38:21 來源:億速云 閱讀:167 作者:小新 欄目:移動開發

這篇文章給大家分享的是有關Android中drawable.xml替代方案的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

前言

在開發中我們經常要使用圖片或者drawable文件夾下的xml,來實現一些效果,Drawable的用法都和xml相關,我們可以使用shape、layer-list等標簽繪制一些背景,還可以通過selector標簽定義View的狀態的效果等。當然了基本每個標簽都對應于一個真正的實體類。

所有drawable.xml對應的Java類如下

Android中drawable.xml替代方案的示例分析

如何維護(替換)drawable xml是android開發中一個老生常談的話題。按照標準的Android布局開發模式,我們不得不為各種UI效果新建不同的xml文件進行描述,哪怕是簡單的一個圓角。隨著項目迭代,成百上千的xml連同那模棱兩可的文件名,不僅讓開發者復用或清理的成本難以估計,還使得項目體積急劇增大。因此,下面我們探索一種原理巧妙、適配全面的drawable替代方案。

下面話不多說了,來一起看看詳細的介紹吧

傳統方案總結

我們先概括下目前市面上已有的方案,大致分為兩種實現方式。

一種是繼承某個(或某幾個)常用的控件,然后將drawable.xml中的常用屬性作為當前控件的自定義屬性,最后在控件內部動態生成drawable作為該控件的背景。這種方案的優點很明顯:能直觀地將drawable效果描述作為控件的屬性定義在布局xml中,具有很好的可讀性;但是缺點也不可忽視,這些屬性并不能應用到任意控件,導致在很多時候還是不得不創建drawable.xml文件。

另一種方案則是將drawable的常用屬性封裝為代碼API,以動態的方式在代碼中生成并賦值給控件。這種方案理論上完全拋棄了drawable.xml,可以適配任意控件,但是若想完全以這種方式達到完全替換xml,個人覺得不可能,代碼量大,關聯性低是其最大的缺點,單看布局,無從知曉該控件的最終效果。不過,如果兩相結合,作為對第一種方案的補充倒是一個不錯的方案。

新方案探索

上述兩種方案各有千秋,但都無法完全解決問題,我們對上述兩種方案進行分析,提出以下問題:為什么不能有一種「既具有高可讀性,又能全面適配」的drawable.xml替代方案呢?也就是說能同時兼顧前面提到的兩種方案的優點,高可讀性意味著對drawable的描述需要作為屬性定義在布局文件中、全面適配意味這些屬性對任意控件都有效。思來想去,答案似乎只有一個:DataBinding。說到這里,可能有些朋友已經隱隱猜到了,不過別急,容我娓娓道來。

DataBinding是Android官方推出的數據綁定庫,盡管已有數年,但是我估計仍有部分開發者還沒有接觸甚至有些抵觸,具體就不細說,但是我希望你暫且能擁抱它,繼續閱讀。

數據綁定讓數據變化能直接反映到布局中,對于控件已有的屬性,例如TextView的android:text屬性,一旦通過DataBinding綁定:

<TextView
 android:text="@{name}"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />

在運行時內部就會調用TextView內部的setText方法。其實現原理的關鍵就是DataBinding通過提供的@BindingAdapter注解,該注解將任意指定的屬性和任意指定的方法關聯,DataBinding會在編譯的時候動態生成的調用關系,而對于常用的控件,DataBinding已經預置了對應的注解方法,例如以下就是TextView的setText方法:

@BindingAdapter("android:text")
public static void setText(TextView view, CharSequence text) {
 final CharSequence oldText = view.getText();
 if (text == oldText || (text == null && oldText.length() == 0)) {
  return;
 }
 if (text instanceof Spanned) {
  if (text.equals(oldText)) {
   return; // No change in the spans, so don't set anything.
  }
 } else if (!haveContentsChanged(text, oldText)) {
  return; // No content changes, so don't set anything.
 }
 view.setText(text);
}

我們需要關注的就是這個@BindingAdapter注解,「任意指定的屬性」這個屬性并非特指我們在布局中Android提供的標準屬性,也就是說,我們可以提供任意字符串作為屬性,而任意方法很好理解,上面的代碼片段很好的表達了這個意思,我們唯一需要關注的就是這個方法的參數:第一個參數是指定注解中的屬性的作用域,后面的參數則是和注解所聲明的屬性一一對應,那么結合到我們本文的主題,答案也就呼之欲出了:

新方案實現

提供一個用@BindingAdapter注解的方法,作用域指定為View(即任意控件);參數約定為drawable.xml中的屬性,不就達到了目的嗎。是否是感覺到一絲絲巧妙?既然方案有了,下面我們來看具體實現。

限于drawable屬性的豐富性,本文以常用的屬性solid 和 corner為例展開。如以下片段所示:

@BindingAdapter(value = {
  "drawable_solidColor",
  "drawable_radius",
}, requireAll = false)
public static void setViewBackground(View v, int color, int radius) {
 GradientDrawable drawable = new GradientDrawable();
 drawable.setColor(color);
 drawable.setCornerRadius(radius);
 view.setBackground(drawable);
}

上面代碼片段定義了兩個屬性:drawable_solidColor, drawable_radius,分別表示solid的color和corner的radius屬性,也就是說稍后我們就就可以在布局文件中為每個View都指定該屬性了;

這里可能有朋友會產生疑問,drawable的屬性那么多,這里只定義了兩個還好,如果把所有的drawable屬性都定義,那豈不是每個控件都要把每個屬性都指定一次,即使不需要。所以還需要提一下requireAll參數,它表示是否需要每個屬性都必須綁定了數據才會調用setViewBackground方法,設置為false后,就可以在布局文件中只指定需要的屬性即可。

以上幾行代碼完成了基本定義,下面我們來看看如何使用:

<layout>
 <TextView
  drawable_radius="@{10}"
  drawable_solidColor="@{0xffff0000}"
  
  android:layout_width="60dp"
  android:layout_height="60dp" />
<layout/>

不用懷疑,就是這么簡單,即使這里不貼出效果圖,我想大家腦海中已經浮現出來了,是不是覺得一目了然?以此類推,其它的drawable屬性也可以通過本方案逐一實現。

感謝各位的閱讀!關于“Android中drawable.xml替代方案的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

厦门市| 通榆县| 九江县| 福安市| 玉田县| 伊宁县| 上高县| 波密县| 霍州市| 比如县| 大城县| 安阳市| 陈巴尔虎旗| 揭阳市| 惠水县| 冕宁县| 道孚县| 张家界市| 什邡市| 普定县| 禄丰县| 行唐县| 宁夏| 和静县| 四川省| 长沙市| 五大连池市| 黑河市| 栾城县| 湘潭市| 阿图什市| 阳江市| 天气| 成武县| 平安县| 钦州市| 察哈| 铜山县| 烟台市| 锦屏县| 罗甸县|