【Android Trick 4】ActionBar操作大全

本例几乎涵盖了有关Actionbar的所有操作,由于前面介绍过tabs和item,这里重点介绍Actionbar的样式修改,需要源工程的请在资源里下载styleactionbar。更多请阅读http://android-developers.blogspot.com/2011/04/customizing-action-bar.html

1、首先准备一个RoundedColourFragment,前面介绍过各部分的作用,这里就不赘述。

view plain
  1. import android.app.Fragment;  
  2. import android.graphics.drawable.GradientDrawable;  
  3. import android.os.Bundle;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.view.ViewGroup.LayoutParams;  
  8. import android.widget.LinearLayout;  
  9.   
  10. public class RoundedColourFragment extends Fragment {  
  11.   
  12.     private View mView;  
  13.     private int mColour;  
  14.     private float mWeight;  
  15.     private int marginLeft, marginRight, marginTop, marginBottom;  
  16.   
  17.     // need a public empty constructor for framework to instantiate  
  18.     public RoundedColourFragment() {  
  19.           
  20.     }  
  21.       
  22.     public RoundedColourFragment(int colour, float weight, int margin_left,  
  23.             int margin_right, int margin_top, int margin_bottom) {  
  24.         mColour = colour;  
  25.         mWeight = weight;  
  26.         marginLeft = margin_left;  
  27.         marginRight = margin_right;  
  28.         marginTop = margin_top;  
  29.         marginBottom = margin_bottom;  
  30.     }  
  31.   
  32.     @Override  
  33.     public void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         mView = new View(getActivity());  
  36.   
  37.         GradientDrawable background = (GradientDrawable) getResources()  
  38.                 .getDrawable(R.drawable.rounded_rect);  
  39.         background.setColor(mColour);  
  40.   
  41.         mView.setBackgroundDrawable(background);  
  42.         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0,  
  43.                 LayoutParams.FILL_PARENT, mWeight);  
  44.         lp.setMargins(marginLeft, marginTop, marginRight, marginBottom);  
  45.         mView.setLayoutParams(lp);  
  46.     }  
  47.   
  48.     @Override  
  49.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  50.             Bundle savedInstanceState) {  
  51.         return mView;  
  52.     }  
  53.   
  54. }  


2、MainActivity.java文件,主要是创建tabs、item、drop down navigation等,以及他们之间相互转换的控制逻辑,一部分内容前面也介绍过。

