1. 程式人生 > >Android CardView 和Material Design風格設計學習

Android CardView 和Material Design風格設計學習

這篇文章主要介紹一下我自己對於CardView和Material Design學習的過程。學習途徑主要是通過書本和網上資料學習。

效果圖:

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

說明一下,通過下拉可以讓我們宇宙的圖片拉伸延展出來,通過上滑,可以讓我們宇宙圖片逐漸變換成ToolBar樣式。
一.什麼是Material Design:
Material Design,中文名:材料設計語言,是由Google推出的全新的設計語言,谷歌表示,這種設計語言旨在為手機、平板電腦、桌上型電腦和“其他平臺”提供更一致、更廣泛的“外觀和感覺”。
個人感覺這樣的介面設計可以使得我們的APP介面更加的統一和美觀。

二.什麼是CardView:
卡片佈局,從名字中就能感受到介面的劃分以卡片形式為主,並且通過其屬性設定,可以更大程度上滿足我們對於卡片介面的設計。

三.學習過程:

首先我們先新增依賴:

  compile 'com.android.support:recyclerview-v7:25.1.1'
    compile 'com.android.support:cardview-v7:25.1.1'
    compile 'com.github.githubwing:ByeBurger:1.2.3'

這部分依賴是用於cardview和recyclerview包括coordinationlayout的依賴。

然後看一下佈局檔案:
recycler_view_item:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_margin="5dp" android:clickable
="true" app:cardElevation="5dp" android:foreground="?attr/selectableItemBackground" app:cardCornerRadius="2dp">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/fruit_image" android:layout_width="match_parent" android:layout_height="100dp" android:scaleType="center"/> <TextView android:id="@+id/fruit_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:textSize="16sp" android:layout_gravity="center"/> </LinearLayout> </android.support.v7.widget.CardView>

可以看到,我們外層佈局採用的是cardview佈局,我們設定了它的陰影,圓角和邊距,然後下面的控制元件就是具體item中顯示的控制元件了。
這個佈局檔案也是我們圖一種Recycler的Item的佈局樣式。

activity_main:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.administrator.learncardview.MainActivity">
    <android.support.design.widget.CoordinatorLayout
        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.support.v7.widget.Toolbar
    android:id="@+id/tool_bar"
    android:layout_width="match_parent"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_scrollFlags="scroll|enterAlways|snap"
    android:layout_height="?attr/actionBarSize"/>
        </android.support.design.widget.AppBarLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>
    </android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.DrawerLayout>

MainActivity的佈局樣式,這裡面我們按照以前一樣,放置了RecyclerView,然後可以看到我們的外層佈局採用的是DrawerLayout.

<android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

這個佈局可以達到上滑隱藏toolbar和下拉顯示toolbar的效果,然後我們用到了AppBarLayout
這個也是和CoordinatorLayout配套使用的。通過它在裡面我們就可以包裹我們的Toolbar來達到隱藏Toolbar和顯示ToolBar的效果了。

接了下來我恩 我們ToolBar的設定:

    <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
    android:id="@+id/tool_bar"
    android:layout_width="match_parent"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_scrollFlags="scroll|enterAlways|snap"
    android:layout_height="?attr/actionBarSize"/>
        </android.support.design.widget.AppBarLayout>

設定它的popup主題風格

 app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

設定它的滑動標誌:

 app:layout_scrollFlags="scroll|enterAlways|snap"

這裡的三個引數,scroll代表Recyclerview在向上滾動的時候Toolbar會一起向上滾動並且隱藏。enterAlways代表RecyclerView在向下滾動的時候Toolbar會隨著Recycler的滾動而顯示,而snap代表著,Toolbar會跟根據RecyclerView的滾動距離選擇一個合適自己的狀態進行隱藏或者顯示。
這裡ToolBar的設定就這麼多了,然後我們在看看RecyclerView的屬性設定。

  <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
    </android.support.v7.widget.RecyclerView>

可以看到我們有一句:

app:layout_behavior="@string/appbar_scrolling_view_behavior">

這裡是設定RecyclerView的佈局行為

這兩個佈局的效果就相當於設定了我們第一個介面的佈局:

這裡寫圖片描述
接下來我們看看跳轉後的介面佈局:

friut_activity:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:layout_height="235dp">
    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsongbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
       >
        <ImageView
            android:fitsSystemWindows="true"
            android:id="@+id/iamge_fruit"
            android:scaleType="centerCrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@mipmap/sky1"
            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:layout_width="match_parent"
            android:layout_height="wrap_content">
            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="15dp"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:layout_marginTop="35dp"
                app:cardCornerRadius="4dp"
                >
                <TextView
                    android:id="@+id/fruit_textview"
                    android:layout_width="wrap_content"
                    android:layout_margin="10dp"
                    android:layout_height="wrap_content" />
            </android.support.v7.widget.CardView>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

