天天看點

Android 标題欄(2)

本文來自網易雲社群

作者:孫聖翔

添加ActionProvider

1.在menu菜單中添加app:actionProviderClass屬性:

<item   
 android:id="@+id/plus"  
   android:icon="@drawable/actionbar_plus_icon_normal"  
     android:title="@string/more"    
     app:actionProviderClass="android.support.v7.widget.ShareActionProvider"   
      app:showAsAction="always">
</item>
// 注意 根據是否引用的support包,actionProviderClass設定的類不同,如果是support包則設定為android.support.v7.widget.ShareActionProvider且用app來辨別, 否則設定為android.widget.ShareActionProvider且用android來辨別      

2. 在代碼中設定

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.action_menu, menu);
    MenuItem plus = menu.findItem(R.id.plus);  
      //support包中采用如下方法
    //MenuItemCompat.setActionProvider(plus, new ShareActionProvider(this));
    //非support中直接設定
    //plus.setActionProvider(new ShareActionProvider(this));

    //support包中采用如下方法
    ShareActionProvider provider = (ShareActionProvider) MenuItemCompat.getActionProvider(plus);
    provider.setShareIntent(getShareIntent());    
    //ShareActionProvider provider = plus.getActionProvider();
    return true;
}private Intent getShareIntent() {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("image/*");    
    return intent;
}      

上述就實作了分享的效果,隻是需要注意的是要區分所引用的類是否是support包中的類。類型一定要正确。

自定義provider

如果系統提供的provider不符合要求怎麼辦?我們還可以自定義provider。

public class PlusProvider extends ActionProvider {  
  /**
     * Creates a new instance. ActionProvider classes should always implement a
     * constructor that takes a single Context parameter for inflating from menu XML.
     *
     * @param context Context for accessing resources.
     */
    public PlusProvider(Context context) {     
       super(context);
    }    @Override
    public void onPrepareSubMenu(SubMenu subMenu) {
        subMenu.clear();
        subMenu.add("tab1").setIcon(R.drawable.logo).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {          
          @Override
            public boolean onMenuItemClick(MenuItem item) {         
                   return false;
            }
        });
        subMenu.add("tab2").setIcon(R.drawable.logo).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {          
          @Override
            public boolean onMenuItemClick(MenuItem item) {           
                 return false;
            }
        });
    }    
    @Override
    public View onCreateActionView() {    
        return null;
    }   
     @Override
    public boolean hasSubMenu() {      
      return true;
    }
}      

上面我們自定義了一個加号的provider,hasSubMenu表示十分有子菜單,true表示有,在onPrepareSubMenu中初始化子菜單。子菜單可以設定顯示文字,圖示與響應點選事件。

設定完成後,就與系統提供的provider使用方式一樣。

設定ActionLayout

設定ActionLayout可以用自定義的布局來展示菜單圖示。      

 1.建立一個布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:gravity="right"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.netease.study.ui.title.ActionBarActivity">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/actionbar_setting_icon"/></RelativeLayout>      

布局中包含了一個設定圖示,之後在menu中引用

<item    
android:id="@+id/plus"   
 android:icon="@drawable/actionbar_plus_icon_normal" 
    android:title="@string/more"   
     app:actionLayout="@layout/action_layout"  
      app:showAsAction="always">
</item>      

這樣就把預設的加号圖示給改變成設定圖示,在代碼中也可以調用setActionView來更改圖示。但是不建議這樣做,每一個菜單都做明确的事情。

頁面導航

怎麼開啟頁面導航?在代碼中調用getActionBar(). setDisplayHomeAsUpEnabled(true)就可以開啟頁面導航,如果是support包中需要調用getSupportActionBar(),開啟後,預設頁面左上角會出現傳回箭頭。訓示頁面點選可以傳回。僅僅是開啟頁面導航是不夠的,還需要對他進行處理。

因為傳回箭頭也屬于ActionBar中的ActionView是以處理方式是一樣的,不同是的它的id已經預設指定為android.R.id.home。是以需要在onOptionsItemSelected函數中處理id為android.R.id.home:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   
 switch (item.getItemId()) {       
  case android.R.id.home:
            finish();         
               break;
    }   
     return super.onOptionsItemSelected(item);
}      