view plain
  1. import android.animation.ObjectAnimator;  
  2. import android.app.ActionBar;  
  3. import android.app.Activity;  
  4. import android.app.FragmentTransaction;  
  5. import android.app.ActionBar.OnNavigationListener;  
  6. import android.os.Bundle;  
  7. import android.os.Handler;  
  8. import android.view.Menu;  
  9. import android.view.MenuItem;  
  10. import android.view.MenuItem.OnMenuItemClickListener;  
  11. import android.widget.ArrayAdapter;  
  12.   
  13. public class MainActivity extends Activity implements ActionBar.TabListener {  
  14.   
  15.     private final Handler handler = new Handler();  
  16.     private RoundedColourFragment leftFrag;  
  17.     private RoundedColourFragment rightFrag;  
  18.     private boolean useLogo = false;  
  19.     private boolean showHomeUp = false;  
  20.   
  21.     /** Called when the activity is first created. */  
  22.     @Override  
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.main);  
  26.         final ActionBar ab = getActionBar();  
  27.   
  28.         // set defaults for logo & home up  
  29.         ab.setDisplayHomeAsUpEnabled(showHomeUp);  
  30.         ab.setDisplayUseLogoEnabled(useLogo);  
  31.   
  32.         // set up tabs nav  
  33.         for (int i = 1; i < 4; i++) {  
  34.             ab.addTab(ab.newTab().setText("Tab " + i).setTabListener(this));  
  35.         }  
  36.   
  37.         // set up list nav  
  38.         ab.setListNavigationCallbacks(ArrayAdapter  
  39.                 .createFromResource(this, R.array.sections,  
  40.                         android.R.layout.simple_spinner_dropdown_item),  
  41.                 new OnNavigationListener() {  
  42.                     public boolean onNavigationItemSelected(int itemPosition,  
  43.                             long itemId) {  
  44.                         // FIXME add proper implementation  
  45.                         rotateLeftFrag();  
  46.                         return false;  
  47.                     }  
  48.                 });  
  49.   
  50.         // default to tab navigation  
  51.         showTabsNav();  
  52.   
  53.         // create a couple of simple fragments as placeholders  
  54.         final int MARGIN = 16;  
  55.         leftFrag = new RoundedColourFragment(getResources().getColor(  
  56.                 R.color.android_green), 1f, MARGIN, MARGIN / 2, MARGIN, MARGIN);  
  57.         rightFrag = new RoundedColourFragment(getResources().getColor(  
  58.                 R.color.honeycombish_blue), 2f, MARGIN / 2, MARGIN, MARGIN,  
  59.                 MARGIN);  
  60.   
  61.         FragmentTransaction ft = getFragmentManager().beginTransaction();  
  62.         ft.add(R.id.root, leftFrag);  
  63.         ft.add(R.id.root, rightFrag);  
  64.         ft.commit();  
  65.     }  
  66.   
  67.     @Override  
  68.     public boolean onCreateOptionsMenu(Menu menu) {  
  69.         getMenuInflater().inflate(R.menu.main_menu, menu);  
  70.   
  71.         // set up a listener for the refresh item  
  72.         final MenuItem refresh = (MenuItem) menu.findItem(R.id.menu_refresh);  
  73.         refresh.setOnMenuItemClickListener(new OnMenuItemClickListener() {  
  74.             // on selecting show progress spinner for 1s  
  75.             public boolean onMenuItemClick(MenuItem item) {  
  76.                 // item.setActionView(R.layout.progress_action);  
  77.                 handler.postDelayed(new Runnable() {  
  78.                     public void run() {  
  79.                         refresh.setActionView(null);  
  80.                     }  
  81.                 }, 1000);  
  82.                 return false;  
  83.             }  
  84.         });  
  85.         return super.onCreateOptionsMenu(menu);  
  86.     }  
  87.   
  88.     @Override  
  89.     public boolean onOptionsItemSelected(MenuItem item) {  
  90.         switch (item.getItemId()) {  
  91.         case android.R.id.home:  
  92.             // TODO handle clicking the app icon/logo  
  93.             return false;  
  94.         case R.id.menu_refresh:  
  95.             // switch to a progress animation  
  96.             item.setActionView(R.layout.indeterminate_progress_action);  
  97.             return true;  
  98.         case R.id.menu_both:  
  99.             // rotation animation of green fragment  
  100.             rotateLeftFrag();  
  101.             return true;  
  102.         case R.id.menu_text:  
  103.             // alpha animation of blue fragment  
  104.             ObjectAnimator alpha = ObjectAnimator.ofFloat(rightFrag.getView(),  
  105.                     "alpha", 1f, 0f);  
  106.             alpha.setRepeatMode(ObjectAnimator.REVERSE);  
  107.             alpha.setRepeatCount(1);  
  108.             alpha.setDuration(800);  
  109.             alpha.start();  
  110.             return true;  
  111.         case R.id.menu_logo:  
  112.             useLogo = !useLogo;  
  113.             item.setChecked(useLogo);  
  114.             getActionBar().setDisplayUseLogoEnabled(useLogo);  
  115.             return true;  
  116.         case R.id.menu_up:  
  117.             showHomeUp = !showHomeUp;  
  118.             item.setChecked(showHomeUp);  
  119.             getActionBar().setDisplayHomeAsUpEnabled(showHomeUp);  
  120.             return true;  
  121.         case R.id.menu_nav_tabs:  
  122.             item.setChecked(true);  
  123.             showTabsNav();  
  124.             return true;  
  125.         case R.id.menu_nav_label:  
  126.             item.setChecked(true);  
  127.             showStandardNav();  
  128.             return true;  
  129.         case R.id.menu_nav_drop_down:  
  130.             item.setChecked(true);  
  131.             showDropDownNav();  
  132.             return true;  
  133.         case R.id.menu_bak_none:  
  134.             item.setChecked(true);  
  135.             getActionBar().setBackgroundDrawable(null);  
  136.             return true;  
  137.         case R.id.menu_bak_gradient:  
  138.             item.setChecked(true);  
  139.             getActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.ad_action_bar_gradient_bak));  
  140.             return true;  
  141.         default:  
  142.             return super.onOptionsItemSelected(item);  
  143.         }  
  144.     }  
  145.   
  146.     private void rotateLeftFrag() {  
  147.         if (leftFrag != null) {  
  148.             ObjectAnimator.ofFloat(leftFrag.getView(), "rotationY"0180)  
  149.                     .setDuration(500).start();  
  150.         }  
  151.     }  
  152.   
  153.     private void showStandardNav() {  
  154.         ActionBar ab = getActionBar();  
  155.         if (ab.getNavigationMode() != ActionBar.NAVIGATION_MODE_STANDARD) {  
  156.             ab.setDisplayShowTitleEnabled(true);  
  157.             ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);  
  158.         }  
  159.     }  
  160.   
  161.     private void showDropDownNav() {  
  162.         ActionBar ab = getActionBar();  
  163.         if (ab.getNavigationMode() != ActionBar.NAVIGATION_MODE_LIST) {  
  164.             ab.setDisplayShowTitleEnabled(false);  
  165.             ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);  
  166.         }  
  167.     }  
  168.   
  169.     private void showTabsNav() {  
  170.         ActionBar ab = getActionBar();  
  171.         if (ab.getNavigationMode() != ActionBar.NAVIGATION_MODE_TABS) {  
  172.             ab.setDisplayShowTitleEnabled(false);  
  173.             ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
  174.         }  
  175.     }  
  176.   
  177.     public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {  
  178.         // FIXME add a proper implementation, for now just rotate the left  
  179.         // fragment  
  180.         rotateLeftFrag();  
  181.     }  
  182.   
  183.     public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {  
  184.         // FIXME implement this  
  185.     }  
  186.   
  187.     public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {  
  188.         // FIXME implement this  
  189.     }  
  190.   
  191. }  


