先po一张效果图
PS:原谅题主的懒惰吧..
看着是不是很酷炫,那是因为5.0的动画做得好,代码其实没有多少,搞清楚这个布局的层次关系很重要。
废话不多说了,先来看布局文件
最外层是一个DrawerLayout,它里面可以嵌套(一个?)container和多个drawer
在这个demo中DrawerLayout包含了一个CoordinatorLayout , ListView , NavigationView
CoordinatorLayout 作为 container的根布局
listView和navigationview作为DarwerLayout中的darwer
在container中用CoordinatorLayout目的是为了我们在滑动recyclerview时,让顶部的appbarlayout中的组件产生响应
appbarlayout中的CollapsingToolbarLayout是用来控制toolbar和banner图片的响应效果
特别注意:为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如 RecyclerView,NestedScrollView(经过测试,ListView,ScrollView不支持)具有滑动效果的组件。
下面的就是drawerLayout的使用注意事项了:
按情理来说,一个drawerLayout添加一个drawer就够了,可是脑洞一开,想着多加一个会怎样,尝试之后发现很好玩,以后可以各种乱入drawer了,哈哈哈。
因为做毕设的时候用的DrawerLayout还不是这样方便的,那会使用这个布局,设置起来麻烦很多,而现在的实现这个布局,布局文件设置好之后,只用三句话就搞定了,简单的可怕。
下面贴上源码,各位看官就自行分析吧:
主布局文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@+id/drawer_layout" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical"> 8 9 <android.support.design.widget.CoordinatorLayout 10 android:id="@+id/main_content" 11 android:layout_width="match_parent" 12 android:layout_height="match_parent"> 13 14 <android.support.design.widget.AppBarLayout 15 android:id="@+id/app_bar_layout" 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 19 20 <android.support.design.widget.CollapsingToolbarLayout 21 android:id="@+id/collapsing_toolbar_layout" 22 android:layout_width="match_parent" 23 android:layout_height="match_parent" 24 app:contentScrim="@android:color/transparent" 25 app:layout_scrollFlags="scroll|exitUntilCollapsed"> 26 27 <ImageView 28 android:id="@+id/banner" 29 android:layout_width="match_parent" 30 android:layout_height="match_parent" 31 android:contentDescription="banner" 32 android:scaleType="fitXY" 33 android:src="@mipmap/banner" 34 app:layout_collapseMode="parallax" 35 app:layout_collapseParallaxMultiplier="0.5" /> 36 37 <android.support.v7.widget.Toolbar 38 android:id="@+id/tool_bar" 39 android:layout_width="match_parent" 40 android:layout_height="?attr/actionBarSize" 41 android:background="@android:color/transparent" 42 app:layout_collapseMode="pin" /> 43 </android.support.design.widget.CollapsingToolbarLayout> 44 </android.support.design.widget.AppBarLayout> 45 46 <android.support.v7.widget.RecyclerView 47 android:id="@+id/recycler_view" 48 android:layout_width="match_parent" 49 android:layout_height="wrap_content" 50 app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 51 52 <android.support.design.widget.FloatingActionButton 53 android:id="@+id/fab" 54 android:layout_width="wrap_content" 55 android:layout_height="wrap_content" 56 android:layout_margin="@dimen/activity_vertical_margin" 57 android:src="@mipmap/ic_action_web_site" 58 app:borderWidth="0dp" 59 app:elevation="@dimen/fab_elevation" 60 app:layout_anchor="@id/app_bar_layout" 61 app:layout_anchorGravity="end|bottom" 62 app:layout_collapseMode="parallax" 63 app:layout_collapseParallaxMultiplier="0.7" 64 app:pressedTranslationZ="@dimen/fab_translation_z_pressed" 65 app:rippleColor="?attr/colorPrimary" /> 66 </android.support.design.widget.CoordinatorLayout> 67 68 69 <ListView 70 android:id="@+id/id_lv_left_menu" 71 android:layout_width="match_parent" 72 android:layout_height="match_parent" 73 android:layout_gravity="end" 74 android:paddingTop="0dp" 75 android:background="#ffffffff" 76 android:clipToPadding="false" 77 android:divider="@null" 78 android:listSelector="?attr/selectableItemBackground" 79 /> 80 81 <!--<include--> 82 <!--android:layout_width="match_parent"--> 83 <!--android:layout_height="match_parent"--> 84 <!--android:layout_gravity="start"--> 85 <!--android:paddingTop="0dp"--> 86 <!--android:background="#ffffffff"--> 87 <!--android:clipToPadding="false"--> 88 <!--android:id="@+id/custom_drawer"--> 89 <!--layout="@layout/layout_listview_drawer" />--> 90 91 92 <android.support.design.widget.NavigationView 93 android:id="@+id/navigation_view" 94 android:layout_width="wrap_content" 95 android:layout_height="match_parent" 96 android:layout_gravity="start" 97 app:headerLayout="@layout/drawer_header" 98 app:menu="@menu/menu_navigation_items" /> 99 100 </android.support.v4.widget.DrawerLayout>
Activity文件:
1 package com.anhry.hcol.support.design.activity; 2 3 import android.os.Bundle; 4 import android.support.design.widget.AppBarLayout; 5 import android.support.design.widget.CollapsingToolbarLayout; 6 import android.support.design.widget.CoordinatorLayout; 7 import android.support.design.widget.FloatingActionButton; 8 import android.support.design.widget.NavigationView; 9 import android.support.design.widget.Snackbar; 10 import android.support.v4.view.GravityCompat; 11 import android.support.v4.widget.DrawerLayout; 12 import android.support.v7.app.AppCompatActivity; 13 import android.support.v7.widget.LinearLayoutManager; 14 import android.support.v7.widget.RecyclerView; 15 import android.support.v7.widget.Toolbar; 16 import android.view.Gravity; 17 import android.view.LayoutInflater; 18 import android.view.MenuItem; 19 import android.view.View; 20 import android.widget.AdapterView; 21 import android.widget.ImageButton; 22 import android.widget.ImageView; 23 import android.widget.ListView; 24 25 import com.anhry.hcol.support.design.adapter.LeftMenuListAdapter; 26 import com.anhry.hcol.support.design.adapter.MenuItemAdapter; 27 import com.anhry.hcol.support.design.module.LvMenuItem; 28 import com.yanbober.support_library_demo.R; 29 import com.yanbober.support_library_demo.RecyclerViewAdapter; 30 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.List; 34 35 /** 36 * @author HCol 37 * @email [email protected] 38 * @create 2015/8/25 39 * @modify 2015年8月29日17:29:04 40 */ 41 public class DesignDemoActivity extends AppCompatActivity { 42 43 /** 44 * views 45 */ 46 private DrawerLayout mDrawerLayout; 47 private CoordinatorLayout mCoordinatorLayout; 48 private AppBarLayout mAppBarLayout; 49 private CollapsingToolbarLayout mCollapsingToolbarLayout; 50 private ImageView mImageView; 51 private Toolbar mToolbar; 52 private RecyclerView mRecyclerView; 53 private NavigationView mNavigationView; 54 private FloatingActionButton mFloatingActionButton; 55 private ImageView mRightNavigationBtn; 56 57 private CoordinatorLayout mCustomDrawer; 58 private RecyclerView leftMenuList; 59 60 private ListView mLvLeftMenu; 61 /** 62 * members 63 */ 64 private RecyclerViewAdapter mAdapter; 65 private LinearLayoutManager mRecyclerLayoutManager; 66 private LeftMenuListAdapter mLeftMenuListAdapter; 67 private List<LvMenuItem> dataSource; 68 private static final String BTN_RIGHT_MENU_TAG = "tag"; 69 70 @Override 71 protected void onCreate(Bundle savedInstanceState) { 72 super.onCreate(savedInstanceState); 73 74 initViews(); 75 } 76 77 /** 78 * init views 79 */ 80 private void initViews() { 81 setContentView(R.layout.activity_my_design); 82 /* 抽屉形式界面的的两个布局控件 83 * 84 * DrawerLayout 做根布局使用 85 * 因为要显示的内容界面和抽屉视图(NavigationView)是包含在此layout之下的 86 * 87 * NavigationView 抽屉布局中的抽屉视图,有源码分析他的实现其实就是一个ListView 88 * 而这里用的是原生的组件,所以在Menu目录下配置好要显示的条目,引用即可,非常方便. 89 * 90 * ref:http://blog.csdn.net/lmj623565791/article/details/46405409 91 * 92 * */ 93 // 原生DrawerLayout 94 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 95 96 // 利用ListView仿制的Drawer 97 mLvLeftMenu = (ListView) findViewById(R.id.id_lv_left_menu); 98 setUpDrawer(); 99 100 // 不用在意这一块 101 // mCustomDrawer = (CoordinatorLayout) findViewById(R.id.custom_drawer); 102 // leftMenuList = (RecyclerView) findViewById(R.id.rv_left_menu); 103 // dataSource = new ArrayList<>( 104 // Arrays.asList( 105 // new LvMenuItem(R.mipmap.ic_action_web_site, "Home"), 106 // new LvMenuItem(R.mipmap.ic_action_web_site, "Messages"), 107 // new LvMenuItem(R.mipmap.ic_action_web_site, "Friends"), 108 // new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 109 // new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 110 // new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 111 // new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 112 // new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 113 // new LvMenuItem(), 114 // new LvMenuItem("Sub Items"), 115 // new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 1"), 116 // new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 2") 117 // )); 118 // mLeftMenuListAdapter = new LeftMenuListAdapter(this, dataSource); 119 // mRecyclerLayoutManager = new LinearLayoutManager(this); 120 // leftMenuList.setAdapter(mLeftMenuListAdapter); 121 // leftMenuList.setLayoutManager(mRecyclerLayoutManager); 122 123 mNavigationView = (NavigationView) findViewById(R.id.navigation_view); 124 mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { 125 @Override 126 public boolean onNavigationItemSelected(MenuItem menuItem) { 127 mDrawerLayout.closeDrawers(); 128 return true; 129 } 130 }); 131 /* 下面就是抽屉布局中[内容布局]的重点了 132 * 133 * CoordinatorLayout 协调者布局 134 * AppBarLayout 导航栏布局 135 * CollapsingToolbarLayout ToolBar的可坍塌布局 136 * 137 * 首先,这三个布局有什么用呢? 138 * 139 * CoordinatorLayout 140 * 官方文档介绍说是一个增强版的FrameLayout 141 * 有两种主要的用途: 142 * 1. 作为一个顶层布局文件来使用 143 * 2. 作为一个有[多个互动视图]的容器 144 * 就是当某一视图有特殊行为动作时,其他子视图会进行相应的动作反应。INTERACTION 145 * 146 * AppBarLayout 147 * 一个模块化的布局文件,可以用来装载一切属于AppBar的组件 148 * 149 * CollapsingToolbarLayout 150 * 151 * CollapsingToolbarLayout is a wrapper for Toolbar which implements a collapsing app bar. 152 * It is designed to be used as a direct child of a AppBarLayout. 153 * 154 * 官方说,它的诞生主要是用来为toolbar锦上添花用的 155 * 被设计来作为AppBarLayout的亲儿子来使用 156 * 157 * */ 158 mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.main_content); 159 mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar_layout); 160 mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout); 161 mImageView = (ImageView) findViewById(R.id.banner); 162 mToolbar = (Toolbar) findViewById(R.id.tool_bar); 163 164 // 创建右边导航按钮 165 ensureRightButtonView(); 166 mToolbar.setNavigationIcon(R.mipmap.ic_drawer); 167 mToolbar.addView(mRightNavigationBtn); 168 mToolbar.setNavigationOnClickListener(new View.OnClickListener() { 169 @Override 170 public void onClick(View v) { 171 mDrawerLayout.openDrawer(GravityCompat.START); 172 } 173 }); 174 mCollapsingToolbarLayout.setTitle("CollapsingTitle"); 175 /* init RecyclerView */ 176 mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 177 mAdapter = new RecyclerViewAdapter(this); 178 mRecyclerView.setAdapter(mAdapter); 179 mRecyclerLayoutManager = new LinearLayoutManager(this); 180 mRecyclerView.setLayoutManager(mRecyclerLayoutManager); 181 182 mFloatingActionButton = (FloatingActionButton)findViewById(R.id.fab); 183 mFloatingActionButton.setOnClickListener(new View.OnClickListener() { 184 @Override 185 public void onClick(View v) { 186 Snackbar.make(mRecyclerView , "papa i‘m here" , Snackbar.LENGTH_LONG).show(); 187 } 188 }); 189 } 190 191 private void setUpDrawer() { 192 LayoutInflater inflater = LayoutInflater.from(this); 193 mLvLeftMenu.addHeaderView(inflater.inflate(R.layout.drawer_header, mLvLeftMenu, false)); 194 mLvLeftMenu.setAdapter(new MenuItemAdapter(this)); 195 mLvLeftMenu.setOnItemClickListener(new AdapterView.OnItemClickListener() { 196 @Override 197 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 198 mDrawerLayout.closeDrawers(); 199 } 200 }); 201 } 202 203 private void ensureRightButtonView() { 204 if (mRightNavigationBtn == null) { 205 mRightNavigationBtn = new ImageButton(this, null, 206 android.support.v7.appcompat.R.attr.toolbarNavigationButtonStyle); 207 final Toolbar.LayoutParams lp = generateDefaultLayoutParams(); 208 lp.gravity = GravityCompat.END | (Gravity.TOP & Gravity.VERTICAL_GRAVITY_MASK); 209 mRightNavigationBtn.setImageResource(R.mipmap.ic_drawer); 210 mRightNavigationBtn.setLayoutParams(lp); 211 mRightNavigationBtn.setTag(BTN_RIGHT_MENU_TAG); 212 mRightNavigationBtn.setOnClickListener(new View.OnClickListener() { 213 @Override 214 public void onClick(View v) { 215 mDrawerLayout.openDrawer(GravityCompat.END); 216 } 217 }); 218 } 219 } 220 221 private Toolbar.LayoutParams generateDefaultLayoutParams() { 222 return new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.WRAP_CONTENT); 223 } 224 }
drawer head:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:background="#000000" 6 android:gravity="center_horizontal" 7 android:orientation="vertical" 8 android:padding="13dp"> 9 10 <ImageView 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:src="@drawable/icon_people" /> 14 15 <TextView 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:layout_marginTop="15dp" 19 android:text="UserName" 20 android:textColor="?attr/colorAccent" 21 android:textSize="24sp" /> 22 </LinearLayout>
ListViewAdapter:
1 public class MenuItemAdapter extends BaseAdapter { 2 private final int mIconSize; 3 private LayoutInflater mInflater; 4 private Context mContext; 5 6 public MenuItemAdapter(Context context) { 7 mInflater = LayoutInflater.from(context); 8 mContext = context; 9 10 mIconSize = context.getResources().getDimensionPixelSize(R.dimen.abc_dialog_padding_material);//24dp 11 } 12 13 private List<LvMenuItem> mItems = new ArrayList<LvMenuItem>( 14 Arrays.asList( 15 new LvMenuItem(R.mipmap.ic_action_web_site, "Home"), 16 new LvMenuItem(R.mipmap.ic_action_web_site, "Messages"), 17 new LvMenuItem(R.mipmap.ic_action_web_site, "Friends"), 18 new LvMenuItem(R.mipmap.ic_action_web_site, "Discussion"), 19 new LvMenuItem(), 20 new LvMenuItem("Sub Items"), 21 new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 1"), 22 new LvMenuItem(R.mipmap.ic_action_web_site, "Sub Item 2") 23 )); 24 25 26 @Override 27 public int getCount() { 28 return mItems.size(); 29 } 30 31 32 @Override 33 public Object getItem(int position) { 34 return mItems.get(position); 35 } 36 37 38 @Override 39 public long getItemId(int position) { 40 return position; 41 } 42 43 @Override 44 public int getViewTypeCount() { 45 return 3; 46 } 47 48 @Override 49 public int getItemViewType(int position) { 50 return mItems.get(position).type; 51 } 52 53 @Override 54 public View getView(int position, View convertView, ViewGroup parent) { 55 LvMenuItem item = mItems.get(position); 56 switch (item.type) { 57 case LvMenuItem.TYPE_NORMAL: 58 if (convertView == null) { 59 convertView = mInflater.inflate(R.layout.design_drawer_item, parent, 60 false); 61 } 62 TextView itemView = (TextView) convertView; 63 itemView.setText(item.name); 64 Drawable icon = mContext.getResources().getDrawable(item.icon); 65 setIconColor(icon); 66 if (icon != null) { 67 icon.setBounds(0, 0, mIconSize, mIconSize); 68 TextViewCompat.setCompoundDrawablesRelative(itemView, icon, null, null, null); 69 } 70 71 break; 72 case LvMenuItem.TYPE_NO_ICON: 73 if (convertView == null) { 74 convertView = mInflater.inflate(R.layout.design_drawer_item_subheader, 75 parent, false); 76 } 77 TextView subHeader = (TextView) convertView; 78 subHeader.setText(item.name); 79 break; 80 case LvMenuItem.TYPE_SEPARATOR: 81 if (convertView == null) { 82 convertView = mInflater.inflate(R.layout.design_drawer_item_separator, 83 parent, false); 84 } 85 break; 86 } 87 88 return convertView; 89 } 90 91 public void setIconColor(Drawable icon) { 92 int textColorSecondary = android.R.attr.textColorSecondary; 93 TypedValue value = new TypedValue(); 94 if (!mContext.getTheme().resolveAttribute(textColorSecondary, value, true)) { 95 return; 96 } 97 int baseColor = mContext.getResources().getColor(value.resourceId); 98 icon.setColorFilter(baseColor, PorterDuff.Mode.MULTIPLY); 99 } 100 }
Item:
1 public class LvMenuItem { 2 3 public LvMenuItem(int icon, String name) { 4 this.icon = icon; 5 this.name = name; 6 7 if (icon == NO_ICON && TextUtils.isEmpty(name)) { 8 type = TYPE_SEPARATOR; 9 } else if (icon == NO_ICON) { 10 type = TYPE_NO_ICON; 11 } else { 12 type = TYPE_NORMAL; 13 } 14 15 if (type != TYPE_SEPARATOR && TextUtils.isEmpty(name)) { 16 throw new IllegalArgumentException("you need set a name for a non-SEPARATOR item"); 17 } 18 } 19 20 public LvMenuItem(String name) { 21 this(NO_ICON, name); 22 } 23 24 public LvMenuItem() { 25 this(null); 26 } 27 28 public static final int NO_ICON = 0; 29 public static final int TYPE_NORMAL = 0; 30 public static final int TYPE_NO_ICON = 1; 31 public static final int TYPE_SEPARATOR = 2; 32 33 public int type; 34 public String name; 35 public int icon; 36 }
Item的资源文件:
design_drawer_item_separator:
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content"> 5 6 <View android:layout_width="match_parent" 7 android:layout_height="1dp" 8 android:background="?android:attr/listDivider"/> 9 10 </FrameLayout>
design_drawer_item_subheader:
1 <?xml version="1.0" encoding="utf-8"?> 2 <TextView xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="?attr/listPreferredItemHeightSmall" 5 android:gravity="center_vertical|start" 6 android:maxLines="1" 7 android:paddingLeft="?attr/listPreferredItemPaddingLeft" 8 android:paddingRight="?attr/listPreferredItemPaddingRight" 9 android:textAppearance="?attr/textAppearanceListItem" 10 android:textColor="?android:textColorSecondary"/>
design_drawer_item:
1 <?xml version="1.0" encoding="utf-8"?> 2 <TextView 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="?attr/listPreferredItemHeightSmall" 6 android:paddingLeft="?attr/listPreferredItemPaddingLeft" 7 android:paddingRight="?attr/listPreferredItemPaddingRight" 8 android:drawablePadding="32dp" 9 android:gravity="center_vertical|start" 10 android:maxLines="1" 11 android:textAppearance="?attr/textAppearanceListItem" 12 android:textColor="?android:attr/textColorPrimary"/>
参考资料:
http://www.2cto.com/kf/201506/409067.html
http://www.open-open.com/lib/view/open1433385856119.html#_label8
http://blog.csdn.net/lmj623565791/article/details/46405409
PS:为什么放多个drawer,而drawerLayout打开drawer的时候不会混乱呢?
没事就看看源码,反正又不要钱..