【Android】Android之Action Bar


Action Bar是在窗口上指示用戶位置的組件,同時給用戶提供導航和操作。使用Action Bar可以讓你的應用在不同配置的屏幕上看起來比較一致。在開始之前,先了解一些相關的術語:

Action Bar有以下幾項關鍵功能:

1)為你的App提供一個裝飾處,同時也可以讓用戶知道自己的所在位置;

2)讓一些重要的操作以一種可預見的方式變得突出並且可訪問(比如搜索);

3)支持風格一致的導航和視圖切換手段;

ActionBar的API首先在Android3.0(API 11)中被加入,但是可以使用Support Library使得API 2.1以及以上支持。

這篇文章專注於指引開發者如何使用support library的action bar,但是在Android3.0以及以上的版本中,開發者應該使用框架中的ActionBar。絕大部分的API是一樣的,只有導入的package名字不一樣。

如果你打算支持比API Level 11低的版本,則導入android.support.v7.app.ActionBar,否則應該導入android.app.ActionBar。

 

Adding the Action Bar

注意,這里講述的是如何使用Support Library中的Action Bar。

1)創建Activity,繼承ActionBarActivity;

2)為Activity設置一個主題;

這樣,你的Activity就已經有了一個action bar了。

備注:在使用Theme.Holo主題的activity中action bar是默認被包含的,而Theme.Holo主題是當targetSdkVersion或者minSdkVersion屬性≥11的時候的默認主題。如果你不想要Activity的action bar,就設置Activity的主題為Theme.Holo.NoActionBar.設置Activity主題的方式如下:

1 <activity android:theme="@style/Theme.AppCompat.Light" ... >

 

Removing the action bar

你可以使用如下代碼在運行時隱藏ActionBar:

1 ActionBar actionBar = getSupportActionBar();//在API 11或者更高的API上,使用getActionBar方法
2 actionBar.hide();

當你隱藏了action bar,系統就會調節你的布局到可用的屏幕的空間,開發者可以調用show()方法讓action bar出現。

在隱藏和顯示action bar的過程中,由於屏幕空間的變化,會導致界面中心布局。如果你的activity經常顯示/隱藏action bar,你或許會期望使用疊加模式,疊加模式在activity布局的上層繪制action bar,將其上面的一部分變的模糊起來。這種情況下,action bar的隱藏和出現不會導致布局變化,為了開起疊加模式,需要為你的activity自定義主題,並且將windowActionBarOverlay設置為true。

 

Using a logo instead of an icon

缺省狀況下,系統會在ActionBar上使用用你的應用圖標,這個圖標是在你的<application>或者<activity>屬性中指定的,但是如果你寫明了<logo>屬性,系統就會使用logo屬性指定的圖片。

 

Adding Action Items

action bar提供了應用當前環境下的重要操作。這些操作排列在action bar上,或者是文字,或者是圖片,稱作action button。排列不下去或者不夠重要的action或被隱藏在actiono verflow中。用戶點擊action overflow的時候隱藏的操作就會顯示出來。

當你的Activity啟動的時候,系統會通過onCreateOptionsMemu()方法初始化你的action items。通過使用這個方法可以Inflate一個menu res文件。文件定義了所有的action items。例如:文件位置:res/menu/main_activity_actions.xml

1 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
2     <item android:id="@+id/action_search"
3           android:icon="@drawable/ic_action_search"
4           android:title="@string/action_search"/>
5     <item android:id="@+id/action_compose"
6           android:icon="@drawable/ic_action_compose"
7           android:title="@string/action_compose" />
8 </menu>

然后你可以在onCreateOptionMenu()中進行如下操作:

1 @Override
2 public boolean onCreateOptionsMenu(Menu menu) {
3     // Inflate the menu items for use in the action bar
4     MenuInflater inflater = getMenuInflater();
5     inflater.inflate(R.menu.main_activity_actions, menu);
6     return super.onCreateOptionsMenu(menu);
7 }

為了聲明一個item apperar作為一個acion button直接顯示在action bar中,我們需要添加屬性showAsAction="ifRoom",如下:

