前言
如果你有關注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
轉載隨意註明出處