擴展用戶體驗之操做欄ActionBar

1、什麼是ActionBarhtml

  熟悉Android的人應該很清楚ActionBar指的是哪一部分,不熟悉的人並不清楚其的重要性,特別是Web app與Hybrid app開發者基本沒有這一律念,固然在大家平時的開發中也用到了相似於ActionBar功能的佈局部分,只是實現當時不一樣而已,一個使用Java實現,一個使用html來佈局。android

  那到底什麼是ActionBar呢?每一個App的不一樣界面中都有一個相同的部分,這部分UI通常在一個App中是一致的,這部分就是導航欄,導航欄中通常有返回導航菜單,應用圖標,產品徽標,當前上下文標題,快捷菜單,以及Tab,例以下圖中就是具備返回導航與上下文標題的操做欄(ActionBar)app

 

2、Android中配置是否引入ActionBaride

  ActionBar並非每一個Activity具備的,有的應用中就看不到這樣的操做欄,例如HyBrid app中整個都沒有ActionBar,可是有的App中又是用這樣的操做欄,這是如何配置的呢?這與Activity的主題有關,例如使用NoActionBar的主題或者使用具備佈局

<item name="android:windowActionBar">false</item>

屬性的主題style時,該Activity就不存在ActionBar,這個不存在並不表示不顯示,而是沒有該實例,即經過mcontext.getActionBar()獲取到的是null,相反的,若是要使用ActionBar,那麼就不能設置Activity的主題具備該屬性。動畫

 

3、靜態ActionBarthis

  靜態ActionBar是指不可操做的ActionBar,就是顯示給用戶「看」的部分,而不是點的部分。spa

  其中包括:圖標、徽標、標題、二級標題code

    圖標:經過Activity註冊時的android:icon設置或者經過getActionBar().setIcon()設置htm

    徽標:經過Activity註冊時的android:logo設置或者經過getActionBar().setLogo()設置

    標題:經過Activity註冊時的android:label設置或者經過getActionBar().setTitle()設置

    二級標題:經過getActionBar().setSubTitle()設置

  圖標與徽標的區別:

    他們二者都是一個圖片,顯示的位置都是在標題的左側,也就是最左側,可是二者只能有一個顯示,沒法同時顯示,圖標表示的應用程序快捷圖標,徽標一般是應用或者企業的品牌,顯示徽標的時候一般不會再顯示標題,即通常的顯示組合是:圖標+標題||徽標;圖標是大小固定的正方形,沒法改變,而徽標的寬度是不固定的,一般狀況下控制徽標的寬度爲圖標的2倍。

  顯示與隱藏:

    ActionBar的顯示:getActionBar().show();

    ActionBar的隱藏:getActionBar().hide();

    標題的顯示與隱藏:getActionBar().setDisplayShowTitleEnable(true|false);

    圖標與徽標的顯示切換:若是二者都有,則默認顯示徽標,當二者都有又想顯示圖標是:getActionBar().setDisplayUseLogoEnable(false);

    圖標與徽標同時隱藏:getActionBar().setDisplayShowHomeEnable(false);

 

4、動態ActionBar

  動態ActionBar表示用戶可以「點」的操做欄。

  ActionBar中通常至少有一個返回上一級的按紐,有的甚至還有下拉菜單按紐,Tab等快捷菜單。

  讓靜態的ActionBar動起來:

getActionBar().setHomeButtonEnabled(true);

  一行代碼可以讓ActionBar中左側圖標、徽標、標題部分可以點擊,固然若是設置

