3.2添加抽屉导航

添加导航抽屉跟Android 5.0之前是一样的,只是以前我们使用ListView来作为菜单容器,现在我们则使用Material Design风格的RecyclerView。

(14)在你工程的java文件夹中,创建3个名为activityadaptermodel的包,将MainActivity.java移到activtiy包中,这样做使得你的代码可以很好地组织和管理。

(15)打开位于app模块下的build.gradle文件并添加如下依赖。添加完依赖之后,点击Build–>Rebuild Project下载所需要的类库

dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support:recyclerview-v7:28.0.+'
}

(16)在model包里,创建名为NavDrawerItem.java的类,然后添加以下代码。这个模型类是一个简单的POJO(Plain Oridinary Java Object即简单的java对象)类,它定义了导航抽屉的菜单项。

package info.androidhive.materialdesign.model;/*** Created by Ravi on 29/07/15.*/
public class NavDrawerItem {private boolean showNotify;private String title;public NavDrawerItem() {}public NavDrawerItem(boolean showNotify, String title) {this.showNotify = showNotify;this.title = title;}public boolean isShowNotify() {return showNotify;}public void setShowNotify(boolean showNotify) {this.showNotify = showNotify;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}
}

(17)在res–>layout下,创建一个名为nav_drawer_row.xml的文件并添加如下代码。这个布局渲染了导航抽屉菜单的每一行,如果你想自定义抽屉菜单项,你需要修改这个布局文件。在这个例子中,它仅包含一个TextView。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:clickable="true"><TextViewandroid:id="@+id/title"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="30dp"android:paddingTop="10dp"android:paddingBottom="10dp"android:textSize="15dp"android:textStyle="bold" /></RelativeLayout>

(18)下载个人资料图标并将它放入drawable文件夹,这一步是可选的,但是这个图标会在导航抽屉的头部用到。
(19)创建另一个名为fragment_navigation_drawer.xml的布局文件并添加如下代码。这个布局文件渲染了整个导航抽屉的视图,这个布局包括一个显示个人信息的头部和一个显示列表的RecycleView。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/white"><RelativeLayoutandroid:id="@+id/nav_header_container"android:layout_width="match_parent"android:layout_height="140dp"android:layout_alignParentTop="true"android:background="@color/colorPrimary"><ImageViewandroid:layout_width="70dp"android:layout_height="70dp"android:src="@drawable/ic_profile"android:scaleType="fitCenter"android:layout_centerInParent="true" /></RelativeLayout><android.support.v7.widget.RecyclerViewandroid:id="@+id/drawerList"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/nav_header_container"android:layout_marginTop="15dp" /></RelativeLayout>

(20)因为RecycleView是自定义的,我们还需要一个adapter来渲染自定义的xml布局,所以在adapter包下面,创建一个名为NavigationDrawerAdapter.java的类并添加如下代码。这个适配器类inflate了nav_drawer_row.xml并渲染了RecycleView抽屉菜单。

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import com.example.wzh.materialdesign.R;
import com.example.wzh.materialdesign.model.NavDrawerItem;import java.util.Collections;
import java.util.List;public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> {List<NavDrawerItem> data = Collections.emptyList();private LayoutInflater inflater;private Context context;public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) {this.context = context;inflater = LayoutInflater.from(context);this.data = data;}public void delete(int position) {data.remove(position);notifyItemRemoved(position);}@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = inflater.inflate(R.layout.nav_drawer_row, parent, false);MyViewHolder holder = new MyViewHolder(view);return holder;}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {NavDrawerItem current = data.get(position);holder.title.setText(current.getTitle());}@Overridepublic int getItemCount() {return data.size();}class MyViewHolder extends RecyclerView.ViewHolder {TextView title;public MyViewHolder(View itemView) {super(itemView);title = (TextView) itemView.findViewById(R.id.title);}}
}

(21)在activity包下,创建一个名为FragmentDrawer.java的Fragment。在Android Studio里面,按以下操作来创建一个新的Fragment,在activity包上右键–>New–>Fragment–>Fragment(Blank),然后给Fragment命名。

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;import com.example.wzh.materialdesign.R;
import com.example.wzh.materialdesign.adapter.NavigationDrawerAdapter;
import com.example.wzh.materialdesign.model.NavDrawerItem;import java.util.ArrayList;
import java.util.List;public class FragmentDrawer extends Fragment {private static String TAG = FragmentDrawer.class.getSimpleName();private RecyclerView recyclerView;private ActionBarDrawerToggle mDrawerToggle;private DrawerLayout mDrawerLayout;private NavigationDrawerAdapter adapter;private View containerView;private static String[] titles = null;private FragmentDrawerListener drawerListener;public FragmentDrawer() {}public void setDrawerListener(FragmentDrawerListener listener) {this.drawerListener = listener;}public static List<NavDrawerItem> getData() {List<NavDrawerItem> data = new ArrayList<>();// preparing navigation drawer itemsfor (int i = 0; i < titles.length; i++) {NavDrawerItem navItem = new NavDrawerItem();navItem.setTitle(titles[i]);data.add(navItem);}return data;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// drawer labelstitles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflating view layoutView layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);adapter = new NavigationDrawerAdapter(getActivity(), getData());recyclerView.setAdapter(adapter);recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {@Overridepublic void onClick(View view, int position) {drawerListener.onDrawerItemSelected(view, position);mDrawerLayout.closeDrawer(containerView);}@Overridepublic void onLongClick(View view, int position) {}}));return layout;}public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {containerView = getActivity().findViewById(fragmentId);mDrawerLayout = drawerLayout;mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {@Overridepublic void onDrawerOpened(View drawerView) {super.onDrawerOpened(drawerView);getActivity().invalidateOptionsMenu();}@Overridepublic void onDrawerClosed(View drawerView) {super.onDrawerClosed(drawerView);getActivity().invalidateOptionsMenu();}@Overridepublic void onDrawerSlide(View drawerView, float slideOffset) {super.onDrawerSlide(drawerView, slideOffset);toolbar.setAlpha(1 - slideOffset / 2);}};mDrawerLayout.setDrawerListener(mDrawerToggle);mDrawerLayout.post(new Runnable() {@Overridepublic void run() {mDrawerToggle.syncState();}});}public static interface ClickListener {public void onClick(View view, int position);public void onLongClick(View view, int position);}static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {private GestureDetector gestureDetector;private ClickListener clickListener;public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {this.clickListener = clickListener;gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onSingleTapUp(MotionEvent e) {return true;}@Overridepublic void onLongPress(MotionEvent e) {View child = recyclerView.findChildViewUnder(e.getX(), e.getY());if (child != null && clickListener != null) {clickListener.onLongClick(child, recyclerView.getChildPosition(child));}}});}@Overridepublic boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {View child = rv.findChildViewUnder(e.getX(), e.getY());if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {clickListener.onClick(child, rv.getChildPosition(child));}return false;}@Overridepublic void onTouchEvent(RecyclerView rv, MotionEvent e) {}@Overridepublic void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}}public interface FragmentDrawerListener {public void onDrawerItemSelected(View view, int position);}
}

(22)最后打开主Activity的布局文件(activity_main.xml)并按下面所示来修改布局。在这个布局里面,我们添加了android.support.v4.widget.DrawerLayout来展示导航抽屉菜单。
当然在标签里,你需要给出fragmentDrawer正确的路径。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:id="@+id/container_toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><includeandroid:id="@+id/toolbar"layout="@layout/toolbar" /></LinearLayout><FrameLayoutandroid:id="@+id/container_body"android:layout_width="fill_parent"android:layout_height="0dp"android:layout_weight="1" /></LinearLayout><fragmentandroid:id="@+id/fragment_navigation_drawer"android:name="com.example.wzh.materialdesign.activity.FragmentDrawer"android:layout_width="@dimen/nav_drawer_width"android:layout_height="match_parent"android:layout_gravity="start"app:layout="@layout/fragment_navigation_drawer"tools:layout="@layout/fragment_navigation_drawer" /></android.support.v4.widget.DrawerLayout>

现在所有的布局文件和java类文件都准备到位了,让我们对MainActivity做一些修改来使导航抽屉工作起来。

(23)打开MainActivity.java文件并做如下修改。
>实现FragmentDrawer.FragmentDrawerListener接口并添加onDrawerItemSelected()重载。
>创建FragmentDrawer的实例并设置抽屉选定的侦听器

import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;import com.example.wzh.materialdesign.R;public class MainActivity extends AppCompatActivity implements
FragmentDrawer.FragmentDrawerListener{private Toolbar mToolbar;private FragmentDrawer drawerFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mToolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(mToolbar);getSupportActionBar().setDisplayShowHomeEnabled(true);drawerFragment= (FragmentDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);drawerFragment.setDrawerListener(this);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main,menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}@Overridepublic void onDrawerItemSelected(View view, int position) {}
}

现在如果你运行App,可以看到导航抽屉,在里面有一个头部视图以及一些列表项。

完整Demo作者已经托管在Github上,可点击这里

从头开始做一个Material Design风格的App(3)相关推荐

  1. css app菜单,简单的Material Design风格手机App菜单特效

    插件描述:这是一款非常简单的Material Design风格手机App菜单特效.该特效使用CSS3和少量的jQuery代码来完成.在用户点击汉堡包菜单按钮之后,按钮会变形放大到整个手机APP屏幕,同 ...

  2. 打造Material Design风格的TabBar

    自从Material Design问世以来, 各种Material Design风格的控件层出不穷, 尤其是google家的几个APP更是将Material Design应用到了极致. 最近在使用go ...

  3. 开发Google Material Design风格的WPF程序

    原文:开发Google Material Design风格的WPF程序 今天在网上看到了一个Material Design风格的WPF皮肤,看上去还是挺不错的 这个项目是开源的,感兴趣的朋友可以下载试 ...

  4. Go项目(一)、服务器数据拉取和Material Design风格

    零.Go项目的github地址:https://github.com/fantianwen/Go 一.前言:因为希望能能够整合现在安卓的围棋app中较好的东西和当下较为流行的App中常见的功能,于是, ...

  5. [Material Design] 教你做一个Material风格、动画的button(MaterialButton)

    原创作品,转载请注明出处:http://blog.csdn.net/qiujuer/article/details/39831451 前段时间Android L 公布了,相信看过公布会了解过的朋友都为 ...

  6. 开启Fluter基础之旅二-------Future再论、常用组件、Material Design风格组件学习

    Future再论: 这里在继续往下学习之前,先来看一下Dart语言关于Event-Queue和Microtask Queue需要注意的一个小点,这个在之前https://www.cnblogs.com ...

  7. Material Design风格登录注册

    本文实现了以下功能 完整的代码和样例托管在Github 当接口锁定时,防止后退按钮显示在登录Activity 上. 自定义 ProgressDialog来显示加载的状态. 符合材料设计规范. 悬浮标签 ...

  8. 纯CSS Material Design风格按钮

    其实Material Design的扁平化icon按钮,这类型的按钮往往只利用几何色块的变化,就能抓住使用者的眼光,并且从几何形状中明白按钮的含意,这也是Material Design非常强调的设计理 ...

  9. html5 仿微信语音播放器,Material design风格HTML5 audio音频播放器

    jAudio.js是一款基于HTML5 audio的Material design风格音频播放器jQuery插件.该音频播放器可以设置音频播放列表,每首曲子的封面,标题等,还可以控制歌曲的播放和快进, ...

最新文章

  1. Quartz之入门实例
  2. poj1185炮兵阵地
  3. oracle delete原理,如何恢复并理解oracle删除数据的原理
  4. oracle查询file_name,Oracle DG环境下db_file_name_convert的实际意义
  5. c语言判断回文平方数,C/C++回文数的判断(转)
  6. 遇上DG挖矿病毒的处理记录
  7. 查找-动态查找表-二叉排序树
  8. CF刷刷水题找自信 2
  9. Ajax批量上传文件Demo
  10. UDS 协议软件架构
  11. 转自 方倍工作室微信公众平台开发
  12. 关于编译ns3的myfirst.cc问题
  13. mcafee杀死oracle,如何从卸载McAfee卸载工具
  14. jQuery封装的获取Url中的Get参数
  15. The Devil Wears Prada-16
  16. 4、Hangfire在AspNetCore中的使用(一)
  17. 语言 英语名称 中文名称 国家码
  18. 什么叫数字化服务-数字化转型网
  19. (万年历一)JAVA在控制台输出万年历(1900年起)
  20. 中毒后360安全卫士打不开的终极解决办法

热门文章

  1. 对python版本设置版本控制
  2. Leetcode 柠檬水找零
  3. Boolan 软件架构与C++专家团队走进华为,助力软件变革共创技术新生态
  4. 图和树的基本概念与认识
  5. 仿哔哩哔哩动画Android客户端(哔哩哔哩 (゜-゜)つロ 干杯~-bilibili)
  6. web前端开发发展前景,前端开发学习方法
  7. 有关C++几个重要的字符类型,LPCWSTR,LPCSTR,PCWSTR,TCARH
  8. 【一则文章带你了解JavaScript】
  9. try(){}catch(){}
  10. 记一次溯源恶意ip45.123.101.251僵尸网络主机的全过程