1 <menu xmlns:android="http://schemas.android.com/apk/res/android"
2       xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
3     <item android:id="@+id/action_search"
4           android:icon="@drawable/ic_action_search"
5           android:title="@string/action_search"
6           yourapp:showAsAction="ifRoom"  />
7     ...
8 </menu>

這個時候,當空間不夠的時候,action item就會顯示在action overflow中。

備注:showAsAction屬性使用的是自定義的名稱空間,當你使用support library定義的任何XML屬性的時候這是必須的,因為這些屬性不存在於老的Android框架API。所以你必須使用自己定義的名稱空間來=作為support library所需屬性的前綴。

如果你的menu既提供了title又提供了icon屬性,那么默認顯示icon,如果你想要顯示文字title,就添加"withText"屬性,如下:

1 <item yourapp:showAsAction="ifRoom|withText" ... />

備注:“withText”屬性是給action bar的一個暗示,告訴它應該顯示文字title,如果可以的話,就顯示,但是當icon是可用的並且action bar的空間受到限制的時候,就不一定會顯示了。

你應該為每一個item聲明title屬性,即使你不聲明title要顯示,因為:

1)如果沒有足夠的空間顯示所有的action item,那顯示在overflow中的Item就只會顯示title;

2)視覺受損者會讀取title;

3)如果action item只顯示icon,那么當用戶長按item的時候,會顯示一個小的提示窗口顯示action的title;

icon是可選的,但是推薦使用。

開發者可以使用"always"聲明一個Item永遠作為action button顯示,但是開發者不應該用它迫使item用這種方式顯示,在空間狹小的設備上,這會引起布局問題。最好的是使用"ifRoom"。這使得系統可以根據空間做出調整。只有當Item非常重要,關系到關鍵特征的時候,才可以使用"always"。

 

Handling clicks on action items

當用戶按下一個action的時候,系統就會調用activity的onOptionsItemSelected()方法,傳遞進去MenuItem參數,然后可以使用如下代碼進行相應的處理:

 1 @Override
 2 public boolean onOptionsItemSelected(MenuItem item) {
 3     // Handle presses on the action bar items
 4     switch (item.getItemId()) {
 5         case R.id.action_search:
 6             openSearch();
 7             return true;
 8         case R.id.action_compose:
 9             composeMessage();
10             return true;
11         default:
12             return super.onOptionsItemSelected(item);
13     }
14 }

備注:最后之所以返回super.onOptionsItemSelected(item);是因為當action bar是由Fragment創建的時候,按下action bar上的action item就會先調用activity的onOptionsItemSelected(),再去調用Fragment的onOptionsItemSelected()方法,為了讓任何一個fragment的onOptionsItemSelected()始終有機會處理該事件,如果方法不處理該事件,就返回默認行為,而不要返回false;

 

Using split action bar

當屏幕空間狹窄的時候,Split action bar在屏幕底部也提供了一條bar來展示action items。這樣分開action bar有助於利用空間安排合理數量的action item。

為了使用split action bar,我們必須做兩件事情:

1)給每個<activity>或者<application>元素添加屬性uiOptions="splitActionBarWhenNarrow" ,這個屬性只在API Level 14或者更高的API level,舊Level會忽略該屬性;

2)為了支持老版本,需要為每一個<activity>元素添加一個<meta-data>元素,聲明和“android.support.UI_OPTIONS”相同的值;

例子如下:

1 <manifest ...>
2     <activity uiOptions="splitActionBarWhenNarrow" ... >
3         <meta-data android:name="android.support.UI_OPTIONS"
4                    android:value="splitActionBarWhenNarrow" />
5     </activity>
6 </manifest>

使用split action bar也允許在移除icon和title之后,導航Tabs變成主action bar。為了達到這個效果,必須使用方法setDisplayShowHomeEnabled(false)和 setDisplayShowTitleEnabled(false)action bar icon和title失效。

 

Navigating Up with the App Icon

讓app icon在界面的繼承關系之間起導航作用。