3、在res/values下的styles.xml文件,这里是本程序讲解的核心,也是actionbar样式转换的核心,java代码如下:

view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <!-- Base application theme is the default theme. -->  
  5.     <style name="Theme" parent="android:Theme"></style>  
  6.   
  7.     <!-- Variation on the Holo Light theme that styles the Action Bar -->  
  8.     <!-- style的名字是Theme.AndroidDevelopers,父类为Theme.Holo.Light,即白底黑字(如果是Theme.Holo,则为黑底白字)-->  
  9.     <style name="Theme.AndroidDevelopers" parent="android:style/Theme.Holo.Light">  
  10.         <!-- 这是items的颜色变化,未选中时为白色,选中时为绿色,逻辑请见ad_selectable_background.xml -->  
  11.         <item name="android:selectableItemBackground">@drawable/ad_selectable_background</item>  
  12.         <!-- 其他部分的颜色变化跟上面类似 -->  
  13.         <item name="android:popupMenuStyle">@style/MyPopupMenu</item>  
  14.         <item name="android:dropDownListViewStyle">@style/MyDropDownListView</item>  
  15.         <item name="android:actionBarTabStyle">@style/MyActionBarTabStyle</item>  
  16.         <item name="android:actionDropDownStyle">@style/MyDropDownNav</item>  
  17.         <item name="android:listChoiceIndicatorMultiple">@drawable/ad_btn_check_holo_light</item>  
  18.         <item name="android:listChoiceIndicatorSingle">@drawable/ad_btn_radio_holo_light</item>  
  19.         <!--<item name="android:actionOverflowButtonStyle">@style/MyOverflowButton</item>-->  
  20.     </style>  
  21.       
  22.     <!-- style the overflow menu -->  
  23.     <style name="MyPopupMenu" parent="android:style/Widget.Holo.Light.ListPopupWindow">  
  24.         <item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>   
  25.     </style>  
  26.       
  27.     <!-- style the items within the overflow menu -->  
  28.     <style name="MyDropDownListView" parent="android:style/Widget.Holo.ListView.DropDown">  
  29.         <item name="android:listSelector">@drawable/ad_selectable_background</item>  
  30.     </style>  
  31.   
  32.     <!-- style for the tabs -->  
  33.     <style name="MyActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBarView_TabView">  
  34.         <item name="android:background">@drawable/actionbar_tab_bg</item>  
  35.         <item name="android:paddingLeft">32dp</item>  
  36.         <item name="android:paddingRight">32dp</item>  
  37.     </style>  
  38.       
  39.     <!-- style the list navigation -->  
  40.     <style name="MyDropDownNav" parent="android:style/Widget.Holo.Light.Spinner.DropDown.ActionBar">  
  41.         <item name="android:background">@drawable/ad_spinner_background_holo_light</item>  
  42.         <item name="android:popupBackground">@drawable/ad_menu_dropdown_panel_holo_light</item>  
  43.         <item name="android:dropDownSelector">@drawable/ad_selectable_background</item>  
  44.     </style>  
  45.   
  46.     <!-- the following can be used to style the overflow menu button  
  47.          only do this if you have an *extremely* good reason to!! -->  
  48.     <!--<style name="MyOverflowButton" parent="@android:style/Widget.Holo.ActionButton.Overflow">  
  49.         <item name="android:src">@android:drawable/ic_menu_view</item>  
  50.         <item name="android:background">@drawable/action_button_background</item>  
  51.     </style>-->  
  52.   
  53. </resources>  

      把style设置好后,只需在AndroidManifest.xml中application或activity的位置加上<activity android:name=".MainActivity"  android:theme="@style/Theme.AndroidDevelopers"&gt;即可,作用于一个应用程序或者一个activity。

      细心的读者可能会发现,其实以前android的属性拿过来都能用,比如说修改actionbar的高度,<android:height=…>,只需把这些属性放在对应的位置,作为一个<item>存在即可。

