Android style & Theme 再探析(四)

業(yè)務(wù)實(shí)踐心得總結(jié)

基于前幾篇的探究,我們已經(jīng)有了對(duì)一個(gè)app的theme和style的理論探究和demo描述了不少泉褐,那么接下來針對(duì)我在自己在app生產(chǎn)環(huán)境中的使用的一個(gè)使用心得總結(jié)

Android Theme的生產(chǎn)環(huán)境使用總結(jié)



本篇主要針對(duì)小伙伴如果要在自己的app中實(shí)踐赐写,整理以前混亂的theme和style的一個(gè)實(shí)踐

針對(duì)Theme配置的一些建議

如果大家按本文第一章的方式設(shè)定Theme時(shí),一定要注意幾點(diǎn):

文字顏色一定要設(shè)置小心膜赃,由于Theme具有繼承性挺邀,所以文字顏色的設(shè)定會(huì)被Android本身的style的繼承結(jié)構(gòu)沿用到其子類;但是跳座,在沿用其子類時(shí)端铛,有時(shí)會(huì)進(jìn)行一定配置的重寫,而此時(shí)重寫的配置就會(huì)變?yōu)橐粋€(gè)不可控因素疲眷,產(chǎn)生意想不到的bug

示例:
筆者在使用時(shí)禾蚕,設(shè)定了這樣的配置

<style name="ThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
        <!--忽略部分代碼-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="buttonStyle">@style/EhiTheme.Button</item>
    </style>
    <!--主題修改為使用最新-->
    <style name="EhiTheme" parent="ThemeBase">
        <!--定義v21 之前api的內(nèi)容-->
    </style>
      <!--重寫button默認(rèn)樣式-->
     <style name="EhiTheme.Button" parent="@style/Widget.AppCompat.Button">
        <item name="android:background">@drawable/btn_default_ehi_selector</item>
        <item name="android:textColor">@color/white</item>
    </style>

代碼可以看的出,此為一個(gè)button的默認(rèn)樣式修改咪橙;而這份代碼關(guān)鍵就在于

<item name="android:textColor">@color/white</item>

這句代碼將按鈕文字設(shè)置為白色十分危險(xiǎn)夕膀,因?yàn)锳ndroid中很多控件都會(huì)沿用這部分的樣式;但是美侦,同時(shí)這個(gè)部分的樣式針對(duì)各個(gè)版本的Android系統(tǒng)上也是有著不同的體現(xiàn)产舞!

以下是不同版本下,此重寫樣式后AlertDialog的不同體現(xiàn)


Android 8.0
Android 6.0

通過上圖可以看到菠剩,在Android 6.0的彈窗上易猫,文字采用了colorAccent的顏色,而Android8.0則采用了文字繼承下來的白色具壮;但是兩者在顯示上的一個(gè)共同點(diǎn)就是准颓,背景都被置空;這就造成了白色背景加上白色字體的顯示bug棺妓!

a>同時(shí),要特別注意的一點(diǎn)是攘已,這樣的bug不止存在alertDialog,同樣會(huì)反映在 timePickDialog和datePickDialog上面怜跑!
b>另外样勃,需要大家注意的是吠勘,在v7包下的alertDialog和app包下的alertDialog是讀取的兩套設(shè)定

v7包:

 <item name="alertDialogTheme"></item>

app系統(tǒng)包下:

<item name="android:alertDialogTheme"></item>

如果項(xiàng)目在使用上不規(guī)范的情況下,很可能兩種dialog都會(huì)引入進(jìn)行使用峡眶,那么兩種其一不起作用剧防,都會(huì)有產(chǎn)生Bug的風(fēng)險(xiǎn)!
解決方案:
針對(duì)Dialog的Theme主題部分辫樱,進(jìn)行重寫

定義Alert自己的Theme:

colors.xml

<color name="colorAccent">#FFFF7E00</color>

Themes.xml

    <style name="EhiTheme.AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColor">@color/colorAccent</item>
        <item name="buttonStyle">@style/EhiTheme.Button.Alert</item>
    </style>

    <style name="EhiTheme.Button.Alert" parent="@style/Widget.AppCompat.Button">
        <item name="android:background">@color/white</item>
        <item name="android:textColor">@color/colorAccent</item>
    </style>

<style name="ThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
        <!--定義v7 之后所有api的內(nèi)容-->
        <!--基本主題色-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--部分忽略-->
        <item name="buttonStyle">@style/EhiTheme.Button</item>
        <item name="alertDialogTheme">@style/EhiTheme.AlertDialog</item>
         <item name="android:alertDialogTheme">@style/EhiTheme.AlertDialog</item>
    </style>
       

