ActionBar的使用

作者: olaH | 来源:发表于2017-10-31 22:35 被阅读0次

    前言

    山水一程,三生有幸。

    启用ActionBar

    ActionBar需要在Android3.0以上的版本才能启用。如果希望关闭ActionBar,则可以设置该应用的主题为Xxxx.NoActionBar,配置如下。
    android:theme="@android:style/Theme.Material.NoActionBar"
    
    但是在实际项目中,通常推荐使用代码来控制ActionBar的显示、隐藏。

    代码示例

    actionbar.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="show"
            android:text="显示" />
    
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="hide"
            android:text="隐藏" />
    
    </LinearLayout>
    
    MainActivity.java
    public class MainActivity extends Activity {
    
        ActionBar actionBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.actionbar);
    
            //获取该Activity的ActionBar
            //只有当应用主题没有关闭ActionBar才生效
            actionBar = getActionBar();
        }
    
        public void show(View v)
        {
            actionBar.show();
        }
        public void hide(View v)
        {
            actionBar.hide();
        }
    
    }
    

    效果

    Screenshot_20171024-153252.png Screenshot_20171024-153406.png

    使用ActionBar显示选项菜单项

    因为Android不再强制要求手机必须提供MENU按键,这样可能导致用户无法打开选项菜单。为解决这个问题,从Android3.0开始,MenuItem新增了如下方法。
    • setShowAsAction(int actionEnum):该方法设置是否将该菜单项显示在ActionBar上,作为Action Item。
    该方法支持如下参数值。
    • SHOW_AS_ACTION_ALWAYS:总是将MenuItem显示在ActionBar上。
    • SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW:将该ActionView折叠成普通菜单项。
    • SHOW_AS_ACTION_IF_ROOM:当ActionBar位置足够时才显示MenuItem。
    • SHOW_AS_ACTION_NEVER:不将该MenuItem显示在ActionBar上。
    • SHOW_AS_ACTION_WITH_TEXT:将该MenuItem显示在ActionBar上,并显示菜单项的文本。
    对上一章的菜单示例稍作修改

    代码示例

    main.xml
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context="com.张敦锋.uidemo9.MainActivity" >
    
        <item
            android:icon="@drawable/ic_launcher"
            android:showAsAction="always|withText"
            android:title="font_size">
            <menu>
    
                <!-- 定义一组单选菜单项 -->
                <group android:checkableBehavior="single" >
    
                    <!-- 定义多个菜单项 -->
                    <item
                        android:id="@+id/font_10"
                        android:title="font_10"/>
                    <item
                        android:id="@+id/font_12"
                        android:title="font_12"/>
                    <item
                        android:id="@+id/font_14"
                        android:title="font_14"/>
                    <item
                        android:id="@+id/font_16"
                        android:title="font_16"/>
                    <item
                        android:id="@+id/font_18"
                        android:title="font_18"/>
                </group>
            </menu>
        </item>
        <!-- 定义一个普通菜单项 -->
        <item
            android:id="@+id/plain_item"
            android:showAsAction="always"
            android:title="plain_item"/>
        <item
            android:icon="@drawable/ic_launcher"
            android:showAsAction="always|withText"
            android:title="font_color">
            <menu>
                <!-- 定义一组普通菜单项 -->
                <group>
                    <!-- 定义三个菜单项 -->
                    <item
                        android:id="@+id/red_font"
                        android:title="red_title"
                        />
                    <item
                        android:id="@+id/green_font"
                        android:title="green_title"
                        />
                    <item
                        android:id="@+id/blue_font"
                        android:title="blue_title"
                        />
                </group>
            </menu>
        </item>
    </menu>
    

    效果

    Screenshot_20171025-110032.png

    提示

    Android将会根据不同手机设备采取不同的行为。

    启用程序图标导航

    为了将应用程序图标转变成可以点击的图标,可以调用ActionBar的如下方法。
    • setDisplayHomeAsUpEnable(boolean showHomeAsUp):设置是否将应用程序图标转变成可点击的图标,并在图标上添加一个向左箭头。
    • setDisplayOptions(int options):通过传入int类型常量来控制ActionBar的显示选项。
    • setDisplayShowHomeEnabled(boolean showHome):设置是否显示应用程序图标。
    • setHomeButtonEnabled(boolean enabled):设置是否将应用程序图标转变成可点击的按钮。

    代码示例

    MainActivity.java
    public class MainActivity extends Activity {
    
        private TextView txt;
        ActionBar actionBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.menu);
            txt = (TextView) findViewById(R.id.txt);
            actionBar = getActionBar();
            //设置是否显示该应用程序图标
            actionBar.setDisplayShowHomeEnabled(true);
            //将应用程序图标设置为可点击的按钮
            //actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            MenuInflater inflator = new MenuInflater(this);
            inflator.inflate(R.menu.main, menu);
            return super.onCreateOptionsMenu(menu);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if(item.isCheckable())
            {
                //勾选该菜单项
                item.setChecked(true);
            }
    
            //判断单击的是哪个菜单
            switch (item.getItemId()) {
            case android.R.id.home:
                //创建启动FirstActiviy的Intent
                Intent intent = new Intent(this,FirstActivity.class);
                //添加额外的Flag,将Activity栈中处于FirstActivity之上的Activity弹出
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                //启动intent
                startActivity(intent);
                break;
            case R.id.font_10:
                txt.setTextSize(10 * 2);
                break;
            case R.id.font_12:
                txt.setTextSize(12 * 2);
                break;
            case R.id.font_14:
                txt.setTextSize(14 * 2);
                break;
            case R.id.font_16:
                txt.setTextSize(16 * 2);
                break;
            case R.id.font_18:
                txt.setTextSize(18 * 2);
                break;
            case R.id.red_font:
                txt.setTextColor(Color.RED);
                item.setChecked(true);
                break;
            case R.id.green_font:
                txt.setTextColor(Color.GREEN);
                item.setChecked(true);
                break;
            case R.id.blue_font:
                txt.setTextColor(Color.BLUE);
                item.setChecked(true);
                break;
            case R.id.plain_item:
                Toast.makeText(MainActivity.this, "您单击了普通菜单项", Toast.LENGTH_SHORT).show();
                break;
            }
            return true;
        }
    }
    

    效果

    Screenshot_20171025-130336.png

    提示

    应用程序图标的ID为android.R.id.home。

    添加Action View

    ActionBar上除了可以显示普通的Action Item之外,还可以显示普通的UI组件。为了在ActionBar上添加Action View,可以来用如下两种方式。
    • 定义Action Item时使用android:actionViewClass属性指定Action View的实现类。
    • 定义Action Item时使用android:actionLayout属性指定Action View对应的视图资源。

    代码示例

    menu_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:title="search"
            android:id="@+id/search"
            android:orderInCategory="100"
            android:showAsAction="always"
            android:actionViewClass="android.widget.SearchView"
            />
        <item
            android:id="@+id/progress"
            android:title="clock"
            android:actionLayout="@layout/clock"
            android:orderInCategory="100"
            android:showAsAction="always"
            />
    </menu>
    
    
    clock.xml
    <?xml version="1.0" encoding="utf-8"?>
    <AnalogClock
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    
    MainActivity.java
    public class MainActivity extends Activity {
    
        ActionBar actionBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.actionbar);
    
            actionBar = getActionBar();
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            MenuInflater inflator = new MenuInflater(this);
            inflator.inflate(R.menu.menu_main, menu);
            return super.onCreateOptionsMenu(menu);
        }
    }
    

    效果

    Screenshot_20171025-131704.png

    使用ActionBar实现Tab导航

    为了使用ActionBar实现Tab导航,按如下步骤进行即可。
    • 调用ActionBar的setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)方法设置使用Tab导航方式。
    • 调用ActionBar的addTab()方法添加多个Tab标签,并为每个Tab标签添加事件监听器。
    实际项目中为了更好地展现Tab导航效果,ActionBar通常会与Fragment结合使用,Fragment非常像Activity,后面的章节将会讲述到。

    代码示例

    main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
    </LinearLayout>
    
    DummyFragment.java
    public class DummyFragment extends Fragment{
    
        public static final String ARG_SECTION_NUMBER = "section_number";
        //该方法返回值就是Fragment显示的View组件
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            TextView textView = new TextView(getActivity());
            textView.setGravity(Gravity.START);
            //获取创建该Fragment时传入的参数Bundle
            Bundle args = getArguments();
            //设置TextView显示的文本
            textView.setText(args.getInt(ARG_SECTION_NUMBER) + "");
            textView.setTextSize(30);
            //返回该TextView
            return textView;
        }
    }
    
    MainActivity.java
    public class MainActivity extends Activity implements ActionBar.TabListener{
    
        private static final String SELECTED_ITEM = "selected_item";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            final ActionBar actionBar = getActionBar();
            //设置ActionBar的导航方式:Tab导航
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            //依次添加三个Tab标签,并为三个Tab标签添加事件监听器
            actionBar.addTab(actionBar.newTab().setText("第一页").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("第二页").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("第三页").setTabListener(this));
    
        }
    
    
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
    
            if(savedInstanceState.containsKey(SELECTED_ITEM))
            {
                //选中前面保存的索引对应的Fragment页
                getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(SELECTED_ITEM));
            }
        }
    
    
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            //将当前选中的Fragment页的索引保存到Bundle中
            outState.putInt(SELECTED_ITEM, getActionBar().getSelectedNavigationIndex());
        }
    
    
        //当指定Tab标签被选中时激发该方法
        @Override
        public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
            //创建一个Fragment对象
            Fragment fragment = new DummyFragment();
            //创建一个Bundle对象,用于向Fragment传入参数
            Bundle args = new Bundle();
            args.putInt(DummyFragment.ARG_SECTION_NUMBER, tab.getPosition() + 1);
            //向Fragment传入参数
            fragment.setArguments(args);
            //获取FragmentTransaction对象
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            //使用fragment代替该Activity中的container组件
            ft.replace(R.id.container, fragment);
            //提交事务
            ft.commit();
        }
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
    
        }
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
    
        }
    
    
    }
    

    效果

    Screenshot_20171025-135758.png

    使用ActionBar实现下拉式导航

    ActionBar除了可以提供Tab导航支持之外,还提供了下拉式(DropDown)导航方式。下拉式导航的ActionBar在顶端生成下拉列表,当用户单击某个列表项时,系统根据用户单击事件导航到指定Fragment。为了使用ActionBar实现下拉式导航,按如下步骤进行即可。
    1. 调用ActionBar的setNavigationMode(ActionBar.NAVIGATION_MODE_LIST)方法设置使用下拉列表的导航方式。
    2. 调用setListNavigationCallbacks(SpinnerAdapter adapter, ActionBar.OnNavigationListener callback)方法添加多个列表项,并为每个列表项设置事件监听器。

    代码示例

    MainActivity.java
    public class MainActivity extends Activity implements ActionBar.OnNavigationListener{
    
        private static final String SELECTED_ITEM = "selected_item";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            final ActionBar actionBar = getActionBar();
            //设置ActionBar的导航方式:List导航
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
            //actionBar安装ArrayAdapter
            actionBar.setListNavigationCallbacks(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1
                    , new String[] {"第一页","第二页","第三页"}), this);
        }
    
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
    
            if(savedInstanceState.containsKey(SELECTED_ITEM))
            {
                //选中前面保存的索引对应的Fragment页
                getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(SELECTED_ITEM));
            }
        }
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            //将当前选中的Fragment页的索引保存到Bundle中
            outState.putInt(SELECTED_ITEM, getActionBar().getSelectedNavigationIndex());
        }
    
        //当导航被选中时激发该方法
        @Override
        public boolean onNavigationItemSelected(int position, long id) {
            //创建一个Fragment对象
            Fragment fragment = new DummyFragment();
            //创建一个Bundle对象,用于向Fragment传入参数
            Bundle args = new Bundle();
            args.putInt(DummyFragment.ARG_SECTION_NUMBER, position + 1);
            //向Fragment传入参数
            fragment.setArguments(args);
            //获取FragmentTransaction对象
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            //使用fragment代替该Activity中的container组件
            ft.replace(R.id.container, fragment);
            //提交事务
            ft.commit();
            return true;
        }
    }
    

    效果

    Screenshot_20171025-141443.png

    相关文章

      网友评论

        本文标题:ActionBar的使用

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