Android 标题栏(2)

作者: 网易数帆 | 来源:发表于2018-09-26 13:44 被阅读10次

    本文来自网易云社区

    作者:孙圣翔

    添加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+款云产品! 

    更多网易研发、产品、运营经验分享请访问网易云社区

    相关文章:
    【推荐】 消息推送平台高可用实践(上)
    【推荐】 2017年内容安全十大事件盘点

    相关文章

      网友评论

        本文标题:Android 标题栏(2)

        本文链接:https://www.haomeiwen.com/subject/bdbdoftx.html