4、res/drawable下的一些xml文件,即actionbar修改所需的资源。

4、1------actionbar_tab_bg.xml,用于tab的背景修改。曾一度认为只需在系统tab的基础上修改一下颜色即可,其实不然。需另外弄几张图片,(如我想把tab改成红色背景,那么我就要找几张红色背景的图片)。

view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/ad_tab_unselected_holo" />  
  5.     <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/ad_tab_selected_holo" />  
  6.     <item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />  
  7.     <item android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/ad_tab_selected_pressed_holo" />  
  8.   
  9. </selector>  

4、2------ad_action_bar_gradient_bak.xml,用于actionbar的颜色渐变,本例是从顶到底颜色逐渐变浅。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">  
  3.     <gradient  
  4.         android:startColor="@color/honeycombish_blue"  
  5.         android:endColor="@color/background"  
  6.         android:type="linear"  
  7.         android:angle="270" />  
  8. </shape>  
4、3------ad_btn_check_holo_light.xml,用于单选背景的变换。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <!-- Enabled states -->  
  5.     <item android:state_checked="true" android:state_window_focused="false"  
  6.         android:state_enabled="true" android:drawable="@drawable/btn_check_on_holo_light" />  
  7.       
  8.     <item android:state_checked="false" android:state_window_focused="false"  
  9.         android:state_enabled="true" android:drawable="@drawable/btn_check_off_holo_light" />  
  10.       
  11.     <item android:state_checked="true" android:state_pressed="true"  
  12.         android:state_enabled="true" android:drawable="@drawable/ad_btn_check_on_pressed_holo_light" />  
  13.       
  14.     <item android:state_checked="false" android:state_pressed="true"  
  15.         android:state_enabled="true" android:drawable="@drawable/ad_btn_check_off_pressed_holo_light" />  
  16.       
  17.     <!-- ignoring focused states for brevity   
  18.     <item android:state_checked="true" android:state_focused="true"  
  19.         android:state_enabled="true" android:drawable="@drawable/btn_check_on_focused_holo_light" />  
  20.       
  21.     <item android:state_checked="false" android:state_focused="true"  
  22.         android:state_enabled="true" android:drawable="@drawable/btn_check_off_focused_holo_light" />  
  23.     -->  
  24.       
  25.     <item android:state_checked="false" android:state_enabled="true"  
  26.         android:drawable="@drawable/btn_check_off_holo_light" />  
  27.       
  28.     <item android:state_checked="true" android:state_enabled="true"  
  29.         android:drawable="@drawable/btn_check_on_holo_light" />  
  30.       
  31.     <!-- ignoring disabled states for brevity  
  32.     <item android:state_checked="true" android:state_window_focused="false"  
  33.         android:drawable="@drawable/btn_check_on_disabled_holo_light" />  
  34.       
  35.     <item android:state_checked="false" android:state_window_focused="false"  
  36.         android:drawable="@drawable/btn_check_off_disabled_holo_light" />  
  37.       
  38.     <item android:state_checked="true" android:state_focused="true"  
  39.         android:drawable="@drawable/btn_check_on_disabled_focused_holo_light" />  
  40.       
  41.     <item android:state_checked="false" android:state_focused="true"  
  42.         android:drawable="@drawable/btn_check_off_disabled_focused_holo_light" />  
  43.       
  44.     <item android:state_checked="false"  
  45.         android:drawable="@drawable/btn_check_off_disabled_holo_light" />  
  46.       
  47.     <item android:state_checked="true"  
  48.         android:drawable="@drawable/btn_check_on_disabled_holo_light" />  
  49.      -->  
  50.        
  51. </selector>  