備注:這個和系統自帶的返回鍵是不一樣的,返回鍵是為了讓用戶反向瀏覽歷史打開界面的,它依賴於暫時的界面關系,而不是界面的繼承結構。

為了使app icon起到Up button的作用,需要調用setDisplayHomeAsUpEnabled()方法:

1 @Override
2 protected void onCreate(Bundle savedInstanceState) {
3     super.onCreate(savedInstanceState);
4     setContentView(R.layout.activity_details);
5 
6     ActionBar actionBar = getSupportActionBar();
7     actionBar.setDisplayHomeAsUpEnabled(true);
8     ...
9 }

現在icon就開始顯示一個Up補字號,然而此時它不會做任何事情,為了讓它按下的時候出發特定的操作,有以下兩種選擇:

1)在manifest文件中聲明父Activity。

當父Activity總是一樣的時候,這是最佳的選擇,在manifest文件中聲明父Activity,action bar在用戶按下Up button的時候就會自動觸發正確操作。從API 4.1(API Level 16)開始,開發者可以在<activity>中使用parentActivityName屬性進行聲明,為了支持使用support library的老設備,需要一個<meta-data>元素來明確,如下:

 1 <application ... >
 2     ...
 3     <!-- The main/home activity (has no parent activity) -->
 4     <activity
 5         android:name="com.example.myfirstapp.MainActivity" ...>
 6         ...
 7     </activity>
 8     <!-- A child of the main activity -->
 9     <activity
10         android:name="com.example.myfirstapp.DisplayMessageActivity"
11         android:label="@string/title_activity_display_message"
12         android:parentActivityName="com.example.myfirstapp.MainActivity" >
13         <!-- Parent activity meta-data to support API level 7+ -->
14         <meta-data
15             android:name="android.support.PARENT_ACTIVITY"
16             android:value="com.example.myfirstapp.MainActivity" />
17     </activity>
18 </application>

一旦父Activity在manifest文件被明確,導航就被正確建立起來了。

2)或者,你可以在Activity中覆寫方法getSupportParentActivityIntent()和onCreateSupportNavigateUpTaskStack()。

當用戶以不同的方式達到該界面的時候,可能該界面的父Activity就不確定了。這個時候用戶需要按照來時的路徑進行回退導航。(雖然前面說和回退鍵不一樣,但是這里明顯看出,其實是一樣的)。

兩個方法都是在系統在用戶需要導航,按下Up button的時候被調用,不同的是,前者是在同一個Task中的時候,這個時候你就需要返回響應的intent以便於打開合適的父Activity;后者是這個task不屬於本應用,也就是說是外部的應用打開了你的這個界面,這個時候你就需要使用傳進來的TasjStackBuilder構建適合的back stack來供Up button使用。

即使你為你的Activity覆寫了getSupportParentActivityIntent(),你也可以在manifest文件中聲明缺省的父activity,這些缺省的實現就會在缺省的onCreateSupportNavigateUpTaskStack()方法中合成一個回退stack。

備注:如果你使用一系列的fragment而不是activity構建你的app界面樹,上面的做法就沒有一樣會有效。為了導航fragments,需要重寫onSupportNavigateUp()方法來觸發正確的fragment事務——一般來說,就是將當前的fragment從棧中彈出來,也就是調用popBackStack()

 

Adding an Action View

action view是當你按下一個action button的時候出現的action button的替代視圖。action view在不改變activity或者fragment和不替換action bar的情況下提供了對富action的快速訪問。示例圖如下:

開發者可以使用actionLayout或者actionViewClass屬性來明確一個layout或者widegt類來聲明一個action view,例如,為了增加一個SearchView widget:

1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android="http://schemas.android.com/apk/res/android"
3       xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
4     <item android:id="@+id/action_search"
5           android:title="@string/action_search"
6           android:icon="@drawable/ic_action_search"
7           yourapp:showAsAction="ifRoom|collapseActionView"
8           yourapp:actionViewClass="android.support.v7.widget.SearchView" />
9 </menu>

