此为第一个制作侧滑菜单的实践 。
此部分仅仅为部分实践:
仅缺menu的字符串布局,以及需要修改的MainActivity.java文件,也是需要主要修改的地方。
从使用MD设计-进行侧滑菜单的制作(activity_main.xml部分)仍然可看。
当中为了向前兼容以及使用Material Design,参考了约10个链接。
文件路径、参考链接为文章末尾,为了更好的阅读体验,增加了文件源代码展示(部分代码有删改)。
使用MD设计
设置向前兼容
进行4.0系统的一些工作
参考链接-向前兼容-1
首先准备添加MD设计包,但考虑到Android Icecream(4.0)仅为14,参考链接中得知Appcomat为21,所以先做以下调整:
- build.gradle:
android {
compileSdkVersion 21
defaultConfig {
applicationId "product.felixxiong.com.MyPackgeName"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:21.0.+' //导入Appcompat依赖5.0的21并随时获取可用新版本
implementation 'com.android.support.v7.widget.SwichCompat'//导入支持MD的switch控件
implementation 'com.android.support:design.21' //导入21设计库:参考链接:
values相关xml文件
- 新建values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
</resources>
- 新建values-v21/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
添加依赖
参考链接:向前兼容
apply plugin: 'com.android.application'
allprojects {
repositories {
google()
jcenter()
}
}
...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:21.0.+' //导入Appcompat依赖5.0的21并随时获取可用新版本
implementation 'com.android.support.v7.widget.SwichCompat'//导入支持MD的switch控件
implementation 'com.android.support:design.21' //导入21设计库
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
//implementation 'com.google.android.material:material:1.0.0-rc01'
使用Toolbar替换Action Bar
参考链接-向前兼容-1
- active_main.xml:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<!--参考链接:关于toolbar-4-->
<!--android:background="?attr/colorPrimaryDark"-->
android:background="#3F51B5"> <!--Toolbar可自定义颜色-->
</android.support.v7.widget.Toolbar>
- MainActivity.java:
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
//getLayoutResource()此处需要获取布局文件R.layout.……
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); //主要关于Toolbar的代码
if(toolbar != null) {
setSupportActionBar(toolbar);
}
}
进行侧滑菜单的制作
布局文件
导航栏布局
activity_main.xml
- 设定material.navigation.NavigationView
参考链接:Material Design
<com.google.android.material.navigation.NavigationView
android:id="@+id/left_navigation_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start" <!--layout_gravity指定重力-->
app:headerLayout="@layout/navigation_header" <!--设置navigation头布局-->
app:menu="@menu/my_navigation_items"> <!--设置navigation导航布局-->
<!--android:dividerHeight="0dp"
android:background="#111"--/>
</com.google.android.material.navigation.NavigationView>
</android.support.v4.widget.DrawerLayout>
设置布局,在相应目录下新建文件:
layoutnavigation_header.xml
menumy_navigation_items
android:dividerHeight="0dp"
此处代码链接为开发者文档,MD可能不需要两行代码。
- 添加Framelayout
此处链接为开发者文档。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/decor_content_frame">
<!--主内容视图必须为第一个视图,抽屉式导航必须位于内容顶部-->
<android.support.v7.widget.Toolbar
... />
</FrameLayout>
菜单头部布局
navigation_header.xml
参考链接:侧滑菜单-1
<?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:background="?attr/colorPrimary"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="50dp"
android:paddingTop="50dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<com.google.android.material.internal.VisibilityAwareImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="demo"/>
</LinearLayout>
菜单项布局
my_navigation_items
此处参考链接:侧滑菜单-1,因为开发者文档中使用Adpter方法实现填充,需要深入了解Adpter,故未加入。
JAVA文件()
Main Activity.java
参考链接:侧滑菜单-1
- 初始化抽屉导航栏列表
public class MainActivity extends AppCompatActivity {
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private Toolbar toolbar; //此处Toolbar修改为自己习惯的写法,为变量
private String[] mTitles; //创建标题变量
private DrawerLayout mDrawerLayout; //创建抽屉视图变量
private NavigationView mDrawerNavgation; //创建侧滑菜单视图变量
//private ActionBarDrawerToggle mDrawerToggle; 在后文中出现
//创建Toobar的子类作为监听器,需要在生命周期中调用togge
//private CharSequence mDrawerTitle;
//private CharSequence mTitle;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//mTitles = R.layout.activity_main.getStringArray(R.array.Titles_array); //初始化界面
//此处Toolbar修改为自己习惯的写法,实例化Toolbar写一起
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
onCreateOptionsMenu(R.layout.activity_main);
toolbar.setTitle("My Title");
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerNavgation = (NavigationView) findViewById(R.id.left_navigation_drawer);
mDrawerNavgation.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_layout, mTitles)); //为列表视图设置适配器
mDrawerNavgation.setOnItemClickListener(new DrawerItemClickListener()); //调用接收点击事件,设置点击监听器
}
...
}
}
- 处理导航点击事件
private class DrawerItemClickListener implements NavigationView.OnItemClickListener { //开始处理导航事件:在用户选择某一项时实现接口更改内容视图
@Override //这里开始调用onItemClick
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment = new Fragment(); //封装一个新片段并指定要根据位置显示的
Bundle args = new Bundle();
args.putInt(Fragment.ARG_LIST_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager(); //通过替换任何现有片段插入片段
fragmentManager.beginTransaction()
//将不同的FrameLayout插入内容主视图
.replace(R.id.decor_content_frame, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerNavgation.setItemChecked(position, true);
setTitle(mTitles[position]);
mDrawerLayout.closeDrawer(mDrawerNavgation);
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
3.侦听打开和关闭事件
public class MainActivity extends AppCompatActivity {
private ActionBarDrawerToggle mDrawerToggle;
//创建Toobar的子类作为监听器,需要在生命周期中调用togge
private CharSequence mDrawerTitle;
private CharSequence mTitle;
...
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
...
mTitle = mDrawerTitle = getTitle();
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle); //将抽屉切换设置为DrawerListener
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerNavgation);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
}
- 通过应用图标打开和关闭
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
//通过应用图标打开或关闭抽屉导航栏
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
public void onDrawerClosed(View view) { //当抽屉处于完全关闭状态时调用。
super.onDrawerClosed(view);
//getActionBar().setTitle(mTitle); //设置标题
}
public void onDrawerOpened(View drawerView) { //当抽屉处于完全状态时调用。
super.onDrawerOpened(drawerView);
//getToolBar().setTitle(mDrawerTitle); //设置标题
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle); ////将抽屉切换设置为DrawerListener
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
//每当我们调用invalidateOptionsMenu()时调用
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerNavgation);
//如果导航抽屉已打开,请隐藏与内容视图相关的操作项
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) { //在生命周期中调用ActionBarDrawerToggle
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState(); ////在onRestoreInstanceState发生后同步切换状态。
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
文件全部代码
build.gradle
allprojects {
repositories {
google()
jcenter()
}
}
android {
compileSdkVersion 21
defaultConfig {
applicationId "product.penghaoxiong.com.androidquickcheck"
minSdkVersion 14
targetSdkVersion 21
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:21.0.+' //导入Appcompat依赖5.0的21并随时获取可用新版本
implementation 'com.android.support.v7.widget.SwichCompat'//导入支持MD的switch控件
implementation 'com.android.support:design.21' //导入21设计库
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
//implementation 'com.google.android.material:material:1.0.0-rc01'
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'
}
参考链接
关于向前兼容
关于Toolbar
Material Design
侧滑菜单
路径
- build.gradle:appbuild.gradle
- MainActivity.java:appsrcmainjavaproductfelixxiongcomcheckMainActivityMainActivity.java
- active_main.xml:appsrcmainreslayoutactive_main.xml
- layout:
layoutnavigation_header.xml
- values:appsrcmainresvalues
values/themes.xml
values-v21/themes.xml