日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

讓你的 APP換上Material Design

 飲茶仙人 2017-05-02

 Material Design

我的更多 Android 博文,關(guān)注作者~每周更新一篇 Android干貨博文
http://xuyushi./archives/

吐槽

作為一個(gè) Android developer,沒有什么比拿著 UI 設(shè)計(jì)的一堆 iOS 風(fēng)格的設(shè)計(jì) 來做需求更惡心的了,基本所有空間都要照著 iOS 來畫一遍,Material Design 辣么酷炫 為什么 UI在設(shè)計(jì)的階段不設(shè)計(jì)成 Material Design風(fēng)格呢?

今天試了幾個(gè)比較Support包中比較典型的Material Design控件,后期會(huì)在學(xué)習(xí)下Material Design的設(shè)計(jì)思想和理念,希望能拉著 UI 做一次Material Design 分享,改變我們 APP 的 iOS 風(fēng)格啊。

最終效果如下


Android Design Support 庫依賴

在 build.gradle 中加入support 包

    compile 'com.android.support:appcompat-v7:23.1.1'

Design Support Library 中包含了 Support v4 和 AppCompat v7

Floating Action Button


我們希望FloatingActionButton懸浮在頁面的右下方,所以我們父節(jié)點(diǎn)應(yīng)使用Flowlayout

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas./apk/res/android"
    xmlns:tools="http://schemas./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 一樣可以設(shè)置其點(diǎn)擊事件

private void initFb() {
        mFb = (FloatingActionButton) findViewById(R.id.fb);
        mFb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "fb  predsed ", Toast.LENGTH_SHORT).show();
            }
        });
    }

Android:elevation屬性為 view 在空閑狀態(tài)下的陰影深度, 需要在 api 21以上才能使用,使用 support 包可以使用app:elevation 來表示空閑狀態(tài)高度,app:pressedTanslationZ為按下狀態(tài)的高度

按鈕的顏色一般為主題的強(qiáng)調(diào)色,也可以使用 ”app:backgroundTint“修改

Snackbar

和 Toast 很像,snackbar 可以展示一段簡單的信息,不同點(diǎn)是它的展示更像是整體 UI 的一部分,不是想 toast 一樣是浮在 UI 上的,并且可以有簡單的交互

在點(diǎn)擊 floatingActionButton時(shí)顯示Snackbar


但是可以看到,Snackbar 遮擋住了我們的 view,這時(shí)候需要一個(gè)CoordinatorLayout來協(xié)調(diào) view 布局

CoordinatorLayout

將父布局中的framelaout換成CoordinatorLayout,其他不變,再來看看效果


==todo CoordinatorLayout學(xué)習(xí)==

Toolbar

Toolbar 比傳統(tǒng)的 ActionBar 更靈活,功能也更多,我們可以看到現(xiàn)在市面上很多的 APP 已經(jīng)用 Toolbar 替代了 actionbar,在 Desgin Support 的組件中,很多設(shè)計(jì)都可以和 Toolbar 協(xié)同工作,而不是和 actionbar,所以還是建議使用新的 toolbar 替換以前的 actionbar

替換步驟

1、在 minifest 中,將 activity 的 apptheme 的 style 中的 actionbar屬性去掉

<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. 在 fb 之前放入 Toolbar 組件
<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. 通知系統(tǒng)使用 toolbar
    private void initToolbar() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
    }

CoordinatorLayout中的 view 必須是能一同協(xié)作的 view,就像 Snackbar 一樣,但是 toolbar 并不是這樣能協(xié)同作戰(zhàn)的 view,所以我們需要用一個(gè)可以協(xié)同作戰(zhàn)的 view 來包裹上Toolbar,這就是 AppBarLayout

現(xiàn)在我們的布局文件結(jié)構(gòu)是這樣的

<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>

注意

根據(jù)官方的谷歌文檔,AppBarLayout目前必須是第一個(gè)嵌套在CoordinatorLayout里面的子view

