轉(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測試示例
- 無ActionBar
* 白色背景: `Activity`+ `android:theme="@style/Theme.AppCompat.Light"`
* 黑色背景: `Activity`+ `android:theme="@style/Theme.AppCompat"`
* 自定義默認(rèn)背景:`Activity` 或者 `Activity`+`android:theme="@style/AppTheme"`
- 有ActionBar
- 舊版本:繼承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
-
方法執(zhí)行流程
- 具體實(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
- 方法執(zhí)行流程:
每次長按指定的View疲酌,自動(dòng)在所按的位置處彈出menu蜡峰。 - 設(shè)置流程:
- Activity中獲取一個(gè)組件,如一個(gè)Button:
private Button btn;
- 讓這個(gè)Button進(jìn)行初始化并讓其注冊到ContextMenu中:
btn = (Button) findViewById(R.id.btn_actionbar); registerForContextMenu(btn);
- 重寫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)