注意到showAsAction屬性也包括"collapseActionView"值,這是可選的,后面會詳細解釋。

如果你需要配置action view(例如需要監聽事件),你可以在onCreateOptionsMenu()回調中實現。你可以通過調用靜態方法MenuItemCompat.getActionView()獲得action view對象,然后將它傳送給響應的MenuItem,舉個例子:

1 @Override
2 public boolean onCreateOptionsMenu(Menu menu) {
3     getMenuInflater().inflate(R.menu.main_activity_actions, menu);
4     MenuItem searchItem = menu.findItem(R.id.action_search);
5     SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
6     // Configure the search info and add any event listeners
7     ...
8     return super.onCreateOptionsMenu(menu);
9 }

 

 Handling collapsible action views

為了節省action bar的空間,你可以將action view壓縮成一個action button。坍縮的時候,系統或許會把action放入action overflow,但是當用戶點擊它的時候,它還是會出現在action bar上面。開發者可以通過在showAsAction屬性中添加值"collapseActionView"讓action view可坍縮,就像上面代碼所展示的。

因為當用戶選擇action的時候系統展開了action view,你就不需要響應其onOptionItemSelected()回調,系統仍會調用這個方法,但是當你返回true(表示你已經處理了這個問題),action view就不會展開了。

系統在你按下回退鍵或者Up按鈕的時候也會坍縮你的action view。

如果你需要根據action view的可見性改變activity的界面,你可以設置一個OnActionExpandListener來監聽,例子如下:

 1 @Override
 2 public boolean onCreateOptionsMenu(Menu menu) {
 3     getMenuInflater().inflate(R.menu.options, menu);
 4     MenuItem menuItem = menu.findItem(R.id.actionItem);
 5     ...
 6 
 7     // When using the support library, the setOnActionExpandListener() method is
 8     // static and accepts the MenuItem object as an argument
 9     MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
10         @Override
11         public boolean onMenuItemActionCollapse(MenuItem item) {
12             // Do something when collapsed
13             return true;  // Return true to collapse action view
14         }
15 
16         @Override
17         public boolean onMenuItemActionExpand(MenuItem item) {
18             // Do something when expanded
19             return true;  // Return true to expand action view
20         }
21     });
22 }

 

 Adding an Action Provider

和action view相類似,action provider也是提供一個替代action button的自定義視圖。然而不同於action view,action provider控制所有的action行為,並且可以在點擊的時候產生一個子menu,示例圖如下:

為了聲明一個action provider,你可以在menu<item>標簽里面為actionViewClass提供一個完整的ActionProvider的名字。

開發者可以通過繼承ActionProvider類來實現自己的action provider,但是Android提供了一些內建的providers比如ShareActionProvider,它可以提供一個可以分享內容的可能的app的列表。

因為ActionProvider類定義自己的action行為,你不需要通過onOptionItemSelected()方法區監聽動作。然而如果有必要,你還是可以在其中監聽click事件,但是一定要返回false以便於action provider能夠收到onPerformDefaultAction()回調來執行實際需要執行的任務。

然而,如果action provider提供了一個action的子menu,那么你的activity在用戶打開列表或者選擇列表的時候就不會調用onOptionItemSelected()。

 

Using the ShareActionProvider

為了使用ShareActionProvider添加一個share action,可以在<item>標簽中用ShareActionProvider定義actionProviderClass的值,如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <menu xmlns:android="http://schemas.android.com/apk/res/android"
 3       xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
 4     <item android:id="@+id/action_share"
 5           android:title="@string/share"
 6           yourapp:showAsAction="ifRoom"
 7           yourapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
 8           />
 9     ...
10 </menu>

現在action provider就控制了action item,處理它的顯示隱藏以及行為。但是你還是得提供一個title給這個action item以便於它在action overflow中顯示。

