高逼格UI--ASD

轉載來源:http://www.apkbus.com/android-245054-1-1.html



今年的Google IO給我們Android開發着帶來了三樣很屌很屌的library:

  • ASD(Android Support Design)
  • APL(Android Percent Layout)
  • DBL(Data Binding Library)

這三個庫都是很屌很屌的庫,第一個可以讓我們在低版本的Android上使用Material Design,第二個是爲了更好的適配,提供了基於百分比的Layout;至於第三個,能讓Activity更好負責MVC中C的職責,讓我們開發者更少的去findViewById。ok,首先我們來看看第一個庫,可能也是最主要的庫-ASD。

ASD簡介

前面說了,ASD給我們提供了Material Design提供了向下的兼容,當然我們也需要學習幾個控件的使用,最後用一個實例的形式綜合一個需要學習的這幾個控件。如何使用ASD?很簡單,在AS中添加以下一句話就ok啦。

compile ‘com.android.support:design:22.2.0’


當然,我們在我們學習一些控件的時候還需要AppCompat Library。所以:

compile ‘com.android.support:appcompat-v7:22.2.0’


Snackbar

Snackbar我認爲他是一個介於Dialog和Toast之前的玩意,可以在作爲一種用戶選擇提醒時使用。Snackbar的使用很簡單,接下來我們以代碼和效果的形式快速預覽一下這玩意的使用。

[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
public void click(View view) {
  Snackbar.make(view, "真要點我?", Snackbar.LENGTH_LONG)
      .setAction("真的!", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          Toast.makeText(MainActivity.this, "你真點我了!",
              Toast.LENGTH_SHORT).show();
        }
      }).show();
}

來看看效果。

好吧,這玩意真的很簡單,對照着上面的代碼這下面的效果,肯定秒懂的。


FloatingActionButton

在看看看另一個小控件,也許在項目中我們需要一個圓形的Button, 你可能會想到用自定義Shape的方式去做,但那樣文本的顯示不好居中,這時估計就想到用自定義控件去解決了。好吧,現在ASD給我們提供了FloatingActionButton可以輕鬆的創建圓形Button,而且更牛x的是FloatingActionButton具有更絢麗的效果。FloatingActionButton的使用也很簡單,他直接繼承ImageView,所以ImageView的所有屬性都可以用在FloatingActionButton上。來,看看我們的demo:

[XML] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<android.support.design.widget.FloatingActionButton
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:onClick="click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_margin="0dp"
        android:src="@drawable/add"
        app:backgroundTint="#FF00FF00"
        app:rippleColor="#FF0000FF"
        app:borderWidth="0dp"
        app:fabSize="normal"
        app:elevation="10dp"
        app:pressedTranslationZ="20dp"/>

簡單解釋一下命名空間爲app的配置項。

1. app:backgroundTint是指定默認的背景顏色

2. app:rippleColor是指定點擊時的背景顏色

3. app:borderWidth border的寬度

4. app:fabSize是指FloatingActionButton的大小,可選normal|mini

5. app:elevation 可以看出該空間有一個海拔的高度

6. app:pressedTranslationZ 哈,按下去時的z軸的便宜

來看看FloatingActionButton的效果:

恩,不錯,但是有一個明顯的缺陷就是FloatingActionButton和Snackbar的配合不太好,這對於Material Design簡直就是恥辱!

想要解決這個問題,我們需要引入另一個控件。


CoordinatorLayout

CoordinatorLayout這個控件的作用是讓它的子view更好的去協作,在接下來的時間裏,我們基本都會用到這個控件,這裏我們只是簡單的用CoordinatorLayout來包裹一下FloatingActionButton來達到和Snackbar更好協作的效果。修改我們的佈局:

