前言
如果你有关注Material Design,会发现国内的一些app也在使用material Design这种设计,我常用的网易有道词典就使用了Material Design的规范。
Google I/O 2014 发布 Material Design,1sters 于 2014-09-09 上线中文版,并稳稳占据百度和
Google material design 关键字的第一名。历时一年,官方已经新增 20+ 章节,我们再次发力,于「2015-08-16」翻译校对完毕所有新增章节,重新发布。
极客学院教程链接:http://wiki.jikexueyuan.com/project/material-design/
Material Design,中文名:材料设计语言,是由Google推出的全新的设计语言,谷歌表示,这种设计语言旨在为手机、平板电脑、台式机和“其他平台”提供更一致、更广泛的“外观和感觉”
17个使用Material Design风格的APP界面作品欣赏:http://www.shejidaren.com/17-apps-using-material-design.html
这里就不多介绍Material Design了,这篇文章就来实现遵循Material Design规范,当然以下代码实在xamarin android下实现的,使用DrawerLayout+Toolbar实现侧滑动画效果,兼容android4.3以上版本,以及兼容android4.4以上的“沉浸式”状态栏的效果,最终实现的效果图如下
1. DrawerLayout的简单使用
2. DrawerLayout+ToolBar实现侧滑切换动画效果
3. 完美解决沉浸式状态栏兼容android4.4以上版本
1. DrawerLayout的简单使用
DrawerLayout是v4包下提供的一种左右侧滑的抽屉布局效果,它是一个布局控件,和Linearlayout 、RelativeLayout等布局控件是一个概念,使用起来比较简单,只需要按照drawerlayout的规定布局就会有侧滑的效果,官方建议Drawerlayout作为根布局,的确绝大部分都是这样做的,qq就是的。一个规范侧滑布局包括:Draerlayout作为根布局、侧滑布局(使用layout_gravity=”start/left”标记便是侧滑布局)、主内容布局。下面最简单的一个布局来就能实现最基本的侧滑效果。
<?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"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--主内容布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:id="@+id/btn_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示侧滑布局"/>
</LinearLayout>
<!--侧滑布局-->
<LinearLayout
android:layout_height="match_parent"
android:layout_width="320dp"
android:id="@+id/drwerLayout"
android:background="#ffffff"
android:layout_gravity="start">
<TextView android:id="@+id/tv_drawerContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:text="侧滑内容"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
效果图:
activity代码:
[Activity(Label = "DrawerlayoutAndToolBar", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity, DrawerLayout.IDrawerListener
{
private DrawerLayout _drawerLayout;
private Button btn_openDrawer;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView (Resource.Layout.Main);
_drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawerLayout);
btn_openDrawer = FindViewById<Button>(Resource.Id.btn_openDrawer);
btn_openDrawer.Click +=(s,e)=> {
_drawerLayout.OpenDrawer((int)GravityFlags.Start);
};
}
//侧边视图已经打开时调用
public void OnDrawerClosed(View drawerView)
{
System.Diagnostics.Debug.Write("侧边视图已经关闭");
}
//侧边视图已经关闭时调用
public void OnDrawerOpened(View drawerView)
{
System.Diagnostics.Debug.Write("侧边视图已经打开");
}
//侧边视图正在滑动时调用
public void OnDrawerSlide(View drawerView, float slideOffset)
{
System.Diagnostics.Debug.Write("侧边视图已经关闭");
}
//侧边视图滑动状态发生改变时被调用
public void OnDrawerStateChanged(int newState)
{
System.Diagnostics.Debug.Write("drawer的状态"+newState);
//状态值STATE_IDLE:0是闲置状态,STATE_DRAGGING:1拖拽状态,STATE_SETTLING:2(固定状态)
}
}
要注意以下几点:
- DrawerLayout的第一个子布局必须是主内容布局,如果第一个子布局是侧滑内容布局,就会出现问题,这个你可以自己试试看,将这两个布局对换,就会发现通过手势滑动能打开却不能关闭,点击才能关闭。
- 侧滑视图的宽度不建议超过320dp,官方建议是留出一部分能看到主视图
- 必须指定侧滑视图,通过属性layout_gravity来确定,属性值有start、end或者left 、right。start是从左向右滑出,end是从右向左滑出
- 继承接口DrawerLayout.IDrawerListener,实现OnDrawerClosed、OnDrawerOpened、OnDrawerSlide、OnDrawerStateChanged等方法的监听
2. DrawerLayout+ToolBar实现侧滑切换动画效果
在material design的标准下,我们将使用Drawerlayout+Toolbar实现一个图标切换动画的侧滑效果。
在刚学习使用Toolbar的时候有很多的需要的点,可以看看这篇文章xamarin android toolbar(踩坑完全入门详解),所以这里就不多介绍如何使用Toolbar了。
从开头的那张效果图我们可以看出,明显没有将DrawerLayout作为根布局(官方建议还是作为根布局比较好)。
为了提供的布局的使用效率,首先我们新建一个toolbar的布局toolbar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/toolbar_title" />
</android.support.v7.widget.Toolbar>
</LinearLayout>
然后我们再来新建一个Drawerlayout的规定布局drawerLayout.xml
侧边的布局是一个ListView一般都用来放置导航菜单的。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dl_left"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--主布局-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/iv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_horizontal"
android:text="主布局" />
</LinearLayout>
<!--侧滑菜单-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:layout_gravity="start">
<ListView
android:id="@+id/left_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:text="DrawerLayout" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
最后新建一个主布局:Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar_main" />
<include layout="@layout/drawerLayout" />
</LinearLayout>
主题styles.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
</style>
<style name="AppTheme.DrawerArrowToggle" parent="Base.Widget.AppCompat.DrawerArrowToggle">
<item name="color">@android:color/white</item>
</style>
<color name="primary">#1e89e7</color>
<color name="primaryDark">#1976d2</color>
<color name="red">#ff0000</color>
<color name="white">#ffffff</color>
</resources>
主要实现代码MainActivity.cs
[Activity(Label = "DrawerlayoutAndToolBar", MainLauncher = true, Icon = "@drawable/icon",Theme = "@style/BaseAppTheme")]
public class MainActivity : AppCompatActivity
{
private DrawerLayout _drawerLayout;
private ListView listview_leftMenu;
private Android.Support.V7.Widget.Toolbar toolbar;
private Android.Graphics.Drawables.AnimationDrawable _animationDrawable;
private ActionBarDrawerToggle _drawerToggle;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView (Resource.Layout.Main);
_drawerLayout = FindViewById<DrawerLayout>(Resource.Id.dl_left);
listview_leftMenu = FindViewById<ListView>(Resource.Id.left_menu);
toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
_drawerToggle = new ActionBarDrawerToggle(this, _drawerLayout, toolbar, 0,0);//并没有起效果性作用
string[] menus = new string[] { "首页", "博问", "闪存" };
ArrayAdapter adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleExpandableListItem1,menus);
listview_leftMenu.Adapter = adapter;
toolbar.Title = "Toolbar1";
SetSupportActionBar(toolbar);//设置兼容toolbar,替代原本的actionbar
//SupportActionBar.SetDisplayShowHomeEnabled(true);//设置显示左上角Home图标
//SupportActionBar.SetDisplayHomeAsUpEnabled(true);//设置左上角的左箭头; 这两个必须同时为true才能显示
SupportActionBar.SetDisplayShowTitleEnabled(true);//设置不显示标题
SupportActionBar.SetHomeButtonEnabled(true);//设置返回键可用
SupportActionBar.Title = "Toolbar";
toolbar.Title = "Toolbar1";
toolbar.SetTitleTextColor(Resources.GetColor(Resource.Color.white));
_drawerLayout.SetDrawerListener(_drawerToggle); //设置侧滑监听
_drawerToggle.SyncState(); //设置左箭头与Home图标的切换与侧滑同步
StatusBarUtil.SetColorStatusBar(this);
}
//图标动画效切换的关键:响应action 按钮的点击事件,包括左侧系统的home按钮,left按钮,右侧自定义的菜单等
public override bool OnOptionsItemSelected(IMenuItem item)
{
return base.OnOptionsItemSelected(item) || _drawerToggle.OnOptionsItemSelected(item);
//_drawerToggle.OnOptionsItemSelected(item)兼容android5.0以下的左侧图标切换的动画,不加这句android5.0以下的左上侧按钮无效
}
}
代码比较简单,都注释了。但最尴尬的是toolbar的标题显示不出来,这的确是个问题,在SetSupportActionBar(toolbar)前设置toolbar.title还是没有效果。
ActionBarDrawerToggle是继承DrawerLayout.IDrawerListener,主要的作用是监听DrawerLayout的滑动,还带有切换toolbar左上角的home图标和向左图标的动画效果。
3. 完美解决沉浸式状态栏兼容android4.4以上版本
兼容android4.4“沉浸式”状态栏及以上版本无非就是两种办法1.填充状态栏2.MaginTop,详情参照:http://blog.csdn.net/kebi007/article/details/70215993
这里给我的完美解决方法,使用的是填充状态栏。给它做了一个工具类
public class StatusBarUtil
{
private static View _statusBarView;
/// <summary>
/// 设置颜色状态栏
/// </summary>
/// <param name="activity"></param>
public static void SetColorStatusBar(Activity activity)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
var color = activity.Resources.GetColor(Resource.Color.primary);
//清除透明状态栏,使内容不再覆盖状态栏
activity.Window.ClearFlags(WindowManagerFlags.TranslucentStatus);
activity.Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
activity.Window.SetStatusBarColor(color);
//透明导航栏部分手机导航栏不是虚拟的
//activity.Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
activity.Window.SetNavigationBarColor(color);
}
else if (Build.VERSION.SdkInt == BuildVersionCodes.Kitkat )
{
SetKKStatusBar(activity,Resource.Color.primary);
}
}
//设置透明状态栏,android4.4以上都支持透明化状态
public static void SetTransparentStausBar(Activity activity)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
//状态栏透明
activity.Window.AddFlags(WindowManagerFlags.TranslucentStatus);
//透明导航栏
activity.Window.AddFlags(WindowManagerFlags.TranslucentNavigation);
}
}
public static void SetKKStatusBar(Activity activity ,int statusBarColor)
{
SetTransparentStausBar(activity);//先透明化("去掉"状态栏)
ViewGroup contentView = activity.FindViewById<ViewGroup>(Android.Resource.Id.Content);
_statusBarView = contentView.GetChildAt(0);
//防止重复添加statusBarView
if (_statusBarView != null && _statusBarView.MeasuredHeight == GetStatusBarHeight(activity))
{
_statusBarView.SetBackgroundColor(activity.Resources.GetColor(statusBarColor));
return;
}
_statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent,GetStatusBarHeight(activity));
_statusBarView.SetBackgroundColor(activity.Resources.GetColor(statusBarColor));//填充的到状态栏的view设置颜色
contentView.AddView(_statusBarView,lp);
}
private static int GetStatusBarHeight(Context context)
{
int resourceId = context.Resources.GetIdentifier("status_bar_height", "dimen", "android");
return context.Resources.GetDimensionPixelSize(resourceId);
}
}
总结:toolbar还是无法设置标题。。。。。。。。。
作者:张林
标题:xamarin android实现Toolbar+DrawerLayout完美侧滑导航栏
原文地址:http://blog.csdn.net/kebi007/article/details/77854178
转载随意注明出处