Material Design with the Android Design Support Library

Material Design with the Android Design Support Libraryhtml

 

原文http://www.sitepoint.com/material-design-android-design-support-library/java

 

Material Design,Android 5.0發佈時爲android app 和其餘平臺app引入的一門新的設計語言。android

 

它帶來了一些新的UI組件,如「Floating Action Button」。實施這些新組件,同時確保向後兼容性是一般一個繁瑣的過程。第三方庫一般會須要簡化過程。git

 

在今年的谷歌IO大會上,谷歌推出了Android設計支持庫帶來了一些重要的Material Design組件的開發。該組件是向後兼容,向後兼容到Android 2.1,並實現他們的是比之前更容易。該庫包括一個抽屜式導航視圖,浮動編輯文本,浮動操做按鈕,Snackbar,標籤和motion和滾動框架綁在一塊兒的標籤。在本教程中,咱們將建立一個應用程序,展現了這些組件。github

 

Getting Started

工程源碼:Github https://github.com/sitepoint-editors/Design-Demoapp

 

在開始使用這些組件以前,咱們將創建項目,並設置一些樣式。採用Android Studio中建立一個新的Android項目。將它命名爲「Material Design」並保留其餘設置爲默認值,保證了最低的SDK版本是在API級別15。框架

 

在 build.gradle(module:app)文件添加庫依賴:ide

 

compile 'com.android.support:design:22.2.1'

compile 'com.android.support:cardview-v7:22.2.1'

 

第一個聲明添加 design support library,第二個聲音添加 CardView 庫,稍候咱們將用到。接下來同步更新一下project。它可能會下載一些其餘的支持庫。函數

 

建立文件夾 res/values下資源文件 colors.xml,內容更改以下:工具

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primary">#3F51B5</color>
    <color name="primary_dark">#303F9F</color>
    <color name="accent">#FF4081</color>
</resources>

 

 

在res/values/strings.xml修改以下,咱們在工程須要用到的字符串:

<resources>
    <string name="app_name">Design Demo</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="nav_item_attachment">Attachment</string>
    <string name="nav_item_images">Images</string>
    <string name="nav_item_location">My Location</string>
    <string name="nav_sub_menu">Sub Menu</string>
    <string name="nav_sub_menu_item01">Sub Menu Item 1</string>
    <string name="nav_sub_menu_item02">Sub Menu Item 2</string>
    <string name="drawer_header_text">Drawer Header</string>
    <string name="second_activity_text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin consectetur diam id aliquam scelerisque. Donec ultrices lacus vel dignissim pharetra. Vivamus pharetra augue quis rhoncus placerat. Sed ultricies at risus non cursus. Nam rutrum leo nec placerat consectetur. Vestibulum feugiat eleifend diam, nec interdum augue tincidunt sit amet. Praesent feugiat est auctor lacus consectetur, vitae pellentesque dolor laoreet.</string>
    <string name="title_activity_second">SecondActivity</string>
</resources>

 

 

修改 res/values/styles.xml 文件:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent</item>
    </style>
</resources>

 

在上面代碼中,咱們根據Material Design指南自定義了app的primary, primary-dark and accent color顏色

 

可定製其它主題設置以下圖所示。

注意 item 名稱不包含android: 前綴(如android:colorPrimaryDark),這是爲了向後兼容。android: 註解須要將最低的API級別設置爲 21。咱們須要NoActionBar主題。

由於咱們將使用一個 Toolbar做爲 Action Bar(或者稱爲 AppBar).

 

(SOURCE: https://developer.android.com/training/material/theme.html)

 

添加 Toolbar, res/layout/activity_main.xml

<RelativeLayout 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"
    tools:context=".MainActivity">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark" />
</RelativeLayout>

 

上面代碼中,咱們刪除了RelativeLayout 默認的 padding,而後添加支持庫的 Toolbar。若是你只支持API級別21以上的設備,那麼你可使用默認的 Toolbar組件,而不須要支持庫。

 

修改 MainActivity.java 的 onCreate(Bundle)方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
    actionBar.setDisplayHomeAsUpEnabled(true);
}

 