生下來的唯一要做的事情就是定義你要用來分享的intent。為了這樣做,編輯的onCreateOptionMenu()方法,調用方法MenuItemCompat.getActionProvider(),具體如下:

 1 private ShareActionProvider mShareActionProvider;
 2 
 3 @Override
 4 public boolean onCreateOptionsMenu(Menu menu) {
 5     getMenuInflater().inflate(R.menu.main_activity_actions, menu);
 6 
 7     // Set up ShareActionProvider's default share intent
 8     MenuItem shareItem = menu.findItem(R.id.action_share);
 9     mShareActionProvider = (ShareActionProvider)
10             MenuItemCompat.getActionProvider(shareItem);
11     mShareActionProvider.setShareIntent(getDefaultIntent());
12 
13     return super.onCreateOptionsMenu(menu);
14 }
15 
16 /** Defines a default (dummy) share intent to initialize the action provider.
17   * However, as soon as the actual content to be used in the intent
18   * is known or changes, you must update the share intent by again calling
19   * mShareActionProvider.setShareIntent()
20   */
21 private Intent getDefaultIntent() {
22     Intent intent = new Intent(Intent.ACTION_SEND);
23     intent.setType("image/*");
24     return intent;
25 }

你需要在這個方法里面設置一個默認的intent,但是一旦上下文環境改變,你就需要通過再次調用setShareIntent()方法更新intent。

缺省的,ShareActionProvider會維持一個可以分享內容的列表,根據用戶點擊分享的次數排序,缺省狀態下排序信息是被保存在一個叫做DEFAULT_SHARE_FILE_NAME的私有文件中的,如果你使用的是ShareActionProvider或者它的繼承子類,你就可以使用默認文件,什么都不做,但是假如你使用ShareActionProvider來實現多種動作,俺么就需要自己設置歷史文件,方法是setShareHistoryFileName(),設置一個xml文件的名字。

 

Creating a custom action provider

創建自定義的action provider允許你在一個獨立的模塊中復用和管理動態的行為,而不是在你的fragment或者activity中。就像之前提到的,Android已經為分享行為提供了一個ActionProvider:ShareActionProvider。

為了創建自己的action provider,只需要繼承ActionProvider類,然后合適的實現一些回調方法即可。最重要的是以下幾個方法:

1)ActionProvider()

這個構造方法將APP的Context進來,你需要在這里保存這個變量以便於在其余的回調函數中使用;

2)CreateActionView(MenuItem)

這里是你定義action view的地方,使用從構造方法中獲得的Context實例化一個LayoutInflater,然后從一個xml資源文件中獲得action view布局,然后添加監聽器,例子如下:

 1 public View onCreateActionView(MenuItem forItem) {
 2     // Inflate the action view to be shown on the action bar.
 3     LayoutInflater layoutInflater = LayoutInflater.from(mContext);
 4     View view = layoutInflater.inflate(R.layout.action_provider, null);
 5     ImageButton button = (ImageButton) view.findViewById(R.id.button);
 6     button.setOnClickListener(new View.OnClickListener() {
 7         @Override
 8         public void onClick(View v) {
 9             // Do something...
10         }
11     });
12     return view;
13 }

3)onPerformDefaultAction()

當menu item是在action overflow中被點擊的時候,action provider就會執行一個默認的行為。

然而,如果action provider提供了一個子menu,在調用了onPrepareSubMenu()方法之后,子menu就會顯示,即使這個時候action provider處於action overflow中,這個時候onPerformDefaultAction()。

備注:實現了onOptionsItemSelected()方法的activity和fragment是可以通過return true來屏蔽該事件的,這個時候系統就不會調用onPerformDefaultAction()方法了。

 

Adding Navigation Tabs

action bar上的Tabs讓用戶更容易發現和切換應用界面。action bar提供的tabs可以適應不同的屏幕尺寸,因而非常理想。系統會根據屏幕的尺寸做出最合適的布局。

我們需要提供一個可以放置Fragment的ViewGroup。確保ViewGroup有一個資源ID以便於你可以在代碼中引用和切換tabs的時候容納對應的fragment。如果你的tab填充了整個屏幕,那你的activity就不需要布局文件了。

一旦你決定好了怎么在布局中顯示你的fragments,那么基本的添加tab的流程就是:

1)實現ActionBar.TabListener接口。這個接口為tab事件提供了回調接口,比如當用戶按下某個tab的時候你得切換過去;

2)對於每一個你要添加的tab,初始化一個ActionBar.Tab然后為它添加ActionBar.Listener,然后要設置tab的title(也可以設置它的icon);

3)然后調用方法addTab()往action bar上面添加tab;

注意到ActionBar.TabListener回調函數並沒有寫明到底是哪一個fragment被關聯到tab,我們需要自己定義它們之間的聯系,也就是說,當用戶點擊一個tab的時候,到底是顯示哪一個tab。下面是一個實例化TabListener的例子:

 1 public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
 2     private Fragment mFragment;
 3     private final Activity mActivity;
 4     private final String mTag;
 5     private final Class<T> mClass;
 6 
 7     /** Constructor used each time a new tab is created.
 8       * @param activity  The host Activity, used to instantiate the fragment
 9       * @param tag  The identifier tag for the fragment
10       * @param clz  The fragment's Class, used to instantiate the fragment
11       */
12     public TabListener(Activity activity, String tag, Class<T> clz) {
13         mActivity = activity;
14         mTag = tag;
15         mClass = clz;
16     }
17 
18     /* The following are each of the ActionBar.TabListener callbacks */
19 
20     public void onTabSelected(Tab tab, FragmentTransaction ft) {
21         // Check if the fragment is already initialized
22         if (mFragment == null) {
23             // If not, instantiate and add it to the activity
24             mFragment = Fragment.instantiate(mActivity, mClass.getName());
25             ft.add(android.R.id.content, mFragment, mTag);
26         } else {
27             // If it exists, simply attach it in order to show it
28             ft.attach(mFragment);
29         }
30     }
31 
32     public void onTabUnselected(Tab tab, FragmentTransaction ft) {
33         if (mFragment != null) {
34             // Detach the fragment, because another one is being attached
35             ft.detach(mFragment);
36         }
37     }
38 
39     public void onTabReselected(Tab tab, FragmentTransaction ft) {
40         // User selected the already selected tab. Usually do nothing.
41     }
42 }
View Code

注意:開發者不可以為fragment事務主動調用commit()事件,否則會拋出異常,因為系統會幫你調用,你也不能將這樣的fragment事務壓進棧中。

在這個例子中,當用戶選擇到這個Tab的時候,就先檢測Fragment是不是Null,是的話就去實例化,添加進ft,否則直接attach,取消選擇的時候則直接調用detach。

現在要做的就是創建一個ActionBar.Tab,並且把監聽器加上去。另外,你必須調用方法setNavigationMode(NAVIGATION_MODE_TABS)來使得tabs可見。

舉例如下,下面的代碼使用上面的listener添加了兩個tabs:

 1 @Override
 2 protected void onCreate(Bundle savedInstanceState) {
 3     super.onCreate(savedInstanceState);
 4     // Notice that setContentView() is not used, because we use the root
 5     // android.R.id.content as the container for each fragment
 6 
 7     // setup action bar for tabs
 8     ActionBar actionBar = getSupportActionBar();
 9     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
10     actionBar.setDisplayShowTitleEnabled(false);
11 
12     Tab tab = actionBar.newTab()
13                        .setText(R.string.artist)
14                        .setTabListener(new TabListener<ArtistFragment>(
15                                this, "artist", ArtistFragment.class));
16     actionBar.addTab(tab);
17 
18     tab = actionBar.newTab()
19                    .setText(R.string.album)
20                    .setTabListener(new TabListener<AlbumFragment>(
21                            this, "album", AlbumFragment.class));
22     actionBar.addTab(tab);
23 }
View Code

如果你的activity停止了,你需要在saved instance state中保存當前選中的tab,以便於重新打開的時候可以跳到正確的tab上去,你可以使用方法getSelectedNavigationIndex()方法獲得當前選中的tab的index來進行保存。

注意:保存Fragment的狀態是非常重要的,這樣當用戶切換tab之后又回來,就可以恢復到離開之前的樣子,有些狀態是默認保存的,但是你或許會需要手動保存一些自定的view。