[XML] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<android.support.design.widget.CoordinatorLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_alignParentBottom="true"
  android:layout_alignParentRight="true">
  <android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="0dp"
    android:onClick="click"
    android:layout_gravity="right"
    android:src="@drawable/add"
    app:backgroundTint="#FF00FF00"
    app:borderWidth="0dp"
    app:elevation="20dp"
    app:fabSize="normal"
    app:pressedTranslationZ="10dp"
    app:rippleColor="#FF0000FF" />
</android.support.design.widget.CoordinatorLayout>

此時的效果:

可以看到,當Snackbar顯示的時候,Button自動往上移動了,而當Snackbar消失以後,Button又回到了原來的位置。


TabLayout

TabLayout也是一個好東西,有了它我們再也不需要使用麻煩人的PagerTabStrip了,也不需要使用自定義view的形式來達到效果。首先來看看簡單用法。

[XML] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
8
9
<android.support.design.widget.TabLayout
        android:id="@+id/tl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="#FFFF0000"
        app:tabSelectedTextColor="#FF0000FF"
        app:tabTextColor="#FFFFFFFF"
        app:tabMode="scrollable"
        app:tabGravity="fill"/>

還是隻解釋app命名空間的。

1. app:tabIndicatorColor tab的指示符顏色

2. app:tabSelectedTextColor 選擇tab的文本顏色

3. app:tabTextColor 普通tab字體顏色

4. app:tabMode 模式,可選fixed和scrollable fixed是指固定個數,scrollable是可以橫行滾動的(逼格高)

5. app:tabGravity 對齊方式,可選fill和center

在來看看activity的代碼:

[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tl);
for(int i=0;i<20;i++) tabLayout.addTab(tabLayout.newTab().setText("TAB" + i));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  @Override
  public void onTabSelected(TabLayout.Tab tab) {
    Toast.makeText(MainActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
  }
  @Override
  public void onTabUnselected(TabLayout.Tab tab) {
  }
  @Override
  public void onTabReselected(TabLayout.Tab tab) {
  }
});

首先,獲取該控件,然後一個for循環添加20個tab,使用:

tabLayout.addTab(tabLayout.newTab().setText(“TAB”));


添加新的tab。然後通過setOnTabSelectedListener來設置tab的item點擊事件。so easy。 來看看效果。


AppBarLayout

AppBarLayout這個控件也是讓子view共同協作的,它和CoordinatorLayout的區別在於:

AppBarLayout是在效果上的協作,用AppBarLayout包裹的子view會以一個整體的形式作爲AppBar。

CoordinatorLayout是在行爲上的一種協作,尤其是在滾動的協作上,可以說非常完美(額, 也不是那麼完美)


首先來看一下我們要做的效果吧。

從效果圖上看,Toolbar和TabLayout成爲了一體。


再來看看我們的代碼

[XML] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<android.support.design.widget.CoordinatorLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:fitsSystemWindows="true"
  tools:context=".MainActivity">
  <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.Toolbar
      android:id="@+id/tb"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"/>
    <android.support.design.widget.TabLayout
      android:id="@+id/tl"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>
  </android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

僅僅是用AppBarLayout包裹了一下Toolbar和TabLayout。細心的朋友可能看到了我們的TabLayout的背景也變了顏色,這裏是因爲我們在theme中設置了:

<pre><code><item name=”colorPrimary”>#FF00FF00</item></code></pre>

那上面那個白色背景的呢? 好難看!難道沒有設置嗎?其實我也設置了,但是沒有體現到TabLayout上,從這裏也驗證了我們上面所說的:

<blockquote>AppBarLayout是在效果上的一種協作</blockquote>

既然我們驗證了該假設,那麼順便來驗證一下

<blockquote>CoordinatorLayout是在行爲上的一種協作</blockquote>

的假設吧。 修改代碼:



?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
<android.support.design.widget.CoordinatorLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:fitsSystemWindows="true"
  tools:context=".MainActivity">
  <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.Toolbar
      android:id="@+id/tb"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      app:layout_scrollFlags="scroll|enterAlways"/>
    <android.support.design.widget.TabLayout
      android:id="@+id/tl"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>
  </android.support.design.widget.AppBarLayout>
  <android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
      <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="50dp"
        android:text="Loader最帥"/>
    </LinearLayout>
  </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

對比上面的代碼,首先我們添加了app的命名空間,爲什麼要添加這個?因爲我們下面要用到!(靠!什麼回答)而且,我們給Toolbar增加了一條配置:

[AppleScript] 純文本查看 複製代碼
?
1
app:layout_scrollFlags="scroll|enterAlways"

表示這個控件是可以滾出屏幕的,而且是隨時可以再顯示

layout_scrollFlags的其他取值有:

1. scroll 誰要滾出屏幕,誰就設置這個值

2. enterAlways 其他向上滑動時,可以立即顯示出來

3. exitUntilCollapsed 將關閉滾動直到它被摺疊起來(有 minHeight) 並且一直保持這樣

4. enterAlwaysCollapsed 定義了 View 是如何回到屏幕的,當你的 view 已經聲明瞭一個最小高度(minHeight) 並且你使用了這個標誌,你的 View 只有在回到這個最小的高度的時候纔會展開,只有當 view 已經到達頂部之後它纔會重新展開全部高度。

(以上解釋,參考了其他文章[目測也是翻譯的官方文檔])

在CoordinatorLayout中我們還引入了另外一個新的控件:

NestedScrollView,這個view其實是ScrollView的增強版,增強在哪呢?他支持屬性:

[XML] 純文本查看 複製代碼
?
1
app:layout_behavior="@string/appbar_scrolling_view_behavior"

這條語句的作用是標識他要一起來寫作完成scroll的效果。換句話說,上面的滾出屏幕的效果要配合一個可以滾動的View,並且得設置了該屬性後纔可以。(至少你得告訴人家,誰要滾出去,滑動誰時才滾出去吧)

好吧,來看看此時的效果:

看到了吧,我們在滑動下面的時候,Toolbar自覺的滾出了屏幕,而且在往上滑動的時候,Toolbar立馬出現了,這就是enterAlways的功勞。

CollapsingToolbarLayout

最後,我們來看一個逼格同樣高的控件:CollapsingToolbarLayout。

該控件的的子view必須要有Toolbar,他的作用就是提供一個可摺疊的標題欄。通常情況下,該控件會和上面我們說的一些控件搭配使用,達到一種 固定的效果 。

CollapsingToolbarLayout本身的使用很簡單,只是他的子view需要設置很多屬性來達到這種效果,下面,我們就提供一個demo實例,來學習一下CollapsingToolbarLayout的使用,順便複習一下上面所學到的一些控件。我們來實現一個這樣的UI:

首先來分析一下,最直觀的,可以看到有一個行爲上的協作, 那肯定需要CoordinatorLayout 這個控件,而且還會有一個效果上的協作,那肯定是AppBarLayout 啦,當然,細心的朋友可能還會看出來,那個圖片和Toolbar會有一種視差的效果,而且整個banner部分是一種摺疊的效果,這就需要CollapsingToolbarLayout 這個控件了。

來說一下 CoolapsingToolbarLayout ,這個控件必須要有一個Toolbar的子view,而且它將作爲 AppBarLayout 的唯一直接子view使用,它提供了一個可以摺疊的AppBar,並且還提供一種視差的效果。下面就讓我們從例子中感受CoolapsingToolbarLayout 的使用。

[XML] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">
  <android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true">
    <android.support.design.widget.AppBarLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
      <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/ctl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <ImageView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:src="@drawable/banner"
          android:scaleType="fitXY"
          app:layout_collapseMode="parallax"/>
        <android.support.v7.widget.Toolbar
          android:id="@+id/tb"
          android:layout_width="match_parent"
          android:layout_height="?attr/actionBarSize"
          app:layout_collapseMode="pin"/>
      </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v7.widget.RecyclerView
      android:id="@+id/rv"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
  </android.support.design.widget.CoordinatorLayout>
  <android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentBottom="true">
    <android.support.design.widget.FloatingActionButton
      android:onClick="add"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="right"
      android:layout_margin="0dp"
      android:src="@drawable/add"
      app:backgroundTint="#FF00FF00"
      app:rippleColor="#FF0000FF"
      app:borderWidth="0dp"
      app:fabSize="normal"
      app:elevation="10dp"
      app:pressedTranslationZ="20dp"/>
  </android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

分析一下這個佈局,最外層一個 RelativeLayout 他包含了兩個CoordinatorLayout , 第二個 CoordinatorLayout 比較簡單就是包括了一個FloatingActionButton ,這樣的用法可以參考博客上面講的。

我們的重點是放在第一個 CoordinatorLayout 上。它有兩個直接子view,和我們說的一樣,一個提供滾出效果,一個提供滾動的效果。接下來一個 AppBarLayout 將ImageView 和 Toolbar 作爲了AppBar。可是它不是直接包含了這兩個小控件,而是通過 CollapsingToolbarLayout ,而且表示滾動標識的app:layout_scrollFlags="scroll|exitUntilCollapsed" 也是賦值給了CollapsingToolbarLayout ,在這裏思考一下,這樣整個CoolapsingToolbarLayout 將會作爲一個整體滾出界面。可是看效果並不是啊, Toolbar 明明還在那,那麼接下來,我們來觀察一下這個 ImageView 和 Toolbar有什麼神奇之處:

[XML] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
<ImageView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:src="@drawable/banner"
  android:scaleType="fitXY"
  app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
  android:id="@+id/tb"
  android:layout_width="match_parent"
  android:layout_height="?attr/actionBarSize"
  app:layout_collapseMode="pin"/>

ImageView有一條屬性 app:layout_collapseMode="parallax" 表示這個ImageView以視差的形式摺疊(效果上看着貌似就是有點小偏移)。

Toolbar的 app:layout_collapseMode="pin" 表示Toolbar在摺疊的過程中會停靠頂部(pin的意思是釘住)。

最後我們使用了一個 RecyclerView ,並且給這個控件設置app:layout_behavior="@string/appbar_scrolling_view_behavior" ,至於RecyclerView 如果你不會用,請自行 網補 。

繼續…, 繼續觀察上面的效果,在滑動的過程中有一個蛋疼的顏色–綠色,它是一個從無到有的過程,是一個漸變的效果,它是怎麼控制的呢?

來看看 CollapsingToolbarLayout 它有一條屬性是: app:contentScrim="?attr/colorPrimary" ,設置這條屬性,在滑動的過程中,會自動變化到該顏色。

最後,要注意一下, 現在我們不能給 Toolbar 設置標題了,而是給CollapsingToolbarLayout 設置標題,可以看到標題在滾動的過程中會有一個大小的變化。

現在這個效果的逼格已經很高了,但是我們還不滿足,那個綠色太TMD的難看了, 哎?能不能跟隨那個圖片的顏色?這樣看起來逼格是不是更高!! 哈哈,完全可以!這需要我們再引用另一個庫 Palette ,關於 Palette 的使用,可以看我之前的博客: 《Android5.0之Palette簡單實用》 。

我們在activity中這麼使用:

[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
final CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.ctl);
    ctl.setTitle("Cool UI");
...
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.banner);
    Palette.generateAsync(bmp, new Palette.PaletteAsyncListener() {
      @Override
      public void onGenerated(Palette palette) {
        Palette.Swatch swatch = palette.getDarkMutedSwatch();
        ctl.setContentScrimColor(swatch.getRgb());
      }
    });

來看看此時的效果:

CollapsingToolbarLayout 的ContentScrim是我們從那個Bitmap上取的。好了,就這麼多吧,累尿了,休息去了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章