Download the project resources from gitHub 包含drawable文件夾。你須要複製res目錄到你的工程,上面的代碼纔不會顯示錯誤信息。

 

上面代碼,咱們引用了 Toolbar 做爲 Action Bar,而後爲 Action Bar設置 Home 圖標。

 

運行代碼,你會看一個設置了 Toolbar的AppBar.

 

 

NavigationView

Navigation Drawer是一個Android應用公用組件。它是創建Android導航層次結構的方式之一, Tabs和 Spinners。實現一個歷來就不是一個很快的過程,但如今隨着設計支持庫,它的實現要簡單得多。

 

接着,改修 activity_main.xml:

 

<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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark" />
    </RelativeLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
 

上面代碼,咱們在DrawerLayout佈局添加了一個NavigationView,這裏你會注意到兩個屬性:app:heanderLaytout 用來控制 header 部分的佈局;app:menu 指定了菜單資源,這兩個資源咱們將在下面建立。

 

建立 res/layout/drawer_header.xml文件,內容爲:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:gravity="bottom">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/drawer_header_text"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</LinearLayout>

 

這裏咱們建立了NavigationView的頭部視圖,而後設置視圖背景顏色,高度和顯示的文本。

 

接下來在 res/menu目錄下建立 drawer.xml文件:

<?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/navigation_item_attachment"
            android:checked="true"
            android:icon="@drawable/ic_attachment"
            android:title="@string/nav_item_attachment" />
        <item
            android:id="@+id/navigation_item_images"
            android:icon="@drawable/ic_image"
            android:title="@string/nav_item_images" />
        <item
            android:id="@+id/navigation_item_location"
            android:icon="@drawable/ic_place"
            android:title="@string/nav_item_location" />
    </group>
    <item android:title="@string/nav_sub_menu">
        <menu>
            <item
                android:icon="@drawable/ic_emoticon"
                android:title="@string/nav_sub_menu_item01" />
            <item
                android:icon="@drawable/ic_emoticon"
                android:title="@string/nav_sub_menu_item02" />
        </menu>
    </item>
</menu>

 

在上文中,咱們建立了drawer裏的菜單項。第一部分顯示了菜單項的集合。選中的項目將在導航抽屜突出顯示,確保用戶知道哪些導航項目當前選擇。在第二部分中,咱們使用一個subheader以區別第一部分。

 

在MainActivity.java 添加如下成員變量:

private DrawerLayout mDrawerLayout;

 

而後再 onCreate(Bundle)函數添加如下代碼:

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

 

修改onOptionsItemSelected(MenuItem) 函數:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    switch (id) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            return true;
        case R.id.action_settings:
            return true;
    }
    return super.onOptionsItemSelected(item);
}

 

 

當按鈕屏幕的 home 按鈕,drawer將從左邊滑出。運行代碼看看效果。

 

 

咱們還須要爲NavigationView設置 OnNavigationItemSelectedListener監聽捕獲菜單選擇點擊事件,在onCreate(Bundle)添加代碼:

NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) {
            menuItem.setChecked(true);
            mDrawerLayout.closeDrawers();
            Toast.makeText(MainActivity.this, menuItem.getTitle(), Toast.LENGTH_LONG).show();
            return true;
        }
    });

 

上面的代碼設置在導航視圖中的監聽器,這樣當一個抽屜菜單項被選中,菜單項設置爲選中狀態(這隻會影響到標記爲可檢查的菜單項),抽屜被關閉,並Toast顯示選定菜單項的標題。

 

 

Floating Action Button (FAB)

一個浮動的操做按鈕是一個圓形按鈕,表示您界面上的主要操做。設計庫的FloatingActionButton提供一個一致的實現,在默認狀況下使用colorAccent的主題色。

 