getActionBar().setDisplayHomeAsUpEnabled(true);

  這樣就會在最左邊添加一個返回箭頭,其左側點擊ActionBar內部會廣播一個事件,觸發Activity中的onOptionsItemSelected事件,在該事件中判斷item的id,來執行相應操做,由於其餘的快捷菜單按鈕也會觸發該事件

  實現點擊返回上一級Activity的代碼實例:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.t_act);
        getActionBar().setHomeButtonEnabled(true);
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       switch(item.getItemId()){
           case android.R.id.home:
               finish();
               return true;
           default:
               return super.onOptionsItemSelected(item);
       }
    }

  另外一種簡單的方式是在Activity註冊的時候指定其父Activity:android:parentActivityName="",那麼就不須要重寫onOptionsItemSelected方法就能夠實現點擊返回父Activity了,建議使用第一種,由於第二種返回的動畫與打開新Activity動畫同樣,同時不利於Activity多處複用,若是一個Activity可能存在多個父Activity,這樣就沒辦法了,並且,返回按鈕通常不只僅只是執行返回操做,有時須要關閉一些view或對話框形式Activity,等關閉這些以後再點擊才關閉當前Activity。

  返回按鈕圖片自定義方法

    方法一:該方法可能較低版本的Android API不支持

getActionBar().setHomeAsUpIndicator(R.drawable.back6);

    方法二:在樣式中配置,全部都支持

<item name="android:homeAsUpIndicator">@drawable/back6</item>

 

  導航Tab鍵的使用

    配置導航Tab顯示:getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    一般顯示Tab的時候也是禁用標題的,而Tab的添加須要先建立Tab,而後像actionbar中addTab(tab);

    建立Tab:ActionBar.Tab tab=getActionBar().newTab().setTitle("").setIcon().setTabListener(new ActionBar.TabListener(){...});

         必須指定TabListener,不然會報錯,一般在TabListener中執行切換Fragment操做,業務邏輯是判斷對應的fragment是否存在,若是存在(即在指定  Activity中可以查詢到Fragment)就直接經過attach顯示,不然就先添加add該Fragment,在打開其餘tab 的時候該Listener執行detach操做

    基本工做流程是:初始化、配置新的Fragment,而後在onTabSelected處理程序將此Fragment添加到佈局。在Tab未選中時,它關聯的Fragment應從佈局中分離,當其Tab被從新選中時,該Fragment應該被回收利用

          

        ActionBar.Tab tab1=getActionBar().newTab().setText("Tab2").setTabListener(new ActionBar.TabListener() {
            private Fragment fragment;
            @Override
            public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
                if(fragment==null){
                    fragment=new ffFragment();
                    ft.add(R.id.container,fragment,null);
                }else{
                    ft.attach(fragment);
                }
            }

            @Override
            public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
                if(fragment!=null){
                    ft.detach(fragment);
                }
            }

            @Override
            public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
                
            }
        });

    顯示效果:發現Tab 會與ActionBar分爲兩行顯示,這是由於設備寬度不夠,在Pad中就會一行顯示,固然也能夠強制顯示一行或兩行:

      顯示一行:

        try {
            Method setHasEmbeddedTabsMethod = getActionBar().getClass().getDeclaredMethod(
                    "setHasEmbeddedTabs", boolean.class);
            setHasEmbeddedTabsMethod.setAccessible(true);
            setHasEmbeddedTabsMethod.invoke(getActionBar(), true);
        } catch (Exception ignore) {
        }

      顯示兩行

        try {
            Method setHasEmbeddedTabsMethod = getActionBar().getClass().getDeclaredMethod(
                    "setHasEmbeddedTabs", boolean.class);
            setHasEmbeddedTabsMethod.setAccessible(true);
            setHasEmbeddedTabsMethod.invoke(getActionBar(), false);
        } catch (Exception ignore) {
        }

    顯示成一行時Tab是基於左對齊的,也就是並非在中間的,若是想要在中間顯示,須要經過自定義view的形式來建立自定義ActionBar實現

 

  下拉列表導航實現:

    配置下拉列表導航顯示:getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

    下拉列表導航Spinner同樣,都是經過adapter來設置的,能夠自定義複雜的adapter,而後經過setListNavigationCallbacks方法配置adapter

        getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        ArrayList<String> arrayList=new ArrayList<>();
        arrayList.add("aaa");
        arrayList.add("bbb");
        ArrayAdapter arrayAdapter=new ArrayAdapter(TAct.this,android.R.layout.simple_list_item_1,arrayList);
        getActionBar().setListNavigationCallbacks(arrayAdapter, new ActionBar.OnNavigationListener() {
            @Override
            public boolean onNavigationItemSelected(int itemPosition, long itemId) {
                return false;
            }
        });

    顯示效果也與Spinner相似,不太美觀,更好的體驗須要自定義實現

 

