DrawerLayout 模仿google官方左滑,menu内容延伸到通知栏
2016-04-18 20:46
477 查看
NavigationView extends ScrimInsetsFrameLayout
最近做项目,要模仿google官方应用,使用drawerLayout,达到如下效果
即,menu栏的顶部可以显示到通知栏中。
1. 使用NavigationVIew 作为menu ,并且需要在DrawerLayout ,NavigationView 设置 android:fitsSystemWindows="true" 属性,该属性可以写在xml中,也可以使用代码,但是注意使用地方,当其用到做为activivty 的 theme 时,会引发toast 布局错位,文本显示不全的问题。
<?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" android:fitsSystemWindows="true" tools:openDrawer="start"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@android:color/holo_red_light"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> <Button android:id="@+id/nextbtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nextBtn"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout>
在这里使用了toolbar ,
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 需啊添加以下代码,setSupportActionBar(toolbar);
values-21 ,设置属性
<pre name="code" class="html"> <style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> </style>
2. 当menu使用的是其他控件,例如listview。
<pre name="code" class="html"><com.instanza.cocovoice.uiwidget.HackyDrawerLayout 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" android:fitsSystemWindows="true" tools:context=".MainActivity"> <com.instanza.cocovoice.activity.base.SomaActionbarFrameLayout android:id="@+id/frame" android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="match_parent"/> <com.instanza.cocovoice.uiwidget.ScrimInsetsFrameLayout android:id="@+id/drawer_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" app:insetForeground="#4000" android:fitsSystemWindows="true"> <ListView android:id="@+id/drawer_listview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/white" android:choiceMode="singleChoice" android:divider="@null" android:scrollbars="none"></ListView> </com.instanza.cocovoice.uiwidget.ScrimInsetsFrameLayout> </com.instanza.cocovoice.uiwidget.HackyDrawerLayout>
主要是listview要有个父控件ScrimInsetsFrameLayout,
app:insetForeground="#4000" 则是设置遮罩的阴影颜色。
<pre name="code" class="html">public class ScrimInsetsFrameLayout extends FrameLayout{ private Drawable mInsetForeground; private Rect mInsets; private Rect mTempRect = new Rect(); private OnInsetsCallback mOnInsetsCallback; public ScrimInsetsFrameLayout(Context context) { super(context); init(context, null, 0); } public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } public ScrimInsetsFrameLayout( Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } private void init(Context context, AttributeSet attrs, int defStyle) { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScrimInsetsView, defStyle, 0); if (a == null) { return; } mInsetForeground = a.getDrawable( R.styleable.ScrimInsetsView_insetForeground); a.recycle(); setWillNotDraw(true); } @Override protected boolean fitSystemWindows(Rect insets) { mInsets = new Rect(insets); setWillNotDraw(mInsetForeground == null); ViewCompat.postInvalidateOnAnimation(this); if (mOnInsetsCallback != null) { mOnInsetsCallback.onInsetsChanged(insets); } return true; // consume insets } @Override public void draw(Canvas canvas) { super.draw(canvas); int width = getWidth(); int height = getHeight(); if (mInsets != null && mInsetForeground != null) { int sc = canvas.save(); canvas.translate(getScrollX(), getScrollY()); // Top mTempRect.set(0, 0, width, mInsets.top); mInsetForeground.setBounds(mTempRect); mInsetForeground.draw(canvas); // Bottom mTempRect.set(0, height - mInsets.bottom, width, height); mInsetForeground.setBounds(mTempRect); mInsetForeground.draw(canvas); // Left mTempRect.set( 0, mInsets.top, mInsets.left, height - mInsets.bottom); mInsetForeground.setBounds(mTempRect); mInsetForeground.draw(canvas); // Right mTempRect.set( width - mInsets.right, mInsets.top, width, height - mInsets.bottom); mInsetForeground.setBounds(mTempRect); mInsetForeground.draw(canvas); canvas.restoreToCount(sc); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (mInsetForeground != null) { mInsetForeground.setCallback(this); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mInsetForeground != null) { mInsetForeground.setCallback(null); } } /** * Allows the calling container to specify a callback for custom * processing when insets change (i.e. when {@link #fitSystemWindows(Rect)} * is called. This is useful for setting padding on UI elements * based on UI chrome insets (e.g. a Google Map or a ListView). * When using with ListView or GridView, remember to set * clipToPadding to false. */ public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) { mOnInsetsCallback = onInsetsCallback; } public static interface OnInsetsCallback { public void onInsetsChanged(Rect insets); } }
在values-21
<pre name="code" class="html"><style name="Theme.App" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> </style>
其实,第一种与第二种是一致的,因为
NavigationView extends ScrimInsetsFrameLayout
相关文章推荐
- 二叉搜索树实现 in Go语言
- HDU 1824 Let's go home 2-Sat
- golang交叉编译
- Good Tools for downloading Youtube source
- 2016 Google Code Jam Round 1A (A. The Last Word,B. Rank and File,C. BFFs(二元环))
- django 更改默认语言和时间
- 李艺:Go语言之内的结构体模拟继承
- django提供xml下载
- Google Codejam 2016 Round1A Problem C BFFs 简单图论
- Django笔记 Model的继承和操作
- GOF设计模式快速学习
- Django笔记 CMS框架Mezzanine 2
- Google官方MVP示例之TODO-MVP
- 一起学Django之Day01
- google的Guava库的callback使用分析
- phyton3.5 django典型错误
- AlexNet, VGGNet, GoogLeNet 对比
- django ORM model filter 条件过滤,及多表连接查询、反向查询字段
- google chrome当图片不显示时,默认显示边框的解决办法
- Ajax请求在IE和Google Chrome中可以响应,在Firefox中无法响应