【Android】Android之Action Bar

Action Bar是在窗口上指示用户位置的组件,同时给用户提供导航和操做。使用Action Bar可让你的应用在不一样配置的屏幕上看起来比较一致。在开始以前,先了解一些相关的术语:android

Action Bar有如下几项关键功能:app

1)为你的App提供一个装饰处,同时也可让用户知道本身的所在位置;框架

2)让一些重要的操做以一种可预见的方式变得突出而且可访问(好比搜索);ide

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。ui

 

Adding the Action Barthis

注意,这里讲述的是如何使用Support Library中的Action Bar。spa

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,能够实践的实在太多了,我打算亲自试试~~

相关文章
相关标签/搜索