左上的箭頭圖示,我們可以在style中設定為自己的圖示,也可以在代碼中調用getActionBar().setHomeAsUpIndicator()來更改圖示。

一般情況下隻需要關閉掉目前界面,是以直接調用finish關閉掉目前頁面。但是這不是傳回箭頭設定的初衷,否則他與軟體的傳回沒有任何的差別,那在什麼情況下需要特殊處理呐?

這裡有一個郵件清單頁面,點選其中一項,打開郵件詳情,在郵件詳情頁可以左右導航到上一封或者下一封郵件,這樣在點選左上箭頭事希望能回到清單頁,而軟鍵盤傳回則傳回上一個頁面。這種情況怎麼處理?

1.首先需要在AndroidManifest頁面中對Activity設定parent屬性:

// 4.1版本之前<activity   
 android:name=".ActionBarActivity">
    <meta-data      
      android:name="android.support.PARENT_ACTIVITY"   
           android:value=".MainActivity">
    </meta-data>
</activity>// 4.1版本之後<activity   
 android:name=".ActionBarActivity"   
  android:parentActivityName=".MainActivity">
</activity>      

2:在代碼中處理對應的邏輯:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   
 switch (item.getItemId()) {        case android.R.id.home:
            Intent intent = NavUtils.getParentActivityIntent(this);      
                 if(intent!=null){
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                NavUtils.navigateUpTo(this, intent);
            }else{
                finish();
            }           
             break;
    }   
     return super.onOptionsItemSelected(item);
}      

這樣就可以直接放回到清單頁,不在傳回上一個界面,與傳回鍵處理是不同的。

設定ActionMode

ActionMode是一種菜單,但是與其他菜單不一樣的是,他占據的位置預設為ActionBar的位置,使用方式如下:

private void findViews() {
    View actionMode = findViewById(R.id.show_menu);  
      assert actionMode != null;
    actionMode.setOnLongClickListener(new View.OnLongClickListener() {    
        @Override
        public boolean onLongClick(View v) {
            ActionBarActivity.this.startActionMode(callback);        
                return true;
        }
    });
}private ActionMode.Callback callback = new ActionMode.Callback() {  
  @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mode.getMenuInflater().inflate(R.menu.action_menu1, menu);   
             return true;
    }   
     @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {     
       return false;
    }   
     @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {      
      return false;
    }   
     @Override
    public void onDestroyActionMode(ActionMode mode) {

    }
};      

我在對一個view進行長按的時候,出現ActionMode菜單。

Toolbar

如果Toolbar不當做ActionBar處理,Toolbar怎麼進行設定與菜單顯示?

private void setToolbar(Toolbar toolbar) {   
 //setSupportActionBar(toolbar);
    toolbar.setTitle("主标題");
    toolbar.setSubtitle("副标題");
    toolbar.setLogo(R.drawable.logo);
    toolbar.inflateMenu(R.menu.action_menu);
    toolbar.setOnMenuItemClickListener(new toolbar.OnMenuItemClickListener() {     
       @Override
        public boolean onMenuItemClick(MenuItem item) {           
         return false;
        }
    });
}      

上面示範了當不做為ActionBar時,Toolbar怎麼進行設定,主要是菜單的加載方式變化。Toolbar還可以與CollapsingToolbarLayout,AppBarLayout實作不一樣的标題效果。

總結

這裡主要是對ActionBar和Toolbar的使用進行了梳理,其實還有怎麼對他們進行主題配置,這裡就不在展開了。

Android标題欄(一)](http://blog.csdn.net/xueshanhaizi/article/details/52261960)

Android标題欄(二)](http://blog.csdn.net/xueshanhaizi/article/details/52263547)

網易雲免費體驗館,0成本體驗20+款雲産品! 

更多網易研發、産品、營運經驗分享請通路網易雲社群。

相關文章:

【推薦】 網易雲容器服務微服務化實踐—微服務測試及鏡像化提測全流程實踐

【推薦】 認識使用者訪談

【推薦】 為什麼有些驗證碼看起來很容易但是沒人做自動識别的?