v21中Themes.xml

     <style name="EhiTheme" parent="ThemeBase">
        <!--定義v21 之后api的內(nèi)容-->
        <item name="android:timePickerDialogTheme">?alertDialogTheme</item>
        <item name="android:datePickerDialogTheme">?alertDialogTheme</item>
        <item name="android:alertDialogTheme">?alertDialogTheme</item>
    </style>

代碼中峭拘,如果結(jié)構(gòu)不好有多個(gè)baseActivity基類一定要注意!父類在繼承FragmentActivityAppCompatActivity時(shí)狮暑,其展現(xiàn)形式是不一樣的鸡挠,由于AppCompatActivity在為了保證變?yōu)榻y(tǒng)一樣式在內(nèi)部做了很多封裝;(ps:theme繼承了的情況下Theme.AppCompat.Light.NoActionBar心例;使用基礎(chǔ)activity會(huì)crash)宵凌,需要在添加后測(cè)試一下

針對(duì)view自定義屬性

自定義控件的屬性的命名的一點(diǎn)小建議:

以前我們的自定義view屬性的命名全憑喜好
主流的一般有這樣的,小駝峰的命名形式

<declare-styleable name="EhiTitleBar">
    
        <attr name="isSearchView" format="boolean"/>
        <attr name="searchViewHint" format="string" />
        <attr name="titleBackground" format="color|reference" />
    </declare-styleable>

還有下劃線大法的

<declare-styleable name="EhiDrawingBoard">
        <attr name="stroke_width" format="integer"/>
        <attr name="paint_color" format="color"/>
        <attr name="canvas_color" format="color|reference"/>
        <attr name="anti_alias" format="boolean"/>
    </declare-styleable>

但是我認(rèn)為很多內(nèi)容的使用止后,我們都應(yīng)該更接近原生控件的使用:

例如textView

<TextView
        android:id="@+id/text_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="今天"
        android:layout_marginLeft="10dp"
        android:textColor="@color/black"
        android:textSize="18sp" />

可以看的出android的控件命名其實(shí)是分成兩部分
屬性是作用于其子類本身的內(nèi)部,像這樣的文本尺寸

android:textSize="18sp"

采用了小駝峰法

而屬性比如是作用于控件的類似layoutparam這種和父類相關(guān)的屬性

android:layout_height="wrap_content"

以下劃線來區(qū)分溜腐,這樣其實(shí)我覺得對(duì)于學(xué)習(xí)和接受度其實(shí)都可以很快译株,畢竟在使用原始控件時(shí)的方式都類似

Style命名的一點(diǎn)小建議

style的使用命名規(guī)范的一點(diǎn)小建議

以前的style我們是這么命名的:

<!-- 條目標(biāo)簽樣式 -->
   <style name="item_reimburse_label">
       <item name="android:layout_width">0dp</item>
       <item name="android:layout_height">wrap_content</item>
       <item name="android:layout_weight">0.3</item>
   </style>

但是,這種命名其實(shí)非常凌亂挺益,

  • 看不出style的層級(jí)關(guān)系歉糜,繼承關(guān)系
  • 看不出它所屬的模塊;所以在比較大的項(xiàng)目工程中望众,在上方使用者調(diào)用會(huì)非撤瞬梗混亂
  • style的統(tǒng)一管理十分困難,有差不多的一組style有樣式改動(dòng)烂翰,將會(huì)是一個(gè)災(zāi)難
  • 組件化后夯缺,各個(gè)模塊容易出現(xiàn)命名重復(fù)問題

后來我們進(jìn)行了一點(diǎn)優(yōu)化

<!--myorder是module名-->
 <style name="myorder_item_reimburse_label">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_weight">0.3</item>
    </style>

命名雖然看的出模塊所屬,但是我覺得沒有充分將style的功能發(fā)揮出來甘耿,使用也并不怎么友好踊兜!

我認(rèn)為比較適合我們?cè)诖笮晚?xiàng)目中工程化的style的命名是需要更向系統(tǒng)的style命名形式靠攏的:

一般我們可以采用大駝峰的命名形式,以 . 作為各種應(yīng)用場(chǎng)景的區(qū)分