添加一個正常大小(56dp)浮動動做按鈕,它支持最低大小(40dp),當與其餘元件視覺連續性是相當重要的。

 

 

修改 activity_main.xml添加 FAB:

<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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark" />
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:src="@drawable/ic_done" />
    </RelativeLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

 

在上面,咱們添加FloatingActionButton在佈局的右下角。android:src設置按鈕中顯示的圖標。在代碼中,你可使用setImageDrawable()。

 

運行代碼,顯示結果

 

 

下一節咱們會爲 FAB設置onClickListener

 

 

Snackbar

之前若是你想快速反饋信息給用戶,你能夠用 Toast,如今你有另外一個選擇了,那就是 Snackbar

 

Snackbar顯示在屏幕的底部,幷包含文字與可選的單個動做。超時會自動滑出屏幕。用戶也能夠在超時前手動將其滑出。

 

它的API與Toast相似,可是功能卻被Toast強大

 

在 MainActivity.java的onCreate(Bundle):添加如下代碼

FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Snackbar.make(findViewById(R.id.drawer_layout), "I'm a Snackbar", Snackbar.LENGTH_LONG).setAction("Action", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "Snackbar Action", Toast.LENGTH_LONG).show();
                }
            }).show();
        }
    });

 

在上面代碼中,咱們爲FAB設置一個onClickListener 監聽對象,而後顯示Snackbar,當用戶觸發 Action 按鈕時,顯示一個 Toast信息。

 

注意函數make()的第一個參數,它將做爲Snackbar父視圖,以確實Snackbar顯示在父視圖底部的錨點。

 

運行程序:

 

注意到Snackbar與FAB重疊,咱們將在下一節經過CoordinatorLayout修復這個問題。

 

 

TabLayout

 

在Android裏經過標籤來切換兩個不一樣的視圖已經不是新概念了。可是經過支持庫 TabLayout能夠簡化添加標籤的操做。實現了固定 tab(全部 tab 勢均力敵,寬度固定)和滾動 tab(寬度根據標題長度自適應,能夠水平滑動)兩種形式

 

添加 TabLayout 到應用中,修改 res/layout/activity_main.xml:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    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="match_parent"
    android:fitsSystemWindows="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark" />
            <android.support.design.widget.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:tabGravity="fill"
                android:theme="@style/ThemeOverlay.AppCompat.Dark" />
            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"/>
        </LinearLayout>
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:src="@drawable/ic_done"/>
    </RelativeLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

 

在上文中,咱們添加一個TabLayout以及一個ViewPager。該ViewPager將用於使標籤水平切換。

 

在 MainActivity.java文件下添加如下類:

public static class DesignDemoFragment extends Fragment {
    private static final String TAB_POSITION = "tab_position";
    public DesignDemoFragment() {
    }
    public static DesignDemoFragment newInstance(int tabPosition) {
        DesignDemoFragment fragment = new DesignDemoFragment();
        Bundle args = new Bundle();
        args.putInt(TAB_POSITION, tabPosition);
        fragment.setArguments(args);
        return fragment;
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Bundle args = getArguments();
        int tabPosition = args.getInt(TAB_POSITION);
        TextView tv = new TextView(getActivity());
        tv.setGravity(Gravity.CENTER);
        tv.setText("Text in Tab #" + tabPosition);
        return tv;
    }
}
static class DesignDemoPagerAdapter extends FragmentStatePagerAdapter {
    public DesignDemoPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int position) {
        return DesignDemoFragment.newInstance(position);
    }
    @Override
    public int getCount() {
        return 3;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return "Tab " + position;
    }
}

 

 

而後在onCreate(Bundle)方法添加如下代碼:

DesignDemoPagerAdapter adapter = new DesignDemoPagerAdapter(getSupportFragmentManager());
ViewPager viewPager = (ViewPager)findViewById(R.id.viewpager);
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout)findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);

 