備注:上面實現ActionBar.TabListener是可能的技術之一。另外一個流行的方法是使用ViewPager,這樣用戶就可以通過滑動手勢切換tab。

 

Adding Drop-down Navigation

作為activity的一種導航模式,action bar提供了一個內建的下拉列表,舉個例子,下拉列表可以提供閱覽內容的不同排序依據。

當改變閱覽內容是重要的但是不經常發生的動作的時候,使用下拉列表是非常有用的。如果非常頻繁,這個時候就應該使用導航tab。

使用下拉列表的基本步驟是:

1)創建一個SpinnerAdapter來為下拉列表提供可選擇的item;

2)實現ActionBar.OnNavigationListener來定義當用戶點擊下拉列表框的item的時候的行為;

3)在activity的onCreate()方法中,使用setNavigationMode(NAVIGATION_MODE_LIST)來激活action bar的下拉列表;

4)為下拉列表設置參數,方法如下:

1 actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);

這個方法使用你的SpinnerAdapter和你的OnNavigationListener;

這個流程相對而言是簡單的,主要的工作在於實現SpinnerAdapter和ActionBar.OnNavigationListener。

 

Styling the Action Bar

 如果你想實現一個具有產品特色的視覺設計,action bar是允許你定制顯示細節的,包括action bar的顏色,字體顏色,按鈕風格等等,這就需要你運用Android的style和theme框架來重新設計action bar的特定風格屬性。

注意:請確定你所提供的任何背景圖片都是.9圖以便於拉伸,.9圖需要≤40dp高,30dp寬

例子如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3     <!-- the theme applied to the application or activity -->
 4     <style name="CustomActionBarTheme"
 5            parent="@style/Theme.AppCompat.Light">
 6         <item name="android:actionBarStyle">@style/MyActionBar</item>
 7         <item name="android:actionBarTabTextStyle">@style/TabTextStyle</item>
 8         <item name="android:actionMenuTextColor">@color/actionbar_text</item>
 9 
10         <!-- Support library compatibility -->
11         <item name="actionBarStyle">@style/MyActionBar</item>
12         <item name="actionBarTabTextStyle">@style/TabTextStyle</item>
13         <item name="actionMenuTextColor">@color/actionbar_text</item>
14     </style>
15 
16     <!-- general styles for the action bar -->
17     <style name="MyActionBar"
18            parent="@style/Widget.AppCompat.ActionBar">
19         <item name="android:titleTextStyle">@style/TitleTextStyle</item>
20         <item name="android:background">@drawable/actionbar_background</item>
21         <item name="android:backgroundStacked">@drawable/actionbar_background</item>
22         <item name="android:backgroundSplit">@drawable/actionbar_background</item>
23 
24         <!-- Support library compatibility -->
25         <item name="titleTextStyle">@style/TitleTextStyle</item>
26         <item name="background">@drawable/actionbar_background</item>
27         <item name="backgroundStacked">@drawable/actionbar_background</item>
28         <item name="backgroundSplit">@drawable/actionbar_background</item>
29     </style>
30 
31     <!-- action bar title text -->
32     <style name="TitleTextStyle"
33            parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
34         <item name="android:textColor">@color/actionbar_text</item>
35     </style>
36 
37     <!-- action bar tab text -->
38     <style name="TabTextStyle"
39            parent="@style/Widget.AppCompat.ActionBar.TabText">
40         <item name="android:textColor">@color/actionbar_text</item>
41     </style>
42 </resources>
View Code

然后你可以在你的manifest文件中,將這些主題應用於整個app,方式如下:

1 <application android:theme="@style/CustomActionBarTheme" ... />

或者應用於單個的activity:

1 <activity android:theme="@style/CustomActionBarTheme" ... />

注意:任何一個theme和style都要在<style>標簽中聲明一個父theme,這樣就可以獲得一些你沒有設置的參數的默認值。

 

PS:真是一篇超級冗長的Document,可以實踐的實在太多了,我打算親自試試~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM