做为一个 Android developer,没有什么比拿着 UI 设计的一堆 iOS 风格的设计 来作需求更恶心的了,基本全部空间都要照着 iOS 来画一遍,Material Design 辣么酷炫 为何 UI在设计的阶段不设计成 Material Design风格呢?html
今天试了几个比较Support包中比较典型的Material Design控件,后期会在学习下Material Design的设计思想和理念,但愿能拉着 UI 作一次Material Design 分享,改变咱们 APP 的 iOS 风格啊。java
在 build.gradle
中加入support 包git
1
|
compile 'com.android.support:appcompat-v7:23.1.1' |
Design Support Library 中包含了 Support v4 和 AppCompat v7github
咱们但愿FloatingActionButton
悬浮在页面的右下方,因此咱们父节点应使用Flowlayout
api
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="io.github.xuyushi.materialdesigndemo.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <android.support.design.widget.FloatingActionButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:src="@android:drawable/ic_dialog_email" /> </FrameLayout> |
和普通 button 同样能够设置其点击事件app
1
2 3 4 5 6 7 8 9 |
private void initFb() { mFb = (FloatingActionButton) findViewById(R.id.fb); mFb.setOnClickListener(new View.OnClickListener() { |
Android:elevation
属性为 view 在空闲状态下的阴影深度, 须要在 api 21以上才能使用,使用 support 包可使用app:elevation
来表示空闲状态高度,app:pressedTanslationZ
为按下状态的高度ide
按钮的颜色通常为主题的强调色,也可使用 ”app:backgroundTint“修改布局
和 Toast 很像,snackbar 能够展现一段简单的信息,不一样点是它的展现更像是总体 UI 的一部分,不是想 toast 同样是浮在 UI 上的,而且能够有简单的交互post
在点击 floatingActionButton时显示Snackbar
可是能够看到,Snackbar 遮挡住了咱们的 view,这时候须要一个CoordinatorLayout
来协调 view 布局
将父布局中的framelaout
换成CoordinatorLayout
,其余不变,再来看看效果
==todo CoordinatorLayout学习==
Toolbar 比传统的 ActionBar 更灵活,功能也更多,咱们能够看到如今市面上不少的 APP 已经用 Toolbar 替代了 actionbar,在 Desgin Support 的组件中,不少设计均可以和 Toolbar 协同工做,而不是和 actionbar,因此仍是建议使用新的 toolbar 替换之前的 actionbar
替换步骤
一、在 minifest 中,将 activity 的 apptheme 的 style 中的 actionbar属性去掉
1
2 3 4 5 6 7 8 9 10 11 12 |
<style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<android.support.design.widget.CoordinatorLayout
......... <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/ThemeOverlay.AppCompat.Light" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:src="@android:drawable/ic_dialog_email" app:elevation="12dp" app:pressedTranslationZ="30dp" /> </android.support.design.widget.CoordinatorLayout> |
1
2 3 4 |
private void initToolbar() { mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); } |
CoordinatorLayout
中的 view 必须是能一同协做的 view,就像 Snackbar 同样,可是 toolbar 并非这样能协同做战的 view,因此咱们须要用一个能够协同做战的 view 来包裹上Toolbar
,这就是 AppBarLayout
如今咱们的布局文件结构是这样的
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
<android.support.design.widget.CoordinatorLayout ...> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar .../> </android.support.design.widget.AppBarLayout> <android.support.design.widget.FloatingActionButton ...> </android.support.design.widget.FloatingActionButton> </android.support.design.widget.CoordinatorLayout> |
注意
根据官方的谷歌文档,AppBarLayout目前必须是第一个嵌套在CoordinatorLayout里面的子view
在 toolbar 中加入属性,app:layout_collapseMode=”pin”,使得 Toolbar 中的按钮能固定在顶部
在布局中尝试加入一些按钮
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
....
</android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="test" /> </LinearLayout> ... |
咱们定义三个按键,却被 toolbar 遮住了一个,缘由是LinearLayout
并无被设计成在CoordinatorLayout
协同工做的模式,为了使他们能在CoordinatorLayout
协同工做,咱们须要在LinearLayout
加上一条属性,来告诉它的滚动属性()
1
2 3 4 5 |
<LinearLayout ... app:layout_behavior="@string/appbar_scrolling_view_behavior" ... > |
搞定
根据官网的知道,TabLayout
一般应该是放在顶部,(iOS 的 tab 好像基本在底部),
他应该在阴影部分上面,因此应该放在AppBarlayout
中
1
2 3 4 5 6 7 |
<android.support.design.widget.AppBarLayout ...> <android.support.v7.widget.Toolbar ... /> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content"/> </android.support.design.widget.AppBarLayout> |
java 中设置这些 tab 属性
1
2 3 4 5 6 |
private void initTableLayout() { mTabLayout = (TabLayout) findViewById(R.id.tabLayout); mTabLayout.addTab(mTabLayout.newTab().setText("Tab 1")); mTabLayout.addTab(mTabLayout.newTab().setText("Tab 2")); mTabLayout.addTab(mTabLayout.newTab().setText("Tab 3")); } |
背景会设置为主题色,导航线是强调色。可是字仍是黑色的,由于咱们没有为 tablayout 定义主题,
1
2 3 |
<android.support.design.widget.TabLayout ... app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> |
一般 tablayout 会和ViewPager
一块儿使用 ,这时候使用public void setupWithViewPager (ViewPager viewPager)
当滑档内容时,为了腾出跟多的空间展现内容能够将AppBarLayout
隐藏
1.用 scrollView 包裹 LinearLayout,记得加上 app:layout_behavior
属性
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > ... </LinearLayout> </ScrollView> |
1
2 3 |
<android.support.v7.widget.Toolbar ... app:layout_scrollFlags="scroll|enterAlways" /> |
若是但愿 tablayout 也消失,只须要和 tablayout 加上相同的属性就好了
1
2 3 |
<android.support.design.widget.TabLayout ... app:layout_scrollFlags="scroll|enterAlways" /> |
咱们须要定义AppBarLayout与滚动视图之间的联系。在RecyclerView或者任意支持嵌套滚动的view好比NestedScrollView上添加app:layout_behavior。support library包含了一个特殊的字符串资源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用来通知AppBarLayout 这个特殊的view什么时候发生了滚动事件,这个behavior须要设置在触发事件(滚动)的view之上
当CoordinatorLayout发现scrollView中定义了这个属性,它会搜索本身所包含的其余view,看看是否有view与这个behavior相关联。AppBarLayout.ScrollingViewBehavior描述了RecyclerView与AppBarLayout之间的依赖关系。RecyclerView的任意滚动事件都将触发AppBarLayout或者AppBarLayout里面view的改变。
AppBarLayout里面定义的view只要设置了app:layout_scrollFlags属性,就能够在RecyclerView滚动事件发生的时候被触发:
app:layout_scrollFlags属性里面必须至少启用scroll这个flag,这样这个view才会滚动出屏幕,不然它将一直固定在顶部。可使用的其余flag有:
记住,要把带有scroll flag的view放在前面,这样收回的view才能让正常退出,而固定的view继续留在顶部。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="256dp"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsingToolbarLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> |
注意 CollapsingToolbarLayout 的高度是android:layout_height="match_parent"
CollapsingToolbarLayout在展开和收缩时,标题的文字会自动过分的,能够经过 app:expandedTitleMargin 等来改变文字位置
因为 CollapsingToolbarLayout 是继承 Framelayout 的,因此咱们能够直接添加一个 ImageView 做为背景图片
1
2 3 4 5 6 7 8 |
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/header" /> <android.support.v7.widget.Toolbar ... |
此时虽然背景已经出来了,可是蓝色的导航条依旧存在,须要在 toolbar 去掉这条属性
1
|
android:background="?attr/colorPrimary"
|
给 Imageview 加上视差模式会更帅
1
2 |
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5" |
也能够在最后恢复成主题色
1
2 3 |
<android.support.design.widget.CollapsingToolbarLayout ... app:contentScrim="?attr/colorPrimary"> |
AppBarLayout
布局下,增DrawerLayout
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<android.support.design.widget.AppBarLayout> ... <android.support.v4.widget.DrawerLayout 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" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:openDrawer="start"> <include layout="@layout/content_main" /> <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_main2" app:menu="@menu/activity_main2_drawer" /> </android.support.v4.widget.DrawerLayout> |
DrawerLayout
中分两部分组成,一部分是content 就是咱们须要的主布局内容,另外一部分是咱们的抽屉的布局,NavigationView中有顶部头,和标签
1
2 |
app:headerLayout="@layout/nav_header_main2"
app:menu="@menu/activity_main2_drawer" |
菜单元素是放在group标签之下,同时声明每次只能有一个item被选中:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_camera" android:icon="@drawable/ic_menu_camera" android:title="Import" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_menu_gallery" android:title="Gallery" /> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_menu_slideshow" android:title="Slideshow" /> <item android:id="@+id/nav_manage" android:icon="@drawable/ic_menu_manage" android:title="Tools" /> </group> <item android:title="Communicate"> <menu> <item android:id="@+id/nav_share" android:icon="@drawable/ic_menu_share" android:title="Share" /> <item android:id="@+id/nav_send" android:icon="@drawable/ic_menu_send" android:title="Send" /> </menu> </item> </menu> |
为了防止页面被遮盖,一样要使得 DrawerLayout
协调。加入app:layout_behavior="@string/appbar_scrolling_view_behavior"
属性
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
private void initDraw() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { |
在NestedScrollView
外在包裹一层SwipeRefreshLayout
,
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true" > ..... </android.support.v4.widget.NestedScrollView> </android.support.v4.widget.SwipeRefreshLayout> |
初始化监听器
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private void initRefresh() { mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh); mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { |
失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了全部通向失败的路,只剩下一条路,那就是成功的路
转载自:http://www.cnblogs.com/android-blogs/p/5632103.html