5、自定義導航View

  在Tab與下拉都不適合的狀況下,操做欄容許使用setCustomView方法添加自定義View(包括佈局)

  getActionBar().setDisplayShowCustomEnabled(true);

  getActionBar().setCustomView(R.layout.);

  自定義View會出現同Tab和下拉列表同樣的位置,在應用程序圖標右側,但在任意操做的左側

  能實現的效果:居中Tab與標題等

 

6、右側任意操做欄

   應用中菜單分類:

    一、圖標菜單:在3.0之前經常使用的點擊menu按鈕觸發的菜單界面,具備圖標和文本的菜單,通常只顯示6個,超過6個最後一個會變成more,點擊more會顯示其他的菜單,3.0之後不建議使用,被操做欄操做代替,不能顯示覆選框、單選按鈕或者快捷鍵

    二、操做欄操做:同圖標菜單同樣,能夠顯示圖標,也可選擇性的顯示文本,按照原定,圖標都是單色的,不能顯示覆選框、單選按鈕或者快捷鍵

    三、展開菜單:在3.0之前點擊圖標菜單中的more時就會觸發展開菜單,展開菜單顯示一個在圖標菜單中不可見的菜單的滾動列表

    四、溢出菜單:3.0之後展開菜單被溢出菜單代替,溢出菜單包含未標識爲操做欄操做的菜單項及操做欄缺乏控件而溢出的菜單項

    五、子菜單:Android中子菜單不能像Web中那樣呈現樹狀結構,而是一個點擊彈出浮動菜單對話框的操做

  如何建立菜單:

    給Activity添加一個菜單須要重寫onCreateOptionsMenu處理程序,在3.0之前當Activity第一次顯示菜單的時候會觸發該處理程序,3.0之後在Activity完成佈局開始建立操做欄的時候觸發該處理程序

    其中須要的操是:一:調用父類實現,可能額外包含系統菜單選項,若是徹底自定義菜單則能夠不調用

            二:分組

            三:菜單id

            四:排序方式

            五:add菜單返回MenuItem引用(保留當前引用有用)

            六:return true;

    若是想要將菜單指定到操做欄操做中能夠經過setShowAsActionFlags方法設置:SHOW_AS_ACTION,強制一個菜單項一直做爲操做顯示;SHOW_AS_IF_SPACE,當操做欄有足夠空間時,會顯示指定菜單

    默認的,操做欄中的菜單隻顯示圖標,能夠選擇SHOW_AS_ACTION_WITH_TEXT與前兩個標誌作OR操做來同時顯示文本

  菜單佈局:

    菜單中能夠包括圖標、快捷方式、複選框、單選按鈕、文本

    複選框:經過setCheckable(true)方法將MenuItem變成帶複選框的菜單

    單選按鈕組:針對一組菜單進行的,經過menu.setGroupCheckable(groupId,true,true);設置

    快捷鍵:使用menuItem的setShortcut方法設置,須要設置兩個鍵盤快捷鍵,一個數數字鍵盤,一個是全鍵盤

    扼要標題:setTitleCondensed(),能夠設置在圖標菜單或操做欄操做中顯示的標題,不一樣標題只在溢出菜單或者展開菜單中顯示

    圖標:menuItem.setIcon();設置圖標,圖標只能在圖標菜單或者做爲一個操做顯示,溢出菜單中是不顯示圖標的

    處理點擊事件:setOnMenuItemClickListener,出於效率緣由不建議單個設置,建議使用Activity的onOptionsItemSelected處理程序處理

    Intent:若是某個菜單點擊操做沒有被MenuItemClick處理,也沒有被onOptionsItemSelected處理,那麼就會調用startActivity(intent);

        經過setIntent()方法設置菜單執行Intent

相關文章
相關標籤/搜索