上面代碼中,咱們建立一個簡單的Fragment,幷包含一個TextView視圖,而後建立一個FragmentStatePagerAdapter 做爲ViewPager的適配器,適配器的getCount()函數返回了 標籤總數,getItem(int) 返回了當前標籤頁的fragment, getPageTitle(int) 則設置了標籤title,要讓它工做,咱們使用了 TabLayout的setupWithViewPager()函數,更保標籤更新時,viewpager跟着一塊兒更新。

 

運行程序:

 

 

CoordinatorLayout

 

CoordinatorLayout使用新的思路經過協調調度子佈局的形式實現觸摸影響佈局的形式產生動畫效果。

 

將FloatingActionButton 做爲CoordinatorLayout  的子視圖,而後將Snackbar.make() 函數的第一個參數指定爲CoordinatorLayout 

 

大概意思也就是說:當Snackbar向上移出時,FAB會跟着往上移動,就是同步。就解決了重疊的問題了。(自已的英語水平真差出新高度了)

 

修改 activity_main.xml文件:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    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="match_parent"
    android:fitsSystemWindows="true">
 
    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
 
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark" />
 
            <android.support.design.widget.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:tabGravity="fill"
                android:theme="@style/ThemeOverlay.AppCompat.Dark" />
 
            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"/>
 
        </LinearLayout>
 
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:src="@drawable/ic_done"/>
 
    </android.support.design.widget.CoordinatorLayout>
 
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

 

以上代碼中,FAB做爲CoordinatorLayout的子視圖,就是將RelativeLayout佈局更改爲CoordinatorLayout,注意設置FAB的位置

android:layout_gravity="bottom|right".

 

接下來就是在 MainActivity.java建立Snackbar時,CoordinatorLayout爲做Snackbar的視圖參數(第一個參數):

 

Snackbar.make(findViewById(R.id.coordinator), "I'm a Snackbar", Snackbar.LENGTH_LONG).setAction("Action", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "Snackbar Action", Toast.LENGTH_LONG).show();
                }
            }).show();

 

運行程序,如今當你點擊FAB按鈕時,Snackbar會往向滑進界面,可是不會與FAB按鈕重疊,FAB按鈕會跟着往上移動,但Snackbar移出屏幕時,FAB按鈕會跟着回到原來的位置。

 

另外一個主要用例CoordinatorLayout涉及應用欄和滾動技術。設計庫提供了AppBarLayout容許工具欄和其餘視圖(如由TabLayout提供選項卡)反應以在標有ScrollingViewBehavior同級視圖滾動事件。

 

實現這個功能以前,讓咱們先建立一些東西,咱們能夠滾動。咱們將使用一個RecyclerView建立,咱們能夠滾動項目列表。

(做者使用 ListView, GridView和 ScrollViews不能讓CoordinatorLayout正常工做)

 

build.gradle (Module: app) 文件添加以下內容:

compile 'com.android.support:recyclerview-v7:22.2.1'

 

 

建立 res/layout/ fragment_list_view.xml文件

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

 

 

接着建立另外一個佈局文件 res/layout/list_row.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:padding="16dp"
          android:layout_width="match_parent"
          android:layout_height="56dp">
    <TextView
        android:id="@+id/list_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

 

建立一個java文件DesignDemoRecyclerAdapter.java

package com.echessa.designdemo; // Rename as Appropriate
 
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import java.util.List;
 
/**
 * Created by echessa on 7/24/15.
 */
public class DesignDemoRecyclerAdapter extends RecyclerView.Adapter<DesignDemoRecyclerAdapter.ViewHolder> {
    private List<String> mItems;
    DesignDemoRecyclerAdapter(List<String> items) {
        mItems = items;
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, viewGroup, false);
        return new ViewHolder(v);
    }
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        String item = mItems.get(i);
        viewHolder.mTextView.setText(item);
    }
    @Override
    public int getItemCount() {
        return mItems.size();
    }
    public class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView mTextView;
        ViewHolder(View v) {
            super(v);
            mTextView = (TextView)v.findViewById(R.id.list_item);
        }
    }
}

 

 

 

 