Module.頁面.控件類型.控件修飾描述

    <!--總模塊-->
    <style name="CompanyInfo" />
     <!--總模塊佳恬,所屬界面-->
    <style name="CompanyInfo.DriverMangerSearchOrderResult" />
     <!--總模塊捏境,所屬界面.對(duì)應(yīng)控件-->
    <style name="CompanyInfo.DriverMangerSearchOrderResult.ItemLabelContent">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_marginTop">@dimen/tv_order_content_margin_top</item>
        <item name="android:ellipsize">end</item>
    </style>
      <!--總模塊,所屬界面.對(duì)應(yīng)控件.控件應(yīng)用場(chǎng)景描述-->
     <style name="CompanyInfo.DriverMangerSearchOrderResult.ItemLabelContent.NoBackground">
        <item name="android:background">@null</item>
    </style>

可是毁葱,我們很多情況下會(huì)有很多界面共用同樣的樣式垫言,所以為了這種情況,我們可以利用 style的顯示繼承
首先倾剿,定義一個(gè)公共模塊的樣式

<!--labelContentView的Style-->
    <style name="EhiBase.Widget.LabelContent">
        <!--部分忽略-->
        <item name="contentColor">@color/colorGray100</item>
        <item name="contentHintColor">@color/colorGray350</item>
    </style>

然后筷频,在自己的module里面直接進(jìn)行引用,這樣,在同時(shí)保證了命名的統(tǒng)一的同時(shí),還兼顧的使用通用樣式

<!--用于個(gè)人管理模塊-->
    <style name="PersonalManager" />
    <!--個(gè)人信息界面-->
    <style name="PersonalManager.MyInformation" />
    <!--利用顯示繼承截驮,使用通用樣式-->
    <style name="PersonalManager.MyInformation.LabelContent" parent="EhiBase.Widget.LabelContent"/>
     

這樣有以下優(yōu)勢(shì)

  • 有統(tǒng)一的模塊描述笑陈,頁面描述,控件描述葵袭;
  • 能夠更好使得命名空間不沖突
  • 同時(shí)利用 style的顯式繼承可以做到對(duì)控件的統(tǒng)一管控
  • 類似Android原生的用法涵妥,上手更快

部分源碼展示

 <style name="Theme.AppCompat" parent="Base.Theme.AppCompat"/>
    <style name="Theme.AppCompat.CompactMenu" parent="Base.Theme.AppCompat.CompactMenu"/>
    <style name="Theme.AppCompat.DayNight" parent="Theme.AppCompat.Light"/>
    <style name="Theme.AppCompat.DayNight.DarkActionBar" parent="Theme.AppCompat.Light.DarkActionBar"/>
    <style name="Theme.AppCompat.DayNight.Dialog" parent="Theme.AppCompat.Light.Dialog"/>
    <style name="Theme.AppCompat.DayNight.Dialog.Alert" parent="Theme.AppCompat.Light.Dialog.Alert"/>

隱式繼承控制命名的完整性,顯式繼承控制模塊與模塊之間的通用部分

專題系列:
Android style & Theme 再探析(一)—— 你真的懂Style和Theme嗎坡锡?
Android style & Theme 再探析(二) —— 一統(tǒng)View規(guī)范的大殺器——material design
Android style & Theme 再探析(三) —— 定制Theme示例和日夜間模式踩坑大匯總
Android style & Theme 再探析(四) —— 業(yè)務(wù)實(shí)踐心得總結(jié)
博主博客:
http://www.whdreamblog.cn/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蓬网,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鹉勒,更是在濱河造成了極大的恐慌帆锋,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禽额,死亡現(xiàn)場(chǎng)離奇詭異锯厢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)脯倒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門实辑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人藻丢,你說我怎么就攤上這事剪撬。” “怎么了悠反?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵残黑,是天一觀的道長。 經(jīng)常有香客問我斋否,道長梨水,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任如叼,我火速辦了婚禮冰木,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笼恰。我一直安慰自己踊沸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布社证。 她就那樣靜靜地躺著逼龟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪追葡。 梳的紋絲不亂的頭發(fā)上腺律,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天奕短,我揣著相機(jī)與錄音,去河邊找鬼匀钧。 笑死翎碑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的之斯。 我是一名探鬼主播日杈,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼佑刷!你這毒婦竟也來了莉擒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤瘫絮,失蹤者是張志新(化名)和其女友劉穎涨冀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麦萤,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹿鳖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壮莹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栓辜。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垛孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情施敢,我是刑警寧澤周荐,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站僵娃,受9級(jí)特大地震影響概作,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜默怨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一讯榕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匙睹,春花似錦愚屁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梦谜,卻和暖如春丘跌,著一層夾襖步出監(jiān)牢的瞬間袭景,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工闭树, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耸棒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓报辱,卻偏偏與公主長得像与殃,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捏肢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容