Android開發(fā)細(xì)節(jié)--查漏補(bǔ)缺(一):UI篇

轉(zhuǎn)載請說明出處:Android開發(fā)細(xì)節(jié)--查漏補(bǔ)缺(一):UI篇

引言:一開始,先和大家可能從最開始接觸Android開發(fā)時(shí)就存在的一些我們用過但不太關(guān)注的UI部件相關(guān)知識(shí)。第一篇哈垢,先說一下有關(guān):Menu、標(biāo)題欄 和 Android主題(Theme)的相關(guān)知識(shí)。

Android Theme(主題)


注意:一般我們使用或者自定義style等芥喇,大多用于單個(gè)View,稱為View的樣式凰萨。而樣式也能用于Activity或整個(gè)Application继控,這時(shí)就需要在相應(yīng)<activity>或<application>標(biāo)簽中設(shè)置android:theme屬性,引用的其實(shí)也是style胖眷,但一般稱為主題武通。

  • themes.xml: 低版本的主題,目標(biāo)API level一般在10以下

  • themes_hole.xml: 從 API level 11添加的主題

一珊搀、 support v7庫
作用:用于某些控件和主題等兼容至Android2.1版本(API 7)
對于Theme主題的影響:Theme.AppCompat系列兼容主題冶忱,在引用到v7包之后,就要求使用境析,而android3.0以上系統(tǒng)帶有的Theme.Holo系列主題囚枪,則是未引用兼容包時(shí)注意使用。

  • Android3.0及以上的版本的Style一般寫法:
<style name="XXX" parent="@android:style/Theme.Holo">
   <item name="android:xxx">yyy</item> 
</style>
  • Android2.1及以上兼容版本的Style一般寫法:
<style name="XXX" parent="@style/Theme.AppCompat">
   <item name="xxx">yyy</item> 
</style>

二劳淆、 theme測試示例

  1. 無ActionBar
* 白色背景: `Activity`+ `android:theme="@style/Theme.AppCompat.Light"`
* 黑色背景: `Activity`+ `android:theme="@style/Theme.AppCompat"`
* 自定義默認(rèn)背景:`Activity`  或者 `Activity`+`android:theme="@style/AppTheme"`
  1. 有ActionBar
  2. 舊版本:繼承ActionBarActivity
  * 全白色背景:`ActionBarActivity`+`android:theme="@style/Theme.AppCompat.Light"`
  * 全黑色背景:`ActionBarActivity`+`android:theme="@style/Theme.AppCompat"`
  * 白色背景黑色ActionBar:`ActionBarActivity`+`android:theme="@style/Theme.AppCompat.Light.DarkActionBar"`
  * 自定義默認(rèn)背景:`ActionBarActivity`  或者`ActionBarActivity`+`android:theme="@style/AppTheme"`

Menu


Android Menu 主要是兩種:①OptionMenu【點(diǎn)擊ActionBar的菜單選項(xiàng)或者手機(jī)硬件MENU按鍵觸發(fā)顯示菜單】 ②ContextMenu【指定的View或ViewGroup的長按觸發(fā)】

一链沼、 OptionMenu

  1. 方法執(zhí)行流程


    OptionsMenu.png
  2. 具體實(shí)現(xiàn)代碼示例
* Activity代碼中添加:

```
  @Override
public boolean onCreateOptionsMenu(Menu menu) {
    //方式一(java)
     /*第一個(gè)參數(shù)是groupId,如果不需要可以設(shè)置為Menu.NONE沛鸵。

將若干個(gè)menu item都設(shè)置在同一個(gè)Group中括勺,可以使用setGroupVisible(),setGroupEnabled(),setGroupCheckable()這樣的方法朝刊,
而不需要對每個(gè)item都進(jìn)行setVisible(), setEnable(), setCheckable()這樣的處理耀里,這樣對我們進(jìn)行統(tǒng)一的管理比較方便
* 第二個(gè)參數(shù)就是item的ID,我們可以通過menu.findItem(id)來獲取具體的item
* 第三個(gè)參數(shù)是item的順序拾氓,一般可采用Menu.NONE冯挎,具體看本文最后MenuInflater的部分
* 第四個(gè)參數(shù)是顯示的內(nèi)容,可以是String咙鞍,或者是引用Strings.xml的ID
*/
menu.add(Menu.NONE,ONE_ID,Menu.NONE,"1 Pixel");
menu.add(Menu.NONE, TWO_ID, Menu.NONE, "2 Pixels");
menu.add(Menu.NONE, EIGHT_ID, Menu.NONE, "8 Pixels");
……
///方式二(xml)
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.activity_actionbar,menu);

    // 子菜單設(shè)置
    //通過addSubMenu設(shè)置子菜單房官,作為item加入Menu。參數(shù)和addMenu一致续滋,為了簡單翰守,我們這里的ID直接采用數(shù)字表示
    SubMenu submenu = menu.addSubMenu(Menu.NONE, 100, Menu.NONE, "子菜單測試");
    //在SubMenu中增加子菜單的item
    submenu.add(Menu.NONE,101,Menu.NONE,"sub One");
    submenu.add(Menu.NONE,102,Menu.NONE,"sub Two");
    submenu.add(Menu.NONE,103,Menu.NONE,"sub Three");
    submenu.add(Menu.NONE,104,Menu.NONE,"sub Four");
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    ///----------實(shí)現(xiàn)每次Menu打開時(shí)的操作---------------
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.action_search:
            Toast.makeText(this, "搜索",Toast.LENGTH_SHORT).show(); 
           break;
        case R.id.action_settings:
            Toast.makeText(this, "設(shè)置",Toast.LENGTH_SHORT).show();
            break;
    }
    return super.onOptionsItemSelected(item);
}
```
* 自定義的res/menu/activity_actionbar.xml:

```
<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >



<item android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="@android:string/search_go"
yourapp:showAsAction="ifRoom" />
<item android:id="@+id/action_settings"
android:title="設(shè)置"
yourapp:showAsAction="never" />
</menu>
```

二、 ContextMenu

  1. 方法執(zhí)行流程:
    每次長按指定的View疲酌,自動(dòng)在所按的位置處彈出menu蜡峰。
  2. 設(shè)置流程:
  • Activity中獲取一個(gè)組件,如一個(gè)Button:
    private Button btn;
  • 讓這個(gè)Button進(jìn)行初始化并讓其注冊到ContextMenu中:
     btn  = (Button) findViewById(R.id.btn_actionbar);
     registerForContextMenu(btn);
    
  1. 重寫ContextMenu相關(guān)方法朗恳,讓此方法觸發(fā)時(shí)湿颅,彈出指定的ContextMenu【注意是ContextMenu類型的,不是Menu類型】:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater mi = getMenuInflater();
///R.menu.activity_actionbar與上面OptionsMenu的一樣!
mi.inflate(R.menu.activity_actionbar,menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
}


## ActionBar
---
1. ActionBar的基本使用:
 1. Android 版本 >= 3.0 粥诫,所有使用Theme.Holo主題(及其子類)的Activity都包含了ActionBar油航,當(dāng)`targetSdkVersion` 或 `minSdkVersion `屬性被設(shè)置成“11”或者更大時(shí),他是默認(rèn)主題
 2. Android版本>=2.1 怀浆,要添加ActionBar谊囚,需要加載Android Support庫:`v7 appcompat`庫(現(xiàn)在AS在新建項(xiàng)目時(shí),基本都會(huì)為我們添加這個(gè)庫)执赡。然后:①讓`Activity`繼承`ActionBarActivity` ②在manifast.xml文件中镰踏,給<activity>添加一句:`<activity android:theme="@style/Theme.AppCompat.Light" ... >`

2. xml中設(shè)定每個(gè)Activity的ActionBar上顯示的標(biāo)題(Label):
 通過設(shè)置清單文件中Activity標(biāo)簽中的label屬性,如:`<activity android:name=".actionbar.MyActionBarActivity"    android:label="ActionBar活動(dòng)" ……/>`