修改DesignDemoFragment.onCreateView() 函數的代碼:

@Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Bundle args = getArguments();
        int tabPosition = args.getInt(TAB_POSITION);
        ArrayList<String> items = new ArrayList<String>();
        for (int i = 0; i < 50; i++) {
            items.add("Tab #" + tabPosition + " item #" + i);
        }
        View v =  inflater.inflate(R.layout.fragment_list_view, container, false);
        RecyclerView recyclerView = (RecyclerView)v.findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(new DesignDemoRecyclerAdapter(items));
        return v;
    }

 

使用建立的 fragment_list_view.xml佈局來填充視圖,如今fragment視圖將會包含一個列表項。運行程序:

 

 

修改 activity_main.xml文件:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    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="match_parent"
    android:fitsSystemWindows="true">
 
    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark">
 
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"/>
 
            <android.support.design.widget.TabLayout
                android:id="@+id/tablayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:tabGravity="fill"/>
 
        </android.support.design.widget.AppBarLayout>
 
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
 
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:src="@drawable/ic_done"/>
 
    </android.support.design.widget.CoordinatorLayout>
 
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

 

在上面代碼中,咱們將 Toolbar和TabLayout嵌入到 AppbarLayout中, AppBarLayout容許Toolbar及標誌爲ScrollingViewBehavior的其餘視圖響應滾動事件。當經過RecyclerView用戶滾動時,AppBarLayout響應經過其子的滾動標誌來控制他們是如何進入(滾動在屏幕上)和出口(滾動關閉屏幕)。也就是全部標誌爲ScrollingViewBehavior 的子視圖都會被推入和拉出。

Flags 包括:

  • scroll 這個標誌會被設置到全部但願滾出屏幕的視圖上,若是不設置這一標誌,則視圖會被一直保留在屏幕頂部。
  • enterAlways 這個標誌會確保任何下滑滾屏都會觸發視圖的展示,等於開啓了一種「快速返回」模式。
  • enterAlwaysCollapsed 若是設置了 minHeight 和這個標誌,你的視圖一般會摺疊顯示,只有當滾動視圖已經到達了它的頂點之後纔會打開到完整高度。
  • exitUntilCollapsed 這個標誌會致使視圖在退出以前,一直被鎖定

注意一點:全部設置了 scroll 標誌的視圖必須在未設該標誌的視圖以前進行聲明,這樣能夠確保全部的滾動視圖都從頂部退出,而固定元素都不受影響。

 

 

 

CollapsingToolbarLayout

 

CollapsingToolbarLayout爲AppBar提供了另外一種滾動行爲。咱們將建立另外一個Activity,只包含一個Toolbar.

 

建立一個空的 Activity,命名:SecondActivity

