Material Design最佳体验(3):
使用DrawerLayout、NavigationView轻松实现滑动菜单
作者: |
蒋东国 |
时间: |
2017年03月11日 星期六 |
应用来源: |
路痴宝v1.2 |
博客地址: |
http://blog.youkuaiyun.com/andrexpert/article/details/61429929 |
情景再现:“Material Design是Google在2014年的I/O大会提出的一套全新的界面设计语言,它包含了视觉、运动、互动效果等特性,其宗旨就是解决Android平台界面风格不统一的问题。虽然Material Design是一套界面设计语言,但为了方便APP开发,Google提供了一个Design Support库,这个库对一些常见的控件和效果进行了封装,使开发工程师在在不了解Material Design的情况下能够将自己的应用Material化。”
滑动菜单是Material Design中最常见的效果之一,所谓滑动菜单就是将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后可以通过滑动的方式将菜单显示出来。如果是自己去实现的话,难度应该比较大,还好谷歌提供了一个DrawerLayout控件,使用这个控件我们可以非常轻松地实现滑动菜单。当然,在上干货之前,我们先看下QQ的侧滑菜单来直观感受下:
好了,接下来我们就开始讲解如何使用DrawerLayout和NavigationView来实现一个滑动菜单。DrawerLayout是实现滑动菜单的核心类,是support-v4库提供的一个布局控件,在使用时我们需要引入support-v4包。它的使用非常简单,只需要将Acitivity布局的最外层替换成DrawerLayout,然后放置二个或三个直接子控件即可,其中第一个是用作于主屏幕的中显示的内容,另外两个就分别为左、右滑动菜单布局。activity_main.xml布局代码如下:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img_frame_background" >
<!-- 主页 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<ListView
android:id="@+id/main_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:layout_below="@id/main_toolbar" />
</RelativeLayout>
<!--左侧滑动菜单布局-->
<TextView
android:id="@+id/left_sliding_tv "
android:name="jiangdg.meterial.demosliding.LeftSidingFragment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:tag=" LEFT " />
<!--右侧滑动菜单布局-->
<fragment
android:id="@+id/right_sliding_fragment"
android:name="jiangdg.meterial.demosliding.LeftSidingFragment"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:tag=" RIGHT " />
</android.support.v4.widget.DrawerLayout>
对于DrawerLayout来说,主要是通过android:layout_gravity="start"或android:layout_gravity="end"来指定左右滑动菜单的布局,该布局可以为一个view控件,也可以为一个ViewGroup控件或者fragment。如果滑动菜单为fragment时,还需要添加android:name属性指定相应的Fragment实现类。右侧滑动菜单的Fragment实现类RightSidingFragment.class完整代码如下:
/**
* 左侧滑动菜单Fragment
*
* @author Created by jiangdongguo on 2017-2-22下午11:11:58
*
* Blog:http://blog.youkuaiyun.com/andrexpert
* MyApp:http://www.anzhi.com/soft_2729689.html(安智市场)
/
public class RightSidingFragment extends Fragment {
private LinearLayout mSaoLayout;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_right, null);
findViews(view);
return view;
}
private void findViews(View view) {
mSaoLayout = (LinearLayout)view.findViewById(R.id.saosao_layout);
mSaoLayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MainActivity a = (MainActivity)getActivity();
a.closeLeftDrawer();
}
});
}
}
既然DrawerLayout是一个布局控件,那么首先肯定是通过findViewById来获得实例,然后调用DrawerLayout的openDrawer(Gravity gravity)方法和closeDrawer(Gravity gravity)方法来实现展开或关闭滑动菜单,左右方向由Gravity.START和Gravity.END参数决定,最后也可以使用DrawerLayout的setDrawerListener方法来对滑动菜单的展开状态事件进行监听。MainActivity.class完整代码如下:
/**滑动菜单Demo
*
* @author Created by jiangdongguo on 2017-3-11下午9:16:56
*
* Blog:http://blog.youkuaiyun.com/andrexpert
* MyApp:http://www.anzhi.com/soft_2729689.html(安智市场)
/
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MainActivity";
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initToolbar();
initDrawerLayout();
ListView mListView = (ListView)findViewById(R.id.main_list_view);
List<String> mList = new ArrayList<String>();
for(int i=0;i<20;i++){
String content = "测试-->"+i;
mList.add(content);
}
ArrayAdapter< String> mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,mList);
mListView.setAdapter(mAdapter);
}
private void initToolbar() {
// 替换标题栏为Toolbar
Toolbar mToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(mToolbar);
// 使能Home按键
ActionBar actionbar = getSupportActionBar();
if(actionbar != null){
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeButtonEnabled(true);
}
}
private void initDrawerLayout() {
mDrawerLayout = (DrawerLayout)findViewById(R.id.main_drawer_layout);
//为滑动菜单注册事件监听器
mDrawerLayout.setDrawerListener(new DrawerListener() {
@Override
public void onDrawerStateChanged(int arg0) {
Log.i(TAG, "onDrawerStateChanged");
}
@Override
public void onDrawerSlide(View drawView, float slideOffset) {
Log.i(TAG, " onDrawerSlide");
}
@Override
public void onDrawerOpened(View arg0) {
Log.i(TAG, "onDrawerOpened");
}
@Override
public void onDrawerClosed(View arg0) {
Log.i(TAG, "onDrawerClosed");
}
});
//实例化左侧滑动菜单
TextView mTvLeftDrawer = (TextView)findViewById(R.id.left_sliding_tv);
mTvLeftDrawer.setText("中华人民共和国,万岁!");
}
public void openLeftDrawer(){
//打开左侧滑动菜单
mDrawerLayout.openDrawer(Gravity.START);
}
public void openRightDrawer(){
//打开右侧滑动菜单
mDrawerLayout.openDrawer(Gravity.END);
}
public void closeLeftDrawer() {
//关闭所有滑动菜单
mDrawerLayout.closeDrawers();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.home:
openLeftDrawer();
break;
case R.id.menu_more:
openRightDrawer();
break;
default:
break;
}
return true;
}
}
运行效果如下:
目前我们已经成功实现了滑动菜单功能,并且滑动的效果是非常流畅,可见DrawerLayout控件之强大。但是相比于QQ的侧滑效果,上面实现的左侧滑动菜单布局却显得非常单调,当然,我们也可以使用fragment或者在主布局中设计成QQ侧滑菜单那样,但实际实现起来还是有点复杂。好在Google在提供DrawerLayout轻松实现侧滑菜单,又为我们提供了一个设计侧滑菜单布局的控件- NavigationView。NavigationView是Design Support库中提供的一个控件,它不仅是严格按照Material Design的要求来进行设计的,而且还可以将滑动菜单页面的实现变得非常简单。接下来,我们就将activity_main.xml文件中左侧滑动菜单的布局替换为NavigationView,完整代码如下:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img_frame_background" >
<!-- 主页 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.Toolbar
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<ListView
android:id="@+id/main_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/main_toolbar"
android:background="#FFFFFF" />
</RelativeLayout>
<!-- 左侧滑动菜单 -->
<android.support.design.widget.NavigationView
android:id="@+id/main_left_sliding_nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>
分析:NavigationView控件的使用非常简单,只需将原来左侧滑动菜单的TextView替换成NavigationView即可,然后通过android:layout_gravity="start"属性指定是那一侧滑动菜单,最后通过app:headerLayout="@layout/nav_header"和app:menu="@menu/nav_menu"分别指定滑动菜单布局的头部界面和内容界面。其中,nav_header.xml位于layout目录下,nav_menu.xml位于menu目录下,分别为:
(1) res/layout/nav_header.xml
(2) res/menu/nav_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 菜单组形式,每次只能选中一个item -->
<group android:checkableBehavior="single" >
<item
android:id="@+id/nav_menu_qianbo"
android:icon="@drawable/more_qianbo"
android:title="QQ钱包"/>
<item
android:id="@+id/nav_menu_zhuangbao"
android:icon="@drawable/more_zhuangbao"
android:title="个性装扮"/>
<item
android:id="@+id/nav_menu_shouchang"
android:icon="@drawable/menu_shouchang"
android:title="我的收藏"/>
<item
android:id="@+id/nav_menu_xiangce"
android:icon="@drawable/menu_xiangce"
android:title="我的相册"/>
</group>
</menu>
码字不易,转载请声明出处:http://blog.youkuaiyun.com/andrexpert/article/details/61429929
(.......未完,内容还比较多,明天接着写。。。)