![](http://upload-images.jianshu.io/upload_images/2369895-3a277f9988102697.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

3. ActionBar從創(chuàng)建到行為實(shí)現(xiàn)
 * 創(chuàng)建相應(yīng)的Activity:ActionBarActivity搀玖、AppCompatActivity(均位于v7 support庫中余境,用于兼容到Android2.1版本,即API 7)
 * 創(chuàng)建Menu菜單:
   * 方式一:java代碼
     在**onCreateOptionsMenu(Menu menu)**方法中灌诅,加入如下示例:
     ```
@Override
 public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE,ONE_ID,Menu.NONE,"1 Pixel");
     menu.add(Menu.NONE, TWO_ID, Menu.NONE, "2 Pixels");
     menu.add(Menu.NONE, EIGHT_ID, Menu.NONE, "8 Pixels");
    ……
     return super.onCreateOptionsMenu(menu);
 }
     ```
   * 方式二:xml定義后再引用
     先創(chuàng)建xml菜單布局文件**res/menu/my_menu.xml**:
     ```
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
 <item android:id="@+id/action_search"
     android:icon="@android:drawable/ic_menu_search"
     android:title="@android:string/search_go"
     yourapp:showAsAction="ifRoom"
/>
 <item android:id="@+id/action_settings"
     android:title="設(shè)置"
     yourapp:showAsAction="never"
/>
…………
</menu>
     ```
       此時(shí)芳来,ActionBar已經(jīng)有了菜單列表了!
 * 完善ActionBar信息:
     在Java代碼中完善ActionBar信息
     ```
getSupportActionBar().setIcon(R.mipmap.ic_launcher);
getSupportActionBar().setSubtitle("我是subTitle");
getSupportActionBar().setCustomView(R.layout.view_custom);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setElevation(50);
     ```
 * 最終截圖
   ![](http://upload-images.jianshu.io/upload_images/2369895-e076b6dc075cb7c6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

3. ActionBar的自定義背景
完整示例:`res/values/themes.xml`

<?xml version="1.0" encoding="utf-8"?>
<resources>

<style name="CustomActionBarTheme"
parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
<item name="android:actionMenuTextColor">@android:color/holo_blue_bright</item>
<item name="android:windowActionBarOverlay">true</item>

<item name="actionBarStyle">@style/MyActionBar</item>
<item name="actionBarTabTextStyle">@style/MyActionBarTabText</item>
<item name="actionMenuTextColor">@android:color/holo_blue_bright</item>

<item name="windowActionBarOverlay">true</item>
</style>

<style name="MyActionBar"
parent="@style/Widget.AppCompat.ActionBar">
<item name="android:background">@android:color/holo_green_dark</item>
<item name="android:titleTextStyle">@style/MyActionBarTitleText</item>

<item name="background">@android:color/holo_green_dark</item>
<item name="titleTextStyle">@style/MyActionBarTitleText</item>
</style>

<style name="MyActionBarTitleText"
parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">@android:color/holo_red_light</item>

</style>

<style name="MyActionBarTabText"
parent="@style/Widget.AppCompat.ActionBar.TabText">
<item name="android:textColor">@android:color/holo_blue_light</item>

</style>
</resources>


4. 利用ActionBar快速構(gòu)造返回上級(jí)的按鈕
截圖:
![](http://upload-images.jianshu.io/upload_images/2369895-c87d204f1f047b1f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
設(shè)置步驟:
  1. ActionBarActivity或者AppCompatActivity的onCreate()方法中設(shè)置:
    * `getSupportActionBar().setDisplayHomeAsUpEnabled(true);`  v7庫兼容下使用
    * `getActionBar().setDisplayHomeAsUpEnabled(true);`  非兼容形式猜拾,minSdkVersion>=11時(shí)使用
  2. 在想要設(shè)置此功能的Activity的<activity>標(biāo)簽中設(shè)置如下:
    ```
      <activity android:name=".xxxx.SecondActivity"
  android:label="ActionBar活動(dòng)"
  android:parentActivityName=".MyToolBarActivity"    >
  <!--meta-data用于兼容support4.0以下即舌,指明上級(jí)活動(dòng)-->
  <meta-data
      android:name="android.support.PARENT_ACTIVITY"
      android:value="com.xxxxx.xxxxx.MainActivity"
      />
</activity>
    ```

## Toolbar
---
**一、背景**
* Android5.0推出的一個(gè)MD風(fēng)格的導(dǎo)航欄挎袜。
* 旨在取代ActionBar

**二顽聂、優(yōu)勢**
* 比ActionBar更加靈活:
  * 設(shè)置導(dǎo)航欄圖標(biāo)
  * 設(shè)置App的logo
  * 支持設(shè)置標(biāo)題和子標(biāo)題
  * 支持添加一個(gè)或多個(gè)的自定義控件
  * 支持Action Menu
* 可以放置任何位置

**三肥惭、用法**
1. 導(dǎo)入**appcompat-v7** 的兼容包,使用 **android.support.v7.widget.Toolbar** 進(jìn)行開發(fā)紊搪。
  ```
///基本格式
<android.support.v7.widget.Toolbar
       android:id="@+id/toolbar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
  >
</android.support.v7.widget.Toolbar>
  ```
2. 設(shè)置屬性
  1. 方式一:xml中設(shè)置(* 注意:v7兼容包的緣故蜜葱,toolbar的屬性不在系統(tǒng)中而需要額外查找導(dǎo)入,所有不能用`android:xxx`耀石,而需要自定義`xmlns:toolbar="http://schemas.android.com/apk/res-auto"`牵囤,另外,這種方式難以綁定menu菜單 *)
    ```
<android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/colorAccent"
      toolbar:navigationIcon="@mipmap/ic_launcher"
      toolbar:logo="@mipmap/ic_launcher"
      toolbar:title="Title"
      toolbar:subtitle="subTitle"
      toolbar:titleTextColor="@color/colorPrimary"
      toolbar:subtitleTextColor="@color/colorPrimaryDark"
  >
  <!--引入普通View-->
  <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
         android:layout_margin="20dp"
         android:text="點(diǎn)擊"
      />
  <!--引入自定義View-->
  <include
          layout="@layout/view_custom"/>
  </android.support.v7.widget.Toolbar>
    ```

    ![方式一截圖](http://upload-images.jianshu.io/upload_images/2369895-395aa3bbd52008a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  2. 方式二:Java中設(shè)置
    ```
Toolbar toolbar  = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.mipmap.ic_launcher);///導(dǎo)航icon
toolbar.setLogo(android.R.drawable.ic_menu_search);///logo
toolbar.setTitle("Title");///標(biāo)題
toolbar.setSubtitle("subTitle");///子標(biāo)題
toolbar.addView(new Button(this));//可自己動(dòng)態(tài)加CustomView
toolbar.inflateMenu(R.menu.activity_actionbar);///設(shè)置menu
    ```
     ![方式二截圖](http://upload-images.jianshu.io/upload_images/2369895-c4e559b8db4a60ad.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

3. 擴(kuò)展
  * 改變menu item的文字顏色
    * 首先滞伟,在themes.xml文件中添加一個(gè)<style>揭鳞,注意parent為**parent="Theme.AppCompat.Light.NoActionBar"**
      ```
<style name="MyToolbarStyle" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="android:textColorPrimary">@android:color/holo_red_light</item>
</style>
      ```
    * 然后,給toolbar加上屬性:** toolbar:popupTheme="@style/MyToolbarStyle"**
      ```
<android.support.v7.widget.Toolbar
  android:id="@+id/toolbar"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="@color/colorAccent"
  toolbar:popupTheme="@style/MyToolbarStyle"/>
      ```
     ![ 改變menu item的文字顏色](http://upload-images.jianshu.io/upload_images/2369895-e016baae7a52bd44.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 感謝閱讀
---
點(diǎn)擊進(jìn)入:[我的博客](http://androidjp.cn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梆奈,一起剝皮案震驚了整個(gè)濱河市野崇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亩钟,老刑警劉巖乓梨,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異径荔,居然都是意外死亡督禽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門总处,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人睛蛛,你說我怎么就攤上這事鹦马。” “怎么了忆肾?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵荸频,是天一觀的道長。 經(jīng)常有香客問我客冈,道長旭从,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任场仲,我火速辦了婚禮和悦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渠缕。我一直安慰自己鸽素,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布亦鳞。 她就那樣靜靜地躺著馍忽,像睡著了一般棒坏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遭笋,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天坝冕,我揣著相機(jī)與錄音,去河邊找鬼瓦呼。 笑死徽诲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吵血。 我是一名探鬼主播谎替,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蹋辅!你這毒婦竟也來了钱贯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤侦另,失蹤者是張志新(化名)和其女友劉穎秩命,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褒傅,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弃锐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了殿托。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霹菊。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖支竹,靈堂內(nèi)的尸體忽然破棺而出旋廷,到底是詐尸還是另有隱情,我是刑警寧澤礼搁,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布饶碘,位于F島的核電站,受9級(jí)特大地震影響馒吴,放射性物質(zhì)發(fā)生泄漏扎运。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一饮戳、第九天 我趴在偏房一處隱蔽的房頂上張望豪治。 院中可真熱鬧,春花似錦莹捡、人聲如沸鬼吵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽齿椅。三九已至琉挖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涣脚,已是汗流浹背示辈。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遣蚀,地道東北人矾麻。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像芭梯,于是被迫代替她去往敵國和親险耀。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc玖喘,orm框架 https://github.com/yangf...
    passiontim閱讀 15,429評(píng)論 2 45
  • 曾經(jīng)做大學(xué)畢業(yè)論文的某天甩牺,本來就心情不太好,發(fā)現(xiàn)夾在論文稿里面的封面不見了累奈,就輕聲說“肯定是有人拿走了”贬派,旁邊一室...
    AskYp閱讀 313評(píng)論 4 1
  • 昨天搞乏,何潔和赫子銘出現(xiàn)婚姻危機(jī)上了熱搜,疑似赫子銘的情感電臺(tái)錄音戒努、何潔閨蜜和制片人的爆料请敦、微博上情緒低落的文字,各...
    燚燚好運(yùn)祈福閱讀 802評(píng)論 1 6
  • 起床→刷牙→洗臉→喝水→喝奶→整理著裝,這是大部分人醒來后做事情的秩序缘缚; 喝湯→送菜拌飯,這是大部分人吃飯時(shí)的秩序...
    珊珊0329閱讀 373評(píng)論 0 0