ToolbarDemo【Toolbar作为顶部导航栏的简单使用】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
简单记录ToolBar作为导航栏的使用。关键点在于如何在dialogfragment中使用toolbar!
Toolbar的图标、标题设置:
效果图
参考使用方法的效果图。
代码分析
分为两部分:一部分是固定不变的部分(参考导入步骤);另外一部分是根据实际情况灵活改变的部分(参考使用方法);
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
(1)引入appcompat support v7支持包【一般都会引入】
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.why.project.toolbardemo"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
(2)修改styles.xml文件中的AppTheme
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
(3)将nav_toolbar_base.xml复制到项目中
<?xml version="1.0" encoding="utf-8"?> <!-- 基础的toolbar(代码控制标题、图标显示) --> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar_base" android:layout_width="match_parent" android:layout_height="@dimen/nav_height" android:minHeight="@dimen/nav_height" android:background="@color/nav_bg" app:navigationIcon="@drawable/nav_back" app:contentInsetStart="0dp" app:contentInsetStartWithNavigation="0dp" app:titleTextAppearance="@style/nav_toolbar_title_style" app:theme="@style/nav_toolbar_menu_style" app:popupTheme="@style/nav_toolbar_popup_style" > <TextView android:id="@+id/toolbarTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:textColor="@color/nav_text_color" android:textSize="@dimen/nav_title_text_size" android:layout_gravity="center"/> </android.support.v7.widget.Toolbar>
(4) 将nav_back.png复制到项目中
(5)在colors.xml中添加以下代码
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> <!-- toolbar背景色 --> <color name="nav_bg">#ffffff</color> <!-- toolbar标题颜色 --> <color name="nav_text_color">#434343</color> <!-- toolbar的menu文本颜色 --> <color name="nav_menu_text_color">#3090d9</color> <!-- toolbar的popup背景色 --> <color name="nav_popup_bg_color">#ffffff</color> <!-- toolbar的popup文本颜色 --> <color name="nav_popup_text_color">#818181</color> </resources>
(6)在dimens.xml中添加以下代码
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- toolbar高度 --> <dimen name="nav_height">56dp</dimen> <!-- toolbar标题文字大小 --> <dimen name="nav_title_text_size">18sp</dimen> <!-- toolbar的Menu文字大小 --> <dimen name="nav_menu_text_size">14sp</dimen> <!-- toolbar的popup文字大小 --> <dimen name="nav_popup_text_size">16sp</dimen> </resources>
(7)在styles.xml中添加以下代码
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!-- 添加这一句, 即可改变toolbar右侧更多图标的颜色--> <item name="android:textColorSecondary">@color/nav_menu_text_color</item> </style> <!-- toolbar标题的颜色和大小值设置 --> <style name="nav_toolbar_title_style"> <item name="android:textColor">@color/nav_text_color</item> <item name="android:textSize">@dimen/nav_title_text_size</item> </style> <!-- toolbar的menu(非popup样式)的颜色和大小值设置 --> <style name="nav_toolbar_menu_style"> <item name="android:actionMenuTextColor">@color/nav_menu_text_color</item> <item name="android:textSize">@dimen/nav_menu_text_size</item> </style> <!-- toolbar弹出的popup菜单的颜色和大小值设置 --> <style name="nav_toolbar_popup_style"> <item name="android:colorBackground">@color/nav_popup_bg_color</item> <item name="android:textColor">@color/nav_popup_text_color</item> <item name="android:textSize">@dimen/nav_popup_text_size</item> <!--将overlapAnchor属性设置成false就可以在toolbar下方显示--> <item name="overlapAnchor">false</item> </style> </resources>
至此,toolbar的基础代码添加到项目中了,后续根据想要显示的效果添加图片资源和menu文件。
三、使用方法
(1)在activity布局文件中引用nav_toolbar_base.xml【下面所有activity的布局文件都是这个】
activity_toolbar_normal.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="vertical" android:background="#F4F4F4"> <include layout="@layout/nav_toolbar_base"/> </LinearLayout>
(2)无右侧菜单项图标样式
1、将nav_notifications.png复制到项目中【因为换了个图标,所以需要添加新图标】
2、在Activity中这样写【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.TextView; /** * Created by HaiyuKing * Used 无右侧菜单项样式 */ public class ToolBarNoMenuActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("首页"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 mToolbar.setNavigationIcon(R.drawable.nav_notifications);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
效果图
(3)左图左标题右图样式
1、将nav_ok.png复制到项目中【因为需要用到menu菜单项,所以需要添加新图标】
2、在res/menu目录中添加toolbar_one_menu.xml文件
<?xml version="1.0" encoding="utf-8"?> <!-- 基础的toolbar(右侧只有一个图标的样式) --> <!--app:showAsAction="ifRoom/never/always",ifRoom表示只要在app bar存在可用空间,就可以显示,never表示一直显示在溢出菜单(overflowwindow)里面 --> <!--always:始终把这个放到项目中app bar。但是谷歌建议避免这么使用,除非它非常关键,使它始终显示在操作栏。设置多个始终显示在app bar可能会导致它们在应用栏其他UI重叠。--> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_save" android:icon="@drawable/nav_ok" android:title="保存" app:showAsAction="always" /> </menu>
3、在Activity中这样写【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; /** * Created by HaiyuKing * Used 左图左标题右图样式 */ public class ToolBarTitleLeftActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("标题");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText(""); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_save: Toast.makeText(ToolBarTitleLeftActivity.this,"保存",Toast.LENGTH_SHORT).show(); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_one_menu, menu);//toolbar添加menu菜单 return true; } }
效果图
(4)左图中标题右图样式
跟《(3)左图左标题右图样式》的使用相同的nav_ok.png图标和toolbar_one_menu.xml文件
不同的是activity的写法不一样:【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; /** * Created by HaiyuKing * Used 左图中标题右图样式 */ public class ToolBarTitleCenterActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("标题"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_save: Toast.makeText(ToolBarTitleCenterActivity.this,"保存",Toast.LENGTH_SHORT).show(); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_one_menu, menu);//toolbar添加menu菜单 return true; } }
效果图
(5)无左侧图标布局
1、将nav_close.png复制到项目中【因为为了和上面的有所区别,所以需要添加新图标】
2、跟《(3)左图左标题右图样式》的使用相同的nav_ok.png图标和toolbar_one_menu.xml文件
3、在Activity中这样写【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; /** * Created by HaiyuKing * Used 无左侧图标布局 */ public class ToolBarNoNavigationiconActivity extends AppCompatActivity { private Toolbar mToolbar; private MenuItem menuItem; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("筛选"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_save: finish(); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_one_menu, menu);//toolbar添加menu菜单 menuItem = menu.findItem(R.id.action_save); menuItem.setIcon(R.drawable.nav_close);//动态修改menu的图标 return true; } }
效果图
(6)菜单项中含有文本的布局
1、在res/menu目录中添加toolbar_three_menu.xml文件【因为含有三个菜单项,所以需要使用新的menu文件】
<?xml version="1.0" encoding="utf-8"?> <!-- 基础的toolbar的menu --> <!--app:showAsAction="ifRoom/never/always",ifRoom表示只要在app bar存在可用空间,就可以显示,never表示一直显示在溢出菜单(overflowwindow)里面 --> <!--always:始终把这个放到项目中app bar。但是谷歌建议避免这么使用,除非它非常关键,使它始终显示在操作栏。设置多个始终显示在app bar可能会导致它们在应用栏其他UI重叠。--> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_undo" android:title="撤销" app:showAsAction="always" /> <item android:id="@+id/action_redo" android:title="重做" app:showAsAction="always" /> <item android:id="@+id/action_save" android:icon="@drawable/nav_ok" android:title="保存" app:showAsAction="always" /> </menu>
2、在Activity中这样写【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; /** * Created by HaiyuKing * Used 菜单项中含有文本的布局展现 */ public class ToolBarMenuTextActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("编辑"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_undo: Toast.makeText(ToolBarMenuTextActivity.this,"撤销",Toast.LENGTH_SHORT).show(); break; case R.id.action_redo: Toast.makeText(ToolBarMenuTextActivity.this,"重做",Toast.LENGTH_SHORT).show(); break; case R.id.action_save: Toast.makeText(ToolBarMenuTextActivity.this,"保存",Toast.LENGTH_SHORT).show(); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_three_menu, menu);//toolbar添加menu菜单 return true; } }
效果图
(7)溢出菜单(popup)的样式
1、将nav_menu_fabu.png、nav_menu_share.png复制到项目中【因为使用到新的menu菜单项了,所以需要添加图片资源】
2、在res/menu目录中添加toolbar_popup_menu.xml文件【因为属性有所变化,所以需要使用新的menu文件】
<?xml version="1.0" encoding="utf-8"?> <!-- 基础的toolbar的menu --> <!--app:showAsAction="ifRoom/never/always",ifRoom表示只要在app bar存在可用空间,就可以显示,never表示一直显示在溢出菜单(overflowwindow)里面 --> <!--always:始终把这个放到项目中app bar。但是谷歌建议避免这么使用,除非它非常关键,使它始终显示在操作栏。设置多个始终显示在app bar可能会导致它们在应用栏其他UI重叠。--> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_edit" android:title="编辑" app:showAsAction="always" /> <item android:id="@+id/action_share" android:icon="@drawable/nav_menu_share" android:title="分享" app:showAsAction="never" /> <item android:id="@+id/action_publish" android:icon="@drawable/nav_menu_fabu" android:title="发布" app:showAsAction="never" /> </menu>
3、在Activity中这样写【注意:initToolBar()方法里面的代码可以根据实际情况拆分开,比如想要根据传过来的参数动态更改标题、隐藏menu菜单项等】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; /** * Created by HaiyuKing * Used 溢出菜单(popup)的样式 */ public class ToolBarPopupMenuActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("预览"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_edit: Toast.makeText(ToolBarPopupMenuActivity.this,"编辑",Toast.LENGTH_SHORT).show(); break; case R.id.action_share: Toast.makeText(ToolBarPopupMenuActivity.this,"分享",Toast.LENGTH_SHORT).show(); break; case R.id.action_publish: Toast.makeText(ToolBarPopupMenuActivity.this,"发布",Toast.LENGTH_SHORT).show(); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_popup_menu, menu);//toolbar添加menu菜单 return true; } }
效果图
(8)对话框中使用toolbar
1、新建自定义的dialogfragment文件,比如HasToolbarDialog【注意,黄色标记的代码】【布局文件共用已有的xml文件】
package com.why.project.toolbardemo.dialog; import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v7.widget.Toolbar; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; import com.why.project.toolbardemo.R; /** * Created by HaiyuKing * Used 演示如何使用toolbar的对话框界面 */ public class HasToolbarDialog extends DialogFragment{ private static final String TAG = HasToolbarDialog.class.getSimpleName(); public static final String TAG_FULLSCREEN = "fullScreen";//全屏 public static final String TAG_BELOWSTATUEBAR = "belowStatusBar";//状态栏下方 /**View实例*/ private View myView; /**context实例*/ private Context mContext; /**标记:用来代表是从哪个界面打开的这个对话框*/ private String mTag; private Toolbar mToolbar; public static HasToolbarDialog getInstance(Context mContext, Bundle bundle) { HasToolbarDialog dialog = new HasToolbarDialog(); dialog.mContext = mContext; return dialog; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //android.R.style.Theme_Material_NoActionBar_Fullscreen这个样式好看 //Display fullscreen without actionbar //http://www.itgo.me/a/7477281837685192473/how-to-make-material-design-full-screen-dialog //解决在4.2.2设备上打开崩溃的问题 if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) { setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_NoActionBar_Fullscreen);//全屏(在状态栏底下) } else { setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0));//设置背景为透明,并且没有标题 getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏 //设置窗体全屏 getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); myView = inflater.inflate(R.layout.activity_toolbar_normal, container, false); /*this.getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK) { LogUtil.w(TAG, "onKey"); dismiss(); return true; // return true是中断事件,那么下面的就接受不到按键信息了 }else { return false; //在return false的时候 才会事件继续向下传递。 } } });*/ return myView; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); initToolBar();//初始化toolbar //初始化控件以及设置 initView(); //初始化数据 initDatas(); initEvents(); } /** * 设置宽度和高度值,以及打开的动画效果 */ @Override public void onStart() { super.onStart(); if(mTag.equals(TAG_FULLSCREEN)){//全屏显示 //设置对话框的宽高,必须在onStart中 Window window = this.getDialog().getWindow(); window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);//全屏(盖住状态栏) window.setGravity(Gravity.BOTTOM);//设置在底部 //打开的动画效果 }else{ //从我的场景列表界面中设置按钮打开的 //设置对话框的宽高,必须在onStart中 DisplayMetrics metrics = new DisplayMetrics(); this.getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); Window window = this.getDialog().getWindow(); if(getStatusBarHeight(mContext) <= 96){ window.setLayout(metrics.widthPixels, metrics.heightPixels - getStatusBarHeight(mContext)); }else{ window.setLayout(metrics.widthPixels, this.getDialog().getWindow().getAttributes().height);//适配红米6pro刘海屏 } window.setGravity(Gravity.BOTTOM);//设置在底部 //打开的动画效果 } } /**获取状态栏的高度*/ private int getStatusBarHeight(Context context) { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); } @Override public void onDestroy() { super.onDestroy(); } private void initToolBar() { mToolbar = myView.findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("对话框标题"); //setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar【dialogFragment中去掉】 //设置导航图标要在setSupportActionBar方法之后 mToolbar.setNavigationIcon(R.drawable.nav_back);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //关闭对话框,返回null dismiss(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_edit: Toast.makeText(mContext,"编辑",Toast.LENGTH_SHORT).show(); break; case R.id.action_share: Toast.makeText(mContext,"分享",Toast.LENGTH_SHORT).show(); break; case R.id.action_publish: Toast.makeText(mContext,"发布",Toast.LENGTH_SHORT).show(); break; } return true; } }); //https://stackoverflow.com/questions/27608399/toolbar-in-dialogfragment // Inflate a menu to be displayed in the toolbar mToolbar.inflateMenu(R.menu.toolbar_popup_menu); } /**实例化控件*/ private void initView() { } /** * 初始化数据:tag标记、标题 */ private void initDatas() { mTag = this.getTag(); } /** * 初始化监听事件 */ private void initEvents() { } }
2、在Activity中打开对话框
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import com.why.project.toolbardemo.dialog.HasToolbarDialog; /** * Created by HaiyuKing * Used 在对话框中使用toolbar */ public class ToolBarDialogActivity extends AppCompatActivity { private Toolbar mToolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("点击右侧图标打开一个对话框"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_save: Bundle bundle = new Bundle(); HasToolbarDialog dialog = HasToolbarDialog.getInstance(ToolBarDialogActivity.this,bundle); dialog.show(getSupportFragmentManager(),HasToolbarDialog.TAG_BELOWSTATUEBAR); break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_one_menu, menu);//toolbar添加menu菜单 return true; } }
效果图
Activity界面
对话框界面
(9)动态更新Menu的图标和文本
1、在Activity中使用【注意黄色标记的代码,属于动态更新Menu的核心代码】
package com.why.project.toolbardemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; /** * Created by HaiyuKing * Used 动态更新Menu */ public class ToolBarMenuUpdateActivity extends AppCompatActivity { private Toolbar mToolbar; private boolean showOk = false;//切换图标的状态值,至于默认值是true还是false,根据项目情况而定 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toolbar_normal); initToolBar();//初始化toolbar } private void initToolBar() { mToolbar = findViewById(R.id.toolbar_base); mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示 //设置自定义的标题(居中) TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle); toolBarTitle.setText("动态更新Menu"); setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar //设置导航图标要在setSupportActionBar方法之后 //mToolbar.setNavigationIcon(null);//设置为空的话,就会不显示左侧的图标 //对NavigationIcon添加点击 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //添加menu 菜单点击事件 mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()){ case R.id.action_save: showOrHiddenUpdatedMenu(); //动态更新Menu break; } return true; } }); } @Override public boolean onCreatePanelMenu(int featureId, Menu menu) { getMenuInflater().inflate(R.menu.toolbar_one_menu, menu);//toolbar添加menu菜单 return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { if (! showOk) { menu.findItem(R.id.action_save).setIcon(R.drawable.nav_menu_fabu);//更新android:icon值 menu.findItem(R.id.action_save).setTitle("发布");//更新android:title值 } else { menu.findItem(R.id.action_save).setIcon(R.drawable.nav_ok);//更新android:icon值 menu.findItem(R.id.action_save).setTitle("保存");//更新android:title值 } return super.onPrepareOptionsMenu(menu); } //动态更新Menu private void showOrHiddenUpdatedMenu(){ if(! showOk){ showOk = true; invalidateOptionsMenu(); //重新绘制menu }else{ showOk = false; invalidateOptionsMenu(); //重新绘制menu } } }
onCreateOptionsMenu方法只在创建Activity的时候调用一次,以后就不再调用了,所以就不能在onCreateOptionsMenu中做处理了。
不过系统提供了另外的一个方法onPrepareOptionsMenu,我们可以在这个方法中做一些逻辑处理,然后在需要更新Menu的地方调用invalidateOptionsMenu()方法。
效果图
混淆配置
无
参考资料
《第一行代码(第2版)》
动态更新Toolbar Menu以及Menu中同时显示文字和图标