在 toolbar 中加入屬性,app:layout_collapseMode="pin",使得 Toolbar 中的按鈕能固定在頂部

在布局中加入內(nèi)容

在布局中嘗試加入一些按鈕

....
 </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>
    ...

我們定義三個(gè)按鍵,卻被 toolbar 遮住了一個(gè),原因是LinearLayout并沒有被設(shè)計(jì)成在CoordinatorLayout協(xié)同工作的模式,為了使他們能在CoordinatorLayout協(xié)同工作,我們需要在LinearLayout加上一條屬性,來告訴它的滾動(dòng)屬性()

<LinearLayout
    ...
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    ...
    >

搞定

TabLayout

根據(jù)官網(wǎng)的知道,TabLayout通常應(yīng)該是放在頂部,(iOS 的 tab 好像基本在底部),
他應(yīng)該在陰影部分上面,所以應(yīng)該放在AppBarlayout

<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 中設(shè)置這些 tab 屬性

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"));
}

背景會(huì)設(shè)置為主題色,導(dǎo)航線是強(qiáng)調(diào)色。但是字還是黑色的,因?yàn)槲覀儧]有為 tablayout 定義主題,

<android.support.design.widget.TabLayout
    ...
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

通常 tablayout 會(huì)和ViewPager一起使用 ,這時(shí)候使用
public void setupWithViewPager (ViewPager viewPager)

一張圖看的比較清晰


內(nèi)容滾動(dòng)時(shí),AppBarLayout隱藏

當(dāng)滑檔內(nèi)容時(shí),為了騰出跟多的空間展示內(nèi)容可以將AppBarLayout隱藏

1.用 scrollView 包裹 LinearLayout,記得加上 app:layout_behavior屬性

<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. Toolbar 加上屬性
<android.support.v7.widget.Toolbar
    ...
    app:layout_scrollFlags="scroll|enterAlways" />
  1. scrollView 也不能喝 CoordinatorLayout 協(xié)同工作,同上面一樣,要用別的 view 包裹或者直接使用 NestedSrollView替換scrollView

如果希望 tablayout 也消失,只需要和 tablayout 加上相同的屬性就行了

<android.support.design.widget.TabLayout
    ...
    app:layout_scrollFlags="scroll|enterAlways" />

滑動(dòng)內(nèi)容 和 AppBarLayout是如何進(jìn)行聯(lián)系的?

我們需要定義AppBarLayout與滾動(dòng)視圖之間的聯(lián)系。在RecyclerView或者任意支持嵌套滾動(dòng)的view比如NestedScrollView上添加app:layout_behavior。support library包含了一個(gè)特殊的字符串資源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用來通知AppBarLayout 這個(gè)特殊的view何時(shí)發(fā)生了滾動(dòng)事件,這個(gè)behavior需要設(shè)置在觸發(fā)事件(滾動(dòng))的view之上

當(dāng)CoordinatorLayout發(fā)現(xiàn)scrollView中定義了這個(gè)屬性,它會(huì)搜索自己所包含的其他view,看看是否有view與這個(gè)behavior相關(guān)聯(lián)。AppBarLayout.ScrollingViewBehavior描述了RecyclerView與AppBarLayout之間的依賴關(guān)系。RecyclerView的任意滾動(dòng)事件都將觸發(fā)AppBarLayout或者AppBarLayout里面view的改變。

AppBarLayout里面定義的view只要設(shè)置了app:layout_scrollFlags屬性,就可以在RecyclerView滾動(dòng)事件發(fā)生的時(shí)候被觸發(fā):

