快速掌握 Toolbar、ActionMenuView
2018-01-11 10:15
204 查看
一、隐藏ActionBar方式
1. 代码中隐藏
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 一定要在setContentView()之前调用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); }
2. style.xml文件中隐藏
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <!-- 添加windowActionBar和windowNoTitle属性,单独添加windowActionBar会报错 --> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
或
<!-- 使用无标题栏主题 --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> ...... </style>
二、Toolbar
1. 简介
ToolBar是Android 5.0推出的一个新的导航控件用于取代之前的ActionBar,高度可定制、灵活、具有Material Design风格,为了兼容低版本,该控件放在v7包中。2. 基本使用
1. app.build添加v7依赖
compile 'com.android.support:appcompat-v7:25.3.1'
2. xml引用
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" app:title="MainActivity" app:titleTextColor="#ffffff" android:background="@color/colorPrimary"> </android.support.v7.widget.Toolbar>
注意:如果不设置
app:title属性,默认使用 manifest 文件中
<activity>标签的 android:label 属性值作为标题内容,如果没有则使用
<application>标签下的
3. 代码设置Toolbar替换ActionBar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);
Toolbar还可以再xml或代码中设置很多属性,大部分感觉用处不大,常用的也就是一个NavigationIcon和Option Menu
3. 要点
1. NavigationIcon
一般就是个返回按钮,或者是菜单按钮,使用如下:1.代码设置显示
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
2.自定义按钮
<android.support.v7.widget.Toolbar ...... app:navigationIcon="@drawable/arrow_left"> </android.support.v7.widget.Toolbar>
或
toolbar.setNavigationIcon(R.drawable.arrow_left);
或
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeAsUpIndicator(R.drawable.arrow_left);
3.点击事件
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Toast.makeText(this, "返回", Toast.LENGTH_SHORT).show(); break; } return true; }
或
toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show(); } });
2. Toolbar Shadow
toolbar和主页面之间的分隔阴影1.创建xml,渐变阴影
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="@android:color/transparent" android:endColor="#32000000" android:angle="90" /> </shape>
2.Toolbar下面使用
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" android:textSize="18sp"/> <View android:layout_width="match_parent" android:layout_height="10dp" android:background="@drawable/shadow"/> </FrameLayout>
效果
如果在Toolbar外面包一层AppbarLayout,自带阴影分隔线
3. Toolbar标题居中
1.定制标题,添加textview<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:background="@color/colorPrimary" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="MainActivity" android:textSize="18sp" android:textColor="@android:color/white" android:textStyle="bold" android:layout_gravity="center"/> ..... </android.support.v7.widget.Toolbar>
2.隐藏Actionbar原标题
// xml中设置 app:title="",无效 toolbar.setTitle("");
或
getSupportActionBar().setDisplayShowTitleEnabled(false);
效果
4. Option Menu
1.创建 menu目录,并创建相应menu xml文件<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_menu" android:icon="@drawable/ic_info" android:title="menu" app:showAsAction="collapseActionView"/> <item android:id="@+id/menu_home" android:icon="@drawable/ic_main" android:title="home" app:showAsAction="collapseActionView"/> <item android:id="@+id/menu_self" android:icon="@drawable/ic_me" android:title="self" app:showAsAction="collapseActionView"/> </menu>
2.代码为toolbar添加menu,并设置点击事件
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu,menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.menu_menu: Toast.makeText(this, "菜单", Toast.LENGTH_SHORT).show(); break; case R.id.menu_home: Toast.makeText(this, "首页", Toast.LENGTH_SHORT).show(); break; case R.id.menu_self: Toast.makeText(this, "个人中心", Toast.LENGTH_SHORT).show(); break; } return true; }
效果
3.相关问题
3.1 想把菜单按钮的三个点变成白色
在style中添加textColorSecondary属性,可将白点变为白色
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> ...... <item name="android:textColorSecondary">#ffffff</item> </style>
或
给toolbar设置theme属性和popupTheme属性
<android.support.v7.widget.Toolbar ..... app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
如果只设置了theme属性,弹出菜单会变为黑底白字
注意:设置toolbar的theme为Dark暗色系
ThemeOverlay.AppCompat.Dark,三个点的颜色不是特别白,有点暗,设置为
ThemeOverlay.AppCompat.Dark.ActionBar,三个点为纯白色。
可以看出,不管是theme(设置自己使用的主题)还是popupTheme(自己弹窗所用的主题),如果设置的是Light这种明亮主题(背景),那么它上面的元素则是呈现黑色;如果设置的是Dark这种暗色主题(背景),那么它上面的元素则是白色
3.2 弹出菜单会覆盖toolbar
设置弹窗所用的popupTheme中的overlapAnchor属性
<style name="AppTheme.ToolbarPopupTheme" > <!-- 设置Menu窗口不覆盖Toolbar视图 --> <item name="overlapAnchor">false</item> </style>
<android.support.v7.widget.Toolbar ..... app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/AppTheme.ToolbarPopupTheme"">
效果
3.3 弹窗中,为menuItem设置的图片没有显示,这个是4.0后源码改动的原因,解决方法是在activity中重写一个方法
@Override public boolean onPrepareOptionsMenu(Menu menu) { if(menu != null){ if(menu.getClass().getSimpleName().equals("MenuBuilder")){ try{ Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch(NoSuchMethodException e){} catch(Exception e){} } } return super.onPrepareOptionsMenu(menu); }
效果
3.4 如果menuItem点击没有点击效果,或想设置字体颜色
<style name="AppTheme.ToolbarPopupTheme" > <!-- 设置Menu菜单的背景色,这里是个选择器,按下背景置灰 --> <item name="android:itemBackground">@drawable/item_pressed_selector</item> <!-- 设置Menu菜单的字体颜色 --> <item name="android:textColorPrimary">@android:color/black</item> <!-- 设置Menu窗口不覆盖Toolbar视图 --> <item name="overlapAnchor">false</item> </style>
三、ActionMenuView
1. 简介
Toolbar 默认将 Menu 内容显示在右边,ActionMenuView 是将原本位于 Toolbar 或者 ActionBar 中的 Menu 内容移到自己的名下,以 ViewGroup 的姿态将一系列的 Menu Item 囊括其中,再将自己搁置于 Toolbar 容器中,这样,更方便于管理和呈现 Menu 内容。所以,原本孤立的 Toolbar 控件,就有了一个 Child,使用如下:
2. 基本使用
1. app.build添加v7依赖 (正常用Toolbar时就导入了^_^)
compile 'com.android.support:appcompat-v7:25.3.1'
2. xml中引用actionmenuview
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" app:title="MainActivity" app:titleTextColor="#ffffff" android:background="@color/colorPrimary" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/AppTheme.ToolbarPopupTheme"> <android.support.v7.widget.ActionMenuView android:id="@+id/amv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> </android.support.v7.widget.ActionMenuView> </android.support.v7.widget.Toolbar>
3. 将Toolbar的menu和menu点击事件,都转到actionmenuview中
@Override public boolean onCreateOptionsMenu(Menu menu) { ActionMenuView amv = (ActionMenuView) findViewById(R.id.amv); // 将menu加载到actionmenuview中 getMenuInflater().inflate(R.menu.menu,amv.getMenu()); // menuitem的点击事件 amv.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return onOptionsItemSelected(item); } }); // getMenuInflater().inflate(R.menu.menu,menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.menu_menu: Toast.makeText(this, "菜单", Toast.LENGTH_SHORT).show(); break; case R.id.menu_home: Toast.makeText(this, "首页", Toast.LENGTH_SHORT).show(); break; case R.id.menu_self: Toast.makeText(this, "个人中心", Toast.LENGTH_SHORT).show(); break; } return true; }
效果
注意:给Toolbar设置的popupTheme,对于Actionmenuview不太起作用了。想想也是,现在的Actionmenuview取代了Toolbar原先管理的那个Menu,而且相对独立,不受Toolbar约束;这样Actionmenuview可以显示在Toolbar的任意位置,但同时Toolbar的popupTheme也对Actionmenuview不起作用了。所以我就直接给actionmenuview设置theme控制弹窗的主题,控制它的样式为白底黑字 (
尝试过给ActionMenuView这是popupTheme,但是不起作用)
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> ...... </style> <!-- 自定义的popupTheme ,继承APPTheme,APPTheme继承的明亮系主题 --> <style name="AppTheme.ToolbarPopupTheme" > <!-- 不设置这个属性,三个点会是黑色 --> <item name="android:textColorSecondary">#ffffff</item> <!-- 设置Menu窗口不覆盖Toolbar视图 --> <item name="overlapAnchor">false</item> </style>
<android.support.v7.widget.ActionMenuView ...... app:theme="@style/AppTheme.ToolbarPopupTheme"> </android.support.v7.widget.ActionMenuView>
效果
不显示图标的问题,将上面重写的onPrepareOptionsMenu,修改一下代码如下:
移花接木
@Override public boolean onPrepareOptionsMenu(Menu menu) { // 用ActionMenuView的 Menu 替换原先的 Menu menu = mAmv.getMenu(); if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method m = menu.getClass().getDeclaredMethod( "setOptionalIconsVisible", Boolean.TYPE); m.setAccessible(true); m.invoke(menu, true); } catch (NoSuchMethodException e) { } catch (Exception e) { } } return super.onPrepareOptionsMenu(menu); }
效果
四、Fragment中使用Toolbar,添加optionMenu
1. 在onCreateView()中添加代码,代替原有的ActionBar
@Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_toolbar, container, false); mToolbar = (Toolbar) view.findViewById(R.id.toolbar); // 代替Actionbar ((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar); return view; }
2. 在onCreate()中添加代码,告诉Activity需要创建optionMenu
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); }
3. 重写onCreateOptionMenu()方法,加载菜单
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.clear(); inflater.inflate(R.menu.menu,menu); }
重写Fragment的onCreateOptionMenu()方法,覆盖Activity的onCreateOptionMenu()方法,否则Fragment中的onCreateOptionMenu()不会被调用
4. 菜单点击事件
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { ...... case R.id.menu_self: Toast.makeText(getActivity(), "个人中心", Toast.LENGTH_SHORT).show(); break; } return true; }
注意:
1.
Activity中的onOptionsItemSelected不能返回true,否则Fragment中的onOptionsItemSelected点击事件无效
2.
((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);的位置要在onCreateView中,刚开始测试时特别粗心,是在onCreate中写的,但是onCreate是在onCreateView之前调用,所以此时mToolbar为null,导致测试一直失败,toolbar虽然显示,但不正确,没有能代替Actionbar,Optionmenu也不显示
GitHub示例:ViewDemo/ToolbarDemo
相关文章推荐
- Toolbar 不为人知的助手,ActionMenuView
- Android CircularFloatingActionMenu在ScrollView这样的滚动View中使用(2)
- actionbarsherlock+viewpage+fragment menu not display at first time
- 控制QT中MainWindow上Menu和ToolBar的上下文菜单Action列表
- Android7.0中文文档(API)-- ActionMenuView.LayoutParams
- MenuItemCompat.getActionView(item)返回null
- Android7.0中文文档(API) -- ActionMenuView.OnMenuItemClickListener
- 微信小程序例子——快速掌握滚动视图(scroll-view)
- actionViewClass使用 menuItem.getActionView() MenuItemCompat.getActionView() 返回null
- 快速掌握 Recyclerview、SwipeRefreshLayout、Cardview
- Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果
- android设置toolbar的menu itemTextView颜色 set toolbar menu item text color
- Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu
- 低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航
- ActionMenuView的使用
- QT中菜单Menu与工具栏Toolbar中各个Action的动态添加删除
- android设置toolbar的menu itemTextView颜色
- Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu
- Android CircularFloatingActionMenu在ScrollView这样的滚动View中使用(2)
- Android之debug---menu的getActionView()return null