扩展用户体验之操做栏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

相关文章
相关标签/搜索