app:layout_scrollFlags屬性里面必須至少啟用scroll這個(gè)flag,這樣這個(gè)view才會(huì)滾動(dòng)出屏幕,否則它將一直固定在頂部。可以使用的其他flag有:

  • enterAlways: 一旦向上滾動(dòng)這個(gè)view就可見。
  • enterAlwaysCollapsed: 顧名思義,這個(gè)flag定義的是何時(shí)進(jìn)入(已經(jīng)消失之后何時(shí)再次顯示)。假設(shè)你定義了一個(gè)最小高度(minHeight)同時(shí)enterAlways也定義了,那么view將在到達(dá)這個(gè)最小高度的時(shí)候開始顯示,并且從這個(gè)時(shí)候開始慢慢展開,當(dāng)滾動(dòng)到頂部的時(shí)候展開完。
  • exitUntilCollapsed: 同樣顧名思義,這個(gè)flag時(shí)定義何時(shí)退出,當(dāng)你定義了一個(gè)minHeight,這個(gè)view將在滾動(dòng)到達(dá)這個(gè)最小高度的時(shí)候消失。

記住,要把帶有scroll flag的view放在前面,這樣收回的view才能讓正常退出,而固定的view繼續(xù)留在頂部。

可折疊的 Toolbar

  • 用 CollapsingToolbarLayout 包裹 Toolbar,但仍然在 AppBarLayout 中
  • 刪除 Toolbar 中的 layout_scrollFlags
  • 為 CollapsingToolbarLayout 聲明 layout_scrollFlags,并且將 layout_scrollFlags 設(shè)置成 scroll|exitUntilCollapsed
<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在展開和收縮時(shí),標(biāo)題的文字會(huì)自動(dòng)過度的,可以通過 app:expandedTitleMargin 等來改變文字位置


為 appBar 添加背景圖片

由于 CollapsingToolbarLayout 是繼承 Framelayout 的,所以我們可以直接添加一個(gè) ImageView 作為背景圖片

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/header" />

<android.support.v7.widget.Toolbar
    ...

此時(shí)雖然背景已經(jīng)出來了,但是藍(lán)色的導(dǎo)航條依舊存在,需要在 toolbar 去掉這條屬性

android:background="?attr/colorPrimary"

給 Imageview 加上視差模式會(huì)更帥

app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5"

也可以在最后恢復(fù)成主題色

<android.support.design.widget.CollapsingToolbarLayout
    ...
    app:contentScrim="?attr/colorPrimary">

Navigation Drawer

AppBarLayout布局下,增DrawerLayout

<android.support.design.widget.AppBarLayout>
...

<android.support.v4.widget.DrawerLayout xmlns:app="http://schemas./apk/res-auto"
        xmlns:tools="http://schemas./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 就是我們需要的主布局內(nèi)容,另一部分是我們的抽屜的布局,NavigationView中有頂部頭,和標(biāo)簽

app:headerLayout="@layout/nav_header_main2"
            app:menu="@menu/activity_main2_drawer"

創(chuàng)建菜單。

菜單元素是放在group標(biāo)簽之下,同時(shí)聲明每次只能有一個(gè)item被選中:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas./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協(xié)調(diào)。加入app:layout_behavior="@string/appbar_scrolling_view_behavior"屬性

java初始化

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() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                // Handle navigation view item clicks here.
                int id = item.getItemId();

                if (id == R.id.nav_camera) {
                    // Handle the camera action
                } else if (id == R.id.nav_gallery) {

                } else if (id == R.id.nav_slideshow) {

                } else if (id == R.id.nav_manage) {

                } else if (id == R.id.nav_share) {

                } else if (id == R.id.nav_send) {

                }

                DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
                drawer.closeDrawer(GravityCompat.START);
                return true;
            }
        });

SwipeRefreshLayout

NestedScrollView外在包裹一層SwipeRefreshLayout,

  <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>

初始化監(jiān)聽器

private void initRefresh() {
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshContent();
            }
        });
    }

    private void refreshContent() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(false);
            }
        }, 2000);
    }

我的更多 android 博文,關(guān)注作者~每周更新一篇 Android干貨博文
http://xuyushi./archives/

參考

http:///blog/android-design-support-library-codelab/en
http://www./a/anzhuokaifa/androidkaifa/2015/0717/3196.html
http://www./a/anzhuokaifa/androidkaifa/2015/0608/3011.html
http://developer./design/material/

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多