4、4------ad_btn_radio_holo_light.xml,用于多选背景的变换。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.     <!-- Enabled states -->  
  5.     <item android:state_checked="true" android:state_window_focused="false"  
  6.         android:state_enabled="true" android:drawable="@drawable/btn_radio_on_holo_light" />  
  7.       
  8.     <item android:state_checked="false" android:state_window_focused="false"  
  9.         android:state_enabled="true" android:drawable="@drawable/btn_radio_off_holo_light" />  
  10.       
  11.     <item android:state_checked="true" android:state_pressed="true"  
  12.         android:state_enabled="true" android:drawable="@drawable/ad_btn_radio_on_pressed_holo_light" />  
  13.       
  14.     <item android:state_checked="false" android:state_pressed="true"  
  15.         android:state_enabled="true" android:drawable="@drawable/ad_btn_radio_off_pressed_holo_light" />  
  16.       
  17.     <!-- ignoring focused states for brevity   
  18.     <item android:state_checked="true" android:state_focused="true"  
  19.         android:state_enabled="true" android:drawable="@drawable/btn_radio_on_focused_holo_light" />  
  20.       
  21.     <item android:state_checked="false" android:state_focused="true"  
  22.         android:state_enabled="true" android:drawable="@drawable/btn_radio_off_focused_holo_light" />  
  23.     -->  
  24.       
  25.     <item android:state_checked="false" android:state_enabled="true"  
  26.         android:drawable="@drawable/btn_radio_off_holo_light" />  
  27.       
  28.     <item android:state_checked="true" android:state_enabled="true"  
  29.         android:drawable="@drawable/btn_radio_on_holo_light" />  
  30.       
  31.     <!-- ignoring disabled states for brevity  
  32.     <item android:state_checked="true" android:state_window_focused="false"  
  33.         android:drawable="@drawable/btn_radio_on_disabled_holo_light" />  
  34.       
  35.     <item android:state_checked="false" android:state_window_focused="false"  
  36.         android:drawable="@drawable/btn_radio_off_disabled_holo_light" />  
  37.       
  38.     <item android:state_checked="true" android:state_focused="true"  
  39.         android:drawable="@drawable/btn_radio_on_disabled_focused_holo_light" />  
  40.       
  41.     <item android:state_checked="false" android:state_focused="true"  
  42.         android:drawable="@drawable/btn_radio_off_disabled_focused_holo_light" />  
  43.       
  44.     <item android:state_checked="false"  
  45.         android:drawable="@drawable/btn_radio_off_disabled_holo_light" />  
  46.       
  47.     <item android:state_checked="true"  
  48.         android:drawable="@drawable/btn_radio_on_disabled_holo_light" />  
  49.     -->  
  50.           
  51. </selector>  
4、5------ad_btn_radio_holo_light.xml,用于item背景的变换,未选中时为透明,选中未绿色。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android"  
  3.           android:exitFadeDuration="@android:integer/config_mediumAnimTime" >  
  4.     <item android:state_pressed="true" android:drawable="@drawable/selected_background" />  
  5.     <item android:drawable="@android:color/transparent" />  
  6. </selector>  
4、6------ad_spinner_background_holo_light.xml,用于下拉列表背景的变换。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:state_enabled="false"  
  4.           android:drawable="@drawable/spinner_disabled_holo_light" />  
  5.     <item android:state_pressed="true"  
  6.           android:drawable="@drawable/ad_spinner_pressed_holo_light" />  
  7.     <item android:state_pressed="false" android:state_focused="true"  
  8.           android:drawable="@drawable/ad_spinner_focused_holo_light" />  
  9.     <item android:drawable="@drawable/spinner_default_holo_light" />  
  10. </selector>  
4、7------rounded_rect.xml,用于本例RoundedColourFragment视图的设置。
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">  
  3.     <corners android:radius="@dimen/frag_rounding_radius" />  
  4. </shape>  
dimens.xml
view plain
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <dimen name="frag_rounding_radius">20dp</dimen>  
  4.     <dimen name="progress_action_padding">8dp</dimen>  
  5. </resources>  

     至此,这个工程的逻辑介绍完毕。言语介绍肯定不会很明白,需要的同行可看源代码,相信各位精英能很快领悟到其中的技术,应用到自己的工程中去,使actionbar具有各自工程的特色。

你可能感兴趣的:(【Android Trick 4】ActionBar操作大全)