修改 res/layout/activity_second.xml:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout

    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="match_parent"

   >



    <android.support.design.widget.AppBarLayout

        android:layout_width="match_parent"

        android:layout_height="250dp"

        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout

            android:id="@+id/collapsing_toolbar"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            app:contentScrim="?attr/colorPrimary"

            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="match_parent"

                android:scaleType="centerCrop"

                android:src="@drawable/image"

                app:layout_collapseMode="parallax"/>



            <android.support.v7.widget.Toolbar

                android:id="@+id/toolbar"

                android:layout_width="match_parent"

                android:layout_height="?attr/actionBarSize"

                app:layout_collapseMode="pin"></android.support.v7.widget.Toolbar>



        </android.support.design.widget.CollapsingToolbarLayout>

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



    <android.support.v4.widget.NestedScrollView

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        app:layout_behavior="@string/appbar_scrolling_view_behavior">



        <LinearLayout

            android:orientation="vertical"

            android:paddingTop="24dp"

            android:layout_width="match_parent"

            android:layout_height="match_parent">



            <android.support.v7.widget.CardView

                android:layout_margin="16dp"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <LinearLayout

                    android:orientation="vertical"

                    android:padding="16dp"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content">

                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="Lorem ipsum"/>



                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="@string/second_activity_text"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView

                android:layout_margin="16dp"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <LinearLayout

                    android:orientation="vertical"

                    android:padding="16dp"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content">

                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="Lorem ipsum"/>



                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="@string/second_activity_text"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView

                android:layout_margin="16dp"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <LinearLayout

                    android:orientation="vertical"

                    android:padding="16dp"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content">

                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="Lorem ipsum"/>



                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="@string/second_activity_text"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView

                android:layout_margin="16dp"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <LinearLayout

                    android:orientation="vertical"

                    android:padding="16dp"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content">

                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="Lorem ipsum"/>



                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="@string/second_activity_text"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>

            <android.support.v7.widget.CardView

                android:layout_margin="16dp"

                android:layout_width="match_parent"

                android:layout_height="wrap_content">

                <LinearLayout

                    android:orientation="vertical"

                    android:padding="16dp"

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content">

                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="Lorem ipsum"/>



                    <TextView

                        android:layout_width="match_parent"

                        android:layout_height="wrap_content"

                        android:text="@string/second_activity_text"/>

                </LinearLayout>

            </android.support.v7.widget.CardView>



        </LinearLayout>



    </android.support.v4.widget.NestedScrollView>



</android.support.design.widget.CoordinatorLayout>

 

 

在上文中,咱們使用了CollapsingToolbarLayout,標誌爲 scroll和 exitUnitCollapsed,使它的子視圖所有滾出屏幕,對於Toolbar,咱們設置爲:app:layout_collapseMode="pin" 能夠確保當視圖摺疊時 Toolbar固定在頂部,在CollapsingToolbarLayout的標題將出現較大的時候,佈局是徹底可見,而後過渡到其默認大小,由於它是摺疊的。咱們在代碼中設置此title。佈局的其他部分是一個NestedScrollView包含幾個CardView。

 

在SecondActivity.java中的onCreate(Bundle)函數添加代碼:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
    CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    collapsingToolbar.setTitle("Second Activity");
}

 

這裏咱們爲Toolbar添加向上符號和爲 CollapsingToolbarLayout設置title

 

要使用向上符號工做,還須要在manifest文件中爲SecondActivity添加標籤

<meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.echessa.designdemo.MainActivity" />

 

修改DesignDemoRecyclerAdapter.java 的onBindViewHolder()方法:

 @Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    String item = mItems.get(i);
    viewHolder.mTextView.setText(item);
 
    viewHolder.mTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Context context = view.getContext();
            context.startActivity(new Intent(context, SecondActivity.class));
        }
    });
}

 

 

 

在上文中,咱們的RecyclerView的每一行上的TextView設置一個onClick監聽。這不是設置RecyclerView項監聽的好方式,由於若是你運行應用程序,聽者的觸摸目標將只包括與該行的文本的區域,而不是整個行。我這樣作是在這裏,由於我要的是一個方法來啓動新的活動,因此我選擇一個的方式來寫最少的代碼。

 

 

 

Floating Labels for EditText

 

 

最後要介紹的一個組件是支持庫裏改良型的EditText,譬如它在咱們輸入第一個字符的時候,就會自動隱藏掉提示標籤。如今你該使用 TextInputLayout 了,它會在用戶開始輸入以後,自動將提示標籤懸浮到 EditText 上方,這樣用戶就永遠都能知道輸入內容的上下文。

 

爲了演示這個功能,咱們修改 activity_second.xml佈局文件的第二個CardView的第一個TextView爲 EditText.

<android.support.design.widget.TextInputLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
 
                    <EditText
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textEmailAddress"
                        android:hint="Email" />
                </android.support.design.widget.TextInputLayout>

 

運行程序,提示文件將浮如今EditView的上面

 

 

你還能夠經過設置EditView的setError()函數來爲EditView顯示一個」錯誤信息」。

相關文章
相關標籤/搜索