Android最佳實踐之Material Design

Material概述及主題

學習地址:http://developer.android.com/training/material/get-started.html
使用material design建立App:css

  1. 溫習一下material design說明
  2. 在app中應用material 主題
  3. 建立遵循material design規則的佈局
  4. 指定投射陰影的高度
  5. 使用ListView和CardView
  6. 本身定義動畫

使用Material 主題

<!-- res/values/styles.xml -->
<resources>
  <!-- your theme inherits from the material theme -->
  <style name="AppTheme" parent="android:Theme.Material"> <!-- theme customizations --> </style>
</resources>

新的Material 主題提供了一下內容:html

  • 可以讓你調色的系統組件
  • 系統組件的觸摸反饋動畫
  • Activity的過渡動畫

Material 主題有幾種:java

  • @android:style/Theme.Material(黑色版本號)
  • @android:style/Theme.Material.Light(淺色版本號)
  • @android:style/Theme.Material.Light.DarkActionBar
    MaterialDark
    MaterialLight

注意:Material 主題僅僅在Android 5.0 (API level 21)及以上版本號可用。android

本身定義調色

<resources>
  <!-- inherit from the material theme -->
  <style name="AppTheme" parent="android:Theme.Material"> <!-- Main theme colors --> <!-- your app branding color for the app bar --> <item name="android:colorPrimary">@color/primary</item> <!-- darker variant for the status bar and contextual app bars --> <item name="android:colorPrimaryDark">@color/primary_dark</item> <!-- theme UI controls like checkboxes and text fields --> <item name="android:colorAccent">@color/accent</item> </style>
</resources>

本身定義狀態欄

使用android:statusBarColor屬性改動狀態欄顏色。sql


ThemeColors

在XML佈局中。可以經過android:theme屬性改動佈局元素或子元素的主題,這樣很是方便改動部分特定界面的顏色。canvas

爲你的View指定z軸高度

<TextView
    android:id="@+id/my_textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/next"
    android:background="@color/white"
    android:elevation="5dp" />

使用List和Card

CardView的使用:markdown

<android.support.v7.widget.CardView
    android:id="@+id/card_view"
    android:layout_width="200dp"
    android:layout_height="200dp"
    card_view:cardCornerRadius="3dp">
    ...
</android.support.v7.widget.CardView>

本身定義動畫

Android 5.0 (API level 21)提供了一個新的API來本身定義動畫,如Activity退出有一個過渡的動畫:app

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // enable transitions
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        setContentView(R.layout.activity_my);
    }

    public void onSomeButtonClicked(View view) {
        getWindow().setExitTransition(new Explode());
        Intent intent = new Intent(this, MyOtherActivity.class);
        startActivity(intent,
                      ActivityOptions
                          .makeSceneTransitionAnimation(this).toBundle());
    }
}

RecycleView和CardView

參考地址:http://developer.android.com/training/material/lists-cards.htmlless

RecycleView

RecyclerView是一個更高級更靈活的ListView。它讓滾動大量的列表數據更加高效。
RecyclerView
使用RecyclerView,必須指定一個Adapter(RecyclerView.Adapter)和一個LayoutManager。ide

layout manager 將item放到recycleView中並決定何時reuse它。

layout manager可以向adapter請求不一樣的數據源來更新界面內容。

回收view這樣的方式提高了性能。因爲它避免了非必需的view的建立以及大量的findViewById()消耗。
RecyclerView提供了三個內置的layoutmanager:

  • LinearLayoutManager:提供一個水平和垂直的滾動列表
  • GridLayoutManager顯示一個grid
  • StaggeredGridLayoutManager 顯示一個錯列的grid

動畫

RecyclerView爲加入和刪除item提供了一些內置的動畫。可以繼承RecyclerView.ItemAnimator而後使用RecyclerView.setItemAnimator()方法定製動畫。

樣例

<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView  android:id="@+id/my_recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent"/>

定義好了recycleview。而後鏈接一個layoutmanager,綁定一個adapter:

public class MyActivity extends Activity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }
    ...
}

adapter演示樣例:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.my_text_view, parent, false);
        // set the view's size, margins, paddings and layout parameters
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(mDataset[position]);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

CardView

CardView繼承FrameLayout。它顯示一個卡片視圖。內置了陰影和圓角。使用card_view:cardElevation使cardview有陰影。card_view:cardCornerRadius設置cardview的圓角半徑(代碼中使用CardView.setRadius方法),使用card_view:cardBackgroundColor設置卡片的背景顏色。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:card_view="http://schemas.android.com/apk/res-auto" ... >
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView  xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_gravity="center" android:layout_width="200dp" android:layout_height="200dp" card_view:cardCornerRadius="4dp">

        <TextView  android:id="@+id/info_text" android:layout_width="match_parent" android:layout_height="match_parent" />
    </android.support.v7.widget.CardView>
</LinearLayout>

加入依賴

RecyclerView 和CardView 組件是 v7 Support Libraries中的內容。

因此需要加入依賴:

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

定義陰影和ClippingView

原文地址:http://developer.android.com/training/material/shadows-clipping.html
Material design定義了在UI元素z軸高度(z值)。z值幫助用戶瞭解元素的相對重要性。並重點關注手頭的任務。


z值越大,它投射的陰影更大。更柔和,高z值的view將遮住低z值的view。然而。z值不影響view的size。
陰影由有z值的view的父view進行的clipping的,默認狀況。


當view超出view的平面時。z值有助於建立動畫。

爲view指定z值


z值有兩部分組成:
一、z軸高度:靜態成分
二、平移:動態成分,用於動畫
Z = elevation + translationZ

shadows-depth
圖:不一樣View的z值的陰影

在XML佈局中使用android:elevation設置z軸高度。在代碼中使用View.setElevation()方法設置。
設置平移。使用View.setTranslationZ()方法。

新的方法ViewPropertyAnimator.z() 和 ViewPropertyAnimator.translationZ()贊成你很是easy在z軸進行動畫。

本身定義View的陰影和輪廓(Outlines)

view的背景圖片邊界決定了默認的陰影形狀。

輪廓表明一個圖形對象的外部形狀,它定義了用於觸摸波紋區域。

<TextView
    android:id="@+id/myview"
    ...
    android:elevation="2dp"
    android:background="@drawable/myrect" />

定義一個圓角背景圖:

<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>

view投射了一個圓角的陰影,因爲背景圖片定義了view的輪廓。提供一個本身定義的輪廓可以覆蓋view陰影的默認形狀。定義一個本身定義輪廓用如下代碼:
一、繼承ViewOutlineProvider
二、覆蓋getOutline()方法
三、使用View.setOutlineProvider()方法給view定義本身定義的輪廓。


你可以使用Outline類來建立一個橢圓或矩形的圓角輪廓,view的默認的輪廓獲取的是view的背景。阻止view投射陰影,設置它的輪廓爲null。

裁剪(Clip)View

裁剪View讓你可以easy的改變View的形狀。你可以使用View.setClipToOutline()或android:clipToOutline屬性裁剪View到它的輪廓中。僅僅有矩形、圓形、圓角矩形支持裁剪。在Outline.canClip()中定義的。
要裁剪一個view成一個圖片形狀。需要設置這個圖片做爲view的背景。並調用View.setClipToOutline() 方法。


裁剪View是一個耗時操做,不要使用動圖來裁剪View。爲了達到這個效果。使用 Reveal Effect動畫。

使用Drawable

原文地址:http://developer.android.com/training/material/drawables.html#ColorExtract
在material design中drawable的能力例如如下:

  • Drawable 着手
  • 突出顏色提取
  • 矢量圖

Drawable 資源着色

Android 5.0 (API level 21)及以上版本號,可以給drawable和9patch圖片着色爲**α**Mask,可以用顏色或主題屬性來着色(如?

android:attr/colorPrimary)。
使用setTint()方法將着色應用到BitmapDrawable, NinePatchDrawable 或 VectorDrawable對象中,也可以在佈局文件裏使用android:tint 和android:tintMode來設置。

從一個圖片中提取突出顏色

在Android Support Library r21以上的支持庫中包括了Palette類,它可以幫你從一個圖片中提取突出顏色(VibrantVibrant darkVibrant lightMutedMuted darkMuted light)。
在載入image的地方,將bitmap對象傳到Palette.generate()靜態方法中,假設用不了這個線程,使用Palette.generateAsync()並設置監聽來實現。
比方可以使用Palette.getVibrantColor方法來提取顏色。

使用Palette,需加入依賴:

dependencies {
    ...
    compile 'com.android.support:palette-v7:21.0.0'
}

建立矢量圖

Android 5.0 (API Level 21)及以上版本號。可以建立一個不失幀的矢量圖。僅僅需要使用一個文件做爲矢量圖,而不用爲每個屏幕密度來定義多個文件。

使用元素來定義,如下是一個心形的矢量圖演示樣例:

<!-- res/drawable/heart.xml --> <vector xmlns:android="http://schemas.android.com/apk/res/android" <!-- intrinsic size of the drawable --> android:height="256dp" android:width="256dp" <!-- size of the virtual canvas --> android:viewportWidth="32" android:viewportHeight="32"> <!-- draw a path --> <path android:fillColor="#8fff" android:pathData="M20.5,9.5 c-1.955,0,-3.83,1.268,-4.5,3 c-0.67,-1.732,-2.547,-3,-4.5,-3 C8.957,9.5,7,11.432,7,14 c0,3.53,3.793,6.257,9,11.5 c5.207,-5.242,9,-7.97,9,-11.5 C25,11.432,23.043,9.5,20.5,9.5z" /> </vector>

矢量圖在Android中是一個VectorDrawable對象。

本身定義動畫

參考地址:http://developer.android.com/training/material/animations.html#Reveal
Material 主題提供一些默認的button和Activity轉場的動畫, Android 5.0 (API level 21)及以上的版本號中還贊成本身定義這些動畫並建立如下這些新的動畫:

  • 觸摸反饋
  • 循環顯示
  • Activity 轉場
  • 曲線運動
  • View狀態改變

本身定義觸摸反饋

button默認的觸摸反饋是使用RippleDrawable類。它提供了一種切換狀態時過渡的波紋效果。大部分狀況下。你僅僅需要使用?android:attr/selectableItemBackground(有界波紋)做爲背景就能夠,或者?android:attr/selectableItemBackgroundBorderless(API level 21纔有,無界波紋)。或者你可以在XML中定義RippleDrawable,使用ripple元素。可以改變的RippleDrawable對象顏色,使用主題的android:colorControlHighlight改變觸摸反饋顏色。

使用顯示效果

顯示動畫(Reveal animations)提供了一組UI元素顯示隱藏的視覺連續性的動畫效果。

ViewAnimationUtils.createCircularReveal()方法提供一個極好的循環顯示和隱藏的動畫。

顯示一個以前沒顯示的view使用這個效果:

// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// get the final radius for the clipping circle
float finalRadius = (float) Math.hypot(cx, cy);

// create the animator for this view (the start radius is zero) Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

// make the view visible and start the animation myView.setVisibility(View.VISIBLE);
anim.start();

隱藏以前顯示的view使用:

// previously visible view
final View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// get the initial radius for the clipping circle
float initialRadius = (float) Math.hypot(cx, cy);

// create the animation (the final radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        myView.setVisibility(View.INVISIBLE);
    }
});

// start the animation
anim.start();

本身定義Activity轉場

Android 5.0 (API level 21)提供了例如如下進場和退場動畫:爆炸(從中間進場退場)。平移(從邊緣進場退場)。淡入淡出(進場退場改變透明度)。不論什麼繼承了Visibility類的過渡都支持進場和退場過渡效果。


Android 5.0 (API level 21)也提供了共享元素過渡。changeBounds、changeClipBounds、changeTransform、changeImageTransform 。
SceneTransition
圖:使用共享元素效果的場景過分

sharedelement
圖:使用共享元素轉場

在主題中使用android:windowActivityTransitions屬性設置Activity是否贊成window過渡效果,可以指定進場、退場、共享元素動畫效果:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

change_image_transform動畫效果定義例如如下:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

changeImageTransform元素相應ChangeImageTransform類。
在代碼中贊成window過渡效果,使用Window.requestFeature()方法:

// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// set an exit transition
getWindow().setExitTransition(new Explode());

所有代碼中設置Activity轉場動畫的方法有:Window.setEnterTransition()Window.setExitTransition()Window.setSharedElementEnterTransition()Window.setSharedElementExitTransition()
爲獲得一個完整的過渡效果,需要在兩個Activity(起止)中同一時候設置動畫。

使用Window.setAllowEnterTransitionOverlap()方法可以讓進場動畫儘量快的執行。這個會讓你有更加使人心動的進場動畫。

使用轉場啓動Activity

當你贊成轉場並設置了退場動畫。那麼當你啓動還有一個Activity時就激活了轉場:

startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

假設你在第二個Activity中設置了進場動畫,那麼當Activity啓動時也會激活轉場。要在啓動Activity時禁止使用轉場,將bundle參數設爲null就能夠。

使用共享元素啓動Activity

一、在主題中設置贊成window內容轉場
二、在主題中指定一個共享元素轉場
三、在XML資源中定義轉場
四、使用android:transitionName在兩個Activity的XML佈局中定義一樣的共享元素名稱
五、使用ActivityOptions.makeSceneTransitionAnimation()方法

// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // start the new activity
        startActivity(intent, options.toBundle());
    }
});

對於在代碼中生成的動態共享元素。使用View.setTransitionName()方法在兩個Activity中設置元素名稱。
爲了使動畫反轉,在結束Activity時調用Activity.finishAfterTransition(),而不是Activity.finish()

使用多個共享元素啓動Activity

爲使用多個共享元素啓動Activity。在android:transitionName屬性(或代碼中View.setTransitionName() 方法)在兩個Activity佈局中定義共享元素。而後 建立ActivityOptions

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));

曲線運動

Material Design中的曲線動畫依賴時間插值和空間運動模式。在Android 5.0 (API level 21) 及以上版本號中,你可以使用本身定義的時間曲線和曲線運動模式。


PathInterpolator類是一個新的基於貝葉斯曲線或Path類的插值。這個插值定義了1x1的正方形的運動曲線。(0,0)和(1,1)兩個錨點,以及使用構造參數指定的控制點。

你可以定義一個path插值例如如下:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:controlX1="0.4" android:controlY1="0" android:controlX2="1" android:controlY2="1"/>

在material design的說明中。系統定義了3個主要的曲線的XML資源:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

你可以傳一個PathInterpolator對象給Animator.setInterpolator()方法。
ObjectAnimator類新的構造方法贊成你沿着一個path一次使用兩個以上的屬性進行座標的動畫。

ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
...
mAnimator.start();

View狀態變化的動畫

StateListAnimator類贊成你在View的狀態變化時定義動畫。如下是StateListAnimator的XML資源:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true">
    <set>
      <objectAnimator android:propertyName="translationZ" android:duration="@android:integer/config_shortAnimTime" android:valueTo="2dp" android:valueType="floatType"/>
        <!-- you could have other objectAnimator elements here for "x" and "y", or other properties -->
    </set>
  </item>
  <item android:state_enabled="true" android:state_pressed="false" android:state_focused="true">
    <set>
      <objectAnimator android:propertyName="translationZ" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
    </set>
  </item>
</selector>

定義好動畫後。使用android:stateListAnimator屬性賦值給需要在狀態變化時進行動畫的View。在代碼中使用AnimationInflater.loadStateListAnimator()裝載動畫,而後使用View的View.setStateListAnimator()方法設置View的動畫。
當你的主題繼承material 的主題時。Button默認有一個z方向的動畫,要禁止掉這個,設置android:stateListAnimator爲@null。


AnimatedStateListDrawable類贊成你建立狀態變化動畫的drawable。如下是一個樣例:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector  xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state_focused="true"/>
    <item android:id="@id/default" android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

矢量圖動畫

AnimatedVectorDrawable類贊成你對矢量圖進行屬性動畫。通常定義動畫矢量圖在3個XML文件裏:

  1. 在res/drawable/中使用 元素定義矢量圖
  2. 在res/drawable/中使用元素定義動畫的矢量圖
  3. 在res/anim/中使用定義一個或多個動畫
    動畫矢量圖主要是對 和 進行動畫。
<!-- res/drawable/vectordrawable.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600">
    <group  android:name="rotationGroup" android:pivotX="300.0" android:pivotY="300.0" android:rotation="45.0" >
        <path  android:name="v" android:fillColor="#000000" android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

動畫矢量圖的定義引用了groups 和paths在矢量圖中的名稱:

<!-- res/drawable/animvectordrawable.xml -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vectordrawable" >
    <target  android:name="rotationGroup" android:animation="@anim/rotation" />
    <target  android:name="v" android:animation="@anim/path_morph" />
</animated-vector>

動畫定義使用ObjectAnimatorAnimatorSet對象。

<!-- res/anim/rotation.xml -->
<objectAnimator  android:duration="6000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" />
<!-- res/anim/path_morph.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator  android:duration="3000" android:propertyName="pathData" android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" android:valueType="pathType" />
</set>

保持兼容

原文地址:http://developer.android.com/training/material/compatibility.html#SupportLib
很是多Material Design都是在Android 5.0 (API level 21)及以上的版本號中才幹用。要在老版本號中使用這些新特性,需要作些兼容工做。

定義多個Styles

兼容主題。可以在支持Material主題的設備中使用Material 主題。不支持的使用替代主題。


一、在舊版(Android 5.0曾經)中定義res/values/styles.xml(比方holo主題)
二、在res/values-v21/styles.xml中定義一個Material主題
三、在Manifest中將app的主題設置爲上面定義的主題

假設你使用Material主題但沒有提供兼容的主題,則app不會執行在Android5.0以前的系統裏

定義多個Layout

參考佈局別名。在這裏,定義Android5.0的佈局在res/layout-v21/*.xml中定義。

使用支持庫

v7 Support Libraries r21以上版本號的支持庫,支持Material主題。

  • Theme.AppCompat主題支持很是多Material Design的組件:EditText、Spinner、CheckBox、RadioButton、SwitchCompat、CheckedTextView。
  • 支持Color palette<!-- extend one of the Theme.AppCompat themes -->
    <style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- customize the color palette -->
    <item name="colorPrimary">@color/material_blue_500</item>
    <item name="colorPrimaryDark">@color/material_blue_700</item>
    <item name="colorAccent">@color/material_green_A200</item>
    </style>
  • RecycleViewCardView

加入依賴

dependencies { compile 'com.android.support:appcompat-v7:21.0.+' compile 'com.android.support:cardview-v7:21.0.+' compile 'com.android.support:recyclerview-v7:21.0.+' }

檢測系統版本號

如下特性是Android5.0及以上版本號纔有的:

  • Activity轉場(Activity transitions)
  • 觸摸反饋(Touch feedback)
  • 顯示動畫(Reveal animations)
  • 基於Path的動畫(Path-based animations)
  • 矢量圖(Vector drawables)
  • Drawable着色(Drawable tinting)
    爲保持兼容,需要推斷版本號:
// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Call some material design APIs here
} else {
    // Implement this feature without material design
}

注意:讓app支持Material主題,需要在Manifest文件裏設置android:targetSdkVersion=21。

相關文章
相關標籤/搜索