這個佈局就較為複雜了,讓我們看看他的控制元件和屬性設定吧。
最外層佈局還是coor所以就不多說了。
這裡我們引入了一個新的佈局叫做CollapsingToolbarLayout
它是一個作用於Toolbar基礎之上的佈局。我們稱他為可摺疊標題欄。
他是不能獨立存在的,用它的時候也是將它作文AppBarLayout的直接子佈局使用。
接下來我們看一下CollapsingToolbarLayout的屬性設定:

   <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsongbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
       >

我們可以看到兩個屬性:

   app:contentScrim="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"

這裡的contentScrim的作用就是用於指定可摺疊標題欄在摺疊之後的背景顏色。
scrollFlage中的引數,前面第一個已經說過了,而後面的exitUntilCollapsed表示CollapsingToolBarLayout會隨著滾動完成摺疊之後保留在螢幕上,不會移出螢幕。

CollapsingToolBarLayout的佈局裡我們放置了用於顯示在標題欄拉伸後的圖片,和一個Toolbar

這個佈局的設定就相當於我們設定好了跳轉後的佈局:

這裡寫圖片描述

下載我們看一下主要程式碼:

Adapter:

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    List<String> infos;

    public Adapter(List<String> infos) {
        this.infos = infos;
    }
    /*
      * 子佈局建立時候對其進行佈局繫結和Item的點選事件的設定
      * */
    @Override
    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item, parent, false);
        ViewHolder holder = new ViewHolder(view);
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(parent.getContext(), FruitActivity.class);
                parent.getContext().startActivity(intent);
            }
        });
        return holder;
    }

    /*
    * 子佈局控制元件的資料設定
    * */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.image.setImageResource(R.mipmap.ic_launcher);
        holder.text.setText(infos.get(position).toString());
    }


    @Override
    public int getItemCount() {
        return infos.size();
    }

    /*
    * 子佈局控制元件的初始化
    * */
    static class ViewHolder extends RecyclerView.ViewHolder {
        public ImageView image;
        public TextView text;
        public CardView cardView;

        public ViewHolder(View itemView) {
            super(itemView);
            image = (ImageView) itemView.findViewById(R.id.fruit_image);
            text = (TextView) itemView.findViewById(R.id.fruit_name);
            cardView = (CardView) itemView.findViewById(R.id.card_view);
        }
    }
}

FriutActivity

public class FruitActivity extends AppCompatActivity {
    TextView textView;
    ImageView imageView;
    String x;
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.friut_activity);
        Toolbar bar = (Toolbar) findViewById(R.id.toolbar);
        CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsongbar);
        imageView = (ImageView) findViewById(R.id.iamge_fruit);
        textView = (TextView) findViewById(R.id.fruit_textview);
        setSupportActionBar(bar);//設定預設標題欄
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        loadData();
        collapsingToolbarLayout.setTitle("Firut Name");//設定標題
        imageView.setImageResource(R.mipmap.sky);//設定標題欄找票
        textView.setText(x);//文字資訊

    }
    /*
    * 用於資料展示, 我們通過StringBuilder 重複新增500次資料儲存給x
    * */
    public void loadData(){
        StringBuilder y = new StringBuilder();
    for(int i =0;i<=500;i++){
        y.append("asdasdasdsadsadsadasdasdsadasdascxzcsafdafasdadas");
    }
        x = y.toString();
    }
}

MainActivity

package com.example.administrator.learncardview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    RecyclerView rc;
    List<String> infos = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);//系統標題欄設定
        rc = (RecyclerView) findViewById(R.id.recycler_view);
        loadData();
        Adapter adapter = new Adapter(infos);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2);//GridLlayout樣式
        rc.setLayoutManager(gridLayoutManager);
        rc.setAdapter(adapter);
    }
    /*
    * 資料讀取
    * */
    public void loadData(){
        for(int i = 0 ;i<=20;i++){
            infos.add("香蕉香蕉"+i);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.setting:
                Toast.makeText(this, "setting", Toast.LENGTH_SHORT).show();
                break;
            case R.id.back:
                Toast.makeText(this, "back", Toast.LENGTH_SHORT).show();
                break;
            case R.id.exit:
            Toast.makeText(this, "setting", Toast.LENGTH_SHORT).show();
            break;
        }
        return true;
    }
}

程式碼裡我都有註釋,程式碼的設計並沒有很難。都是比較簡單的。

僅僅是為了記錄自己的學習過程,程式碼不是很規範,如果有什麼錯誤的話,請大神多多包含。

學習過程主要是通過網上資料和郭霖著第一行程式碼中。

推薦郭霖<第一行程式碼>給大家,個人比較喜歡這本書的講解風格。因人而異吧。