1. 程式人生 > >Android學習筆記:介面設計Material Design的基本使用方法(二)

Android學習筆記:介面設計Material Design的基本使用方法(二)

四、卡片式佈局

1、使用CardView實現卡片式佈局

CardView由appcompat-v7庫提供,它也是一個FrameLayout,只是額外的提供了圓角和陰影等效果。

CardView的使用方法:

<android.support.v7.widget.CardView 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:elevation="5dp"
    app:cardCornerRadius="4dp">

   <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

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

程式碼含義很好理解,其中:

app:elevation="5dp"		//指定卡片高度
app:cardCornerRadius="4dp"	//指定卡片圓角弧度

這樣這個TextView就顯示在一個卡片中了。

下面開始使用CardView佈局。專案目標:使用RecyclerView填充主介面,實現水果圖片的列表展現。

使用準備:

①、準備好水果圖片資源(可以在我給的圖片資源中找到)。放入drawable下。

②、新增庫依賴。

因為會使用到CardView、RecyclerView和Glide庫來實現,所以在(preject模式)app/build.gradle中新增三個依賴。

dependencies {
    
	...
	
    compile 'com.android.support:recyclerview-v7:25.3.1'
    compile 'com.android.support:cardview-v7:25.3.1'
    compile 'com.github.bumptech.glide:glide:3.7.0'
}

然後點選 Sync Now進行同步。Glide庫是一個超級強大的載入圖片的開源專案。

準備完成後開始具體實現:

(1)、修改activity_main.xml的程式碼,使RecyclerView填充整個主介面。

在Toolbar和FloatingActionButton標籤的中間加入以下程式碼:

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

(2)使用RecyclerView

①、建立Fruit實體類,包括水果名、資源ID和getter方法。

package com.my.materialdesigntest;
	
public class Fruit {

    private String name;	//水果名

    private int imageId;	//資源ID

    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public int getImageId() {
        return imageId;
    }

}

②、為RecyclerView子項自定義佈局

在layout目錄下新建fruit_item.xml檔案。修改為以下程式碼:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
    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="wrap_content"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">

    <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="centerCrop" />

        <TextView
            android:id="@+id/fruit_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp" />

    </LinearLayout>

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

最外層使用CardView佈局,程式碼很好理解,值得注意的是:android:scaleType="centerCrop",這條語句的含義是:指定圖片的縮放模式,若水果圖片的長寬比例不同,為了能讓圖片能填充整個ImageView,使用centerVrop模式,可以使圖片保持原有比例填充ImageView,並將多餘部分裁剪掉。

③、為RecyclerView自定義介面卡

新建FruitAdapter類,繼承RecyclerView.Adapter,並指定泛型為FruitAdapter.ViewHolder,程式碼如下:

package com.my.materialdesigntest;

import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.util.List;

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    private Context mContext;		//上下文
    private List<Fruit> mFruitList;	//裝載水果資訊的列表

    //建構函式,傳入資料來源
    public FruitAdapter(List<Fruit> mFruitList) {
        this.mFruitList = mFruitList;
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        private CardView cardView;	//RecyclerView子項的最外層佈局
        private ImageView fruitImage;
        private TextView fruitName;

        public ViewHolder(View view) {
            super(view);
            cardView = (CardView) view;	//RecyclerView子項最外層佈局
            fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            fruitName = (TextView) view.findViewById(R.id.fruit_name);
        }
    }

    //必須重寫的第一個方法:建立ViewHolder方法
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mContext == null) {
            mContext = parent.getContext();
        }
        //載入子項佈局
        View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item, parent, false);
        //建立ViewHolder例項
        final ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    //必須重寫的第二個方法:對子項資料賦值
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //獲取當前項的水果例項
        Fruit fruit = mFruitList.get(position);
        //賦值
        holder.fruitName.setText(fruit.getName());
        //根據資源ID獲取水果圖片資源並填充ImageView
        Glide.with(mContext).load(fruit.getImageId()).into(holder.fruitImage);
    }

    //必須重寫的第三個方法:獲取所有子項的個數
    @Override
    public int getItemCount() {
        return mFruitList.size();
    }

}

按照註釋很容易理解。

(3)、修改MainActivity中的程式碼:

public class MainActivity extends AppCompatActivity {

    private DrawerLayout mDrawerLayout; //DrawerLayout佈局,用於實現滑動選單

    //將水果資訊裝填到水果陣列中
    private Fruit[] fruits = {new Fruit("Apple", R.drawable.apple), new Fruit("Banana", R.drawable.banana),
            new Fruit("Orange", R.drawable.orange), new Fruit("Watermelon", R.drawable.watermelon),
            new Fruit("Pear", R.drawable.pear), new Fruit("Grape", R.drawable.grape),
            new Fruit("Pineapple", R.drawable.pineapple), new Fruit("Strawberry", R.drawable.strawberry),
            new Fruit("Cherry", R.drawable.cherry), new Fruit("Mango", R.drawable.mango)};

    //裝載水果的連結串列
    //為什麼有了陣列還要定義List:因為我們要顯示的水果資料個數不確定,使用多少個就往List中裝多少水果資料
    //水果陣列只是裝填水果資訊的模具,具體使用資料還是使用List
    private List<Fruit> fruitList = new ArrayList<>();

    private FruitAdapter adapter;   //介面卡

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...
		
        initFruits();   //初始化水果資料
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        //使用GridLayoutManger佈局,設定每行顯示2列資料
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);
        //建立介面卡
        adapter = new FruitAdapter(fruitList);
        //繫結RecyclerView
        recyclerView.setAdapter(adapter);

    }

    //初始化水果資料
    private void initFruits() {
        //清空水果列表的資料
        fruitList.clear();
        //向List中裝填50個水果資料
        for (int i = 0; i < 50; i++) {
            Random random = new Random();
            //從水果陣列中隨機一個不超過水果陣列長度的整數
            int index = random.nextInt(fruits.length);
            //將隨機出來的水果資料裝到水果List中
            fruitList.add(fruits[index]);
        }
    }
    
    ...

}

執行程式:


效果很不錯,但是Toolbar被蓋住了。

原因:我們使用的最外層佈局是CoordinatorLayout,他是一個加強版的FrameLayout,FrameLayout在其控制元件不指定位置時,都預設放在左上角。RecyclerView和Toolbar都是放在該佈局中,沒有指定位置。自然就產生了這種現象。

解決:解決方法可以是採用傳統方法,把RecyclerView向下偏移一個Toolbar的高度。CoordinatorLayout佈局不是普通的FrameLayout,它有更巧妙的解決方法。

2、使用AppBarLayout

APPBarLayout由Design Support庫提供。它實際上是一個垂直方向的LinearLayout,並且在內部做了很多滾動事件的封裝,應用了一些Material Design的設計理念。

使用AppBarLayout解決上面出現的問題只需要兩步:

①、把Toolbar巢狀到AppBarLayout中。

②、為RecyclerView指定一個佈局行為。

修改activity_main.xml的程式碼:

<?xml version="1.0" encoding="utf-8"?>
<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.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/toolbar"
		android:layout_width="match_parent"
		android:layout_height="?attr/actionBarSize"
		android:background="?attr/colorPrimary"
		android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
		app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

        <android.support.v7.widget.RecyclerView
            
			...
			
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        ...

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

    ...

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

只需要幾行程式碼就可以完成。為RecyclerView新增的佈局行為是:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

它可以把滾動事件傳送給它外層的AppBarLayout佈局。

執行程式:


已經可以解決Toolbar被遮蓋的問題了。

當RecyclerView滾動時,會將滾動事件通知給AppBarLayout,上述程式碼中並沒有進行處理。

當AppBarLayout收到滾動事件時,它內部的子控制元件可以指定如何去相應這些事件。

修改activity_main.xml程式碼,在Toolbar程式碼塊後面加上一條語句即可:

<android.support.v7.widget.Toolbar
    
	...
	
    app:layout_scrollFlags="scroll|enterAlways|snap" />

它的作用是指定Toolbar響應RecyclerView滾動事件的方法。其中:

scroll:當RecyclerView向上滾動時,Toolbar會跟著一起向上滾動並實現隱藏。

enterAlways:當RecyclerView向下滾動時,Toolbar會跟著一起向下滾動並重新顯示。

snap:當Toolbar還沒有完全隱藏或顯示的時候,Toolbar會根據當前滾動的距離,自動選擇隱藏還是顯示。

執行結果:


五、使用SwipeRefreshLayout實現下拉重新整理

SwipeRefreshLayout由Support-v4庫提供,使用時,把需要實現下拉重新整理的控制元件放到SwipeRefreshLayout中就可以了,本文所述就是將RecyclerView放到SwipeRefreshLayout中。

修改activity_main.xml檔案:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
		
</android.support.v4.widget.SwipeRefreshLayout>

剛剛為了解決Toolbar被覆蓋的問題,為Toolbar嵌套了一層AppBarLayout,併為RecyclerView添加了一個佈局行為,這個滾動行為會把滾動事件傳送給它的外層AppBarLayout。現在需要把它挪到SwipRefreshLayout中,否則滾動事件傳送不到AppBarLayout。若它的位置不動,則Toolbar還是會被遮蓋。只需要記住它是追隨AppBarLayout的就可以了。

修改MainActivity的程式碼:

public class MainActivity extends AppCompatActivity {

    ...

    private SwipeRefreshLayout swipeRefreshLayout;  //下拉重新整理佈局,用於實現下拉重新整理

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        //設定下拉重新整理時的進度條顏色
        swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
        //觸發下拉重新整理的事件
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //重新整理水果圖片
                refreshFruits();
            }
        });

    }

    //重新整理顯示的水果圖片
    private void refreshFruits() {
        //重新整理操作一般是從網路上獲取資料,需要開啟執行緒,這裡採用的是本地重新整理
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //使執行緒睡眠2s,因為本地重新整理速度太快,不設定睡眠容易看不到重新整理進度條
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //從主執行緒更新UI
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //再次初始化水果資料,因為每次初始化的水果資料都是不同的
                        initFruits();
                        //通知FruitAdapter的介面卡,資料發生了變化
                        adapter.notifyDataSetChanged();
                        //表示重新整理事件結束,隱藏重新整理進度條,若無此語句,進度條一直存在。
                        swipeRefreshLayout.setRefreshing(false);
                    }
                });
            }
        }).start(); //不要忘記啟動執行緒
    }

    ...
	
}

執行程式:


六、使用CollapsingToolbarLayout實現可摺疊式標題欄

看到CollapsingToolbarLayout這個名字就能夠想到,它是一個和Toolbar相關的佈局。它由Design Support庫提供,作用於Toolbar之上,它可以讓Toolbar的效果更加豐富,實現非常華麗的效果。

注意:CollapsingToolbarLayout並不是獨立存在的,它被限定只能作為AppBarLayout的直接子佈局,而AppBarLayout又必須是CoordinatorLayout的子佈局。

需求:用一個額外的活動來展示水果詳情頁面,實現標題欄可摺疊,內容包括標題欄、水果圖片、水果內容詳情和懸浮按鈕。

新建一個Empty活動,指定活動名為FruitActivity,指定佈局名為activity_fruit.xml。

活動佈局主要分為兩部分,一個是水果標題欄,一個是水果內容詳情。分步驟來實現:

1、實現標題欄部分

(1)、使用CoordinatorLayout作為最外層佈局

<?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.CoordinatorLayout>

(2)、在CoordinatorLayout中巢狀一個AppBarLayout佈局

<?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:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">

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

定義了AppBarLayout的高度為250dp,這個高度是一會標題欄展開後圖片的顯示高度。

(3)、在AppBarLayout中巢狀一個CollapsingToolbarLayout佈局

<?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:id="@+id/appBar"
		android:layout_width="match_parent"
		android:layout_height="250dp">

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

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

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

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

CollapsingToolbarLayout佈局中:

theme屬性:用於設定主題,在MainActivity的Toolbar就是這個主題,現在把這個主題提到上一級來。app:contentScrim屬性:用於指定CoordinatorLayout在趨於摺疊以及摺疊之後的背景色,CoordinatorLayout摺疊之後就是一個普通的Toolbar,所以指定顏色為colorPrimary。
app:layout_scrollflags屬性:
scroll表示CollapsingToolbarLayout會隨著水果內容詳情的滾動一起滾動。
exitUntilCollapsed表示當CollapsingToolbarLayout隨滾動完成摺疊後就保留在介面上,不再移出螢幕。

(4)、在CollapsingToolbarLayout中定義具體內容                                                     

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

    <ImageView
        android:id="@+id/fruit_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        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.design.widget.CollapsingToolbarLayout>

app:layout_collapseMode屬性:用於指定當前控制元件在CollapsingToolbarLayout摺疊過程中的摺疊模式。
Toolbar被指定成pin:表示摺疊的過程中,Toolbar的位置始終保持不變。
ImageView被指定成parallax:表示會在摺疊的過程中產生一定的錯位偏移,即產生一定的視覺效果。

2、實現水果內容詳情部分

(1)、在最外層使用NestedScrollView佈局。

NestedScrollView由Support-v4庫提供。像ScrollView一樣,它支援使用滾動的方式來檢視螢幕以外的資料,而NestedScrollView在此基礎上還增加了巢狀相應滾動事件的功能。由於CoordinatorLayout本身已經可以響應滾動事件了,所以在它的內部就需要使用NestedScrollView或RecyclerView這樣的佈局。

NestedScrollView與AppBarLayout是平級的。在AppBarLayout下使用NestedScrollView標籤:

<?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:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">
		
		...
		
    </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">

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

通過app:behavior屬性指定了一個佈局行為,和之前在RecyclerView中的用法一樣,不會遮蓋到標題欄。

注:不論是ScrollView還是NestedScrollView,它們的內部都只允許存在一個直接子佈局,所以,想要在裡面放很多東西的話通常會先巢狀一個LinearLayout佈局,在LinearLayout佈局中放入具體內容。

(2)、設定NestedScrollView裡的具體內容

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

	<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_content_text"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_margin="10dp" />

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

</LinearLayout>	

3、加入懸浮按鈕

<?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.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        ...

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

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@drawable/ic_comment"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="bottom|end" />

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

通過app:layout_anchor屬性為懸浮按鈕設定了一個錨點,並將它的位置設定為右下角。這樣懸浮按鈕就會出現在展開後的標題欄中,且跟隨著標題欄移動。

4、佈局編寫完畢,開始編寫邏輯功能。

修改FruitActivity中的程式碼:

package com.my.materialdesigntest;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

public class FruitActivity extends AppCompatActivity {

    //水果名欄位
    public static final String FRUIT_NAME = "fruit_name";

    //水果圖片資源ID欄位
    public static final String FRUIT_IMAGE_ID = "fruit_image_id";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fruit);

        //獲取啟動本活動時傳遞過來的資料,沒有資料就無法知道使用者想要檢視的水果資料是什麼
        Intent intent = getIntent();
        //取出資料
        String fruitName = intent.getStringExtra(FRUIT_NAME);
        int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID, 0);

        //關聯控制元件
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        ImageView fruitImageView = (ImageView) findViewById(R.id.fruit_image_view);
        TextView fruitContentText = (TextView) findViewById(R.id.fruit_content_text);

        //使用Toolbar
        setSupportActionBar(toolbar);

        //獲取ActionBar例項,具體由Toolbar實現
        ActionBar actionBar = getSupportActionBar();

        //此時顯示返回按鈕
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

        //設定標題
        collapsingToolbar.setTitle(fruitName);

        //載入圖片
        Glide.with(this).load(fruitImageId).into(fruitImageView);

        //通過generateFruitContent方法獲取一段水果內容資訊
        String fruitContent = generateFruitContent(fruitName);

        //將獲取到的資訊設定到控制元件上
        fruitContentText.setText(fruitContent);
    }

    //通過水果名獲取一段水果資訊
    private String generateFruitContent(String fruitName) {

        //字串緩衝區
        StringBuilder fruitContent = new StringBuilder();

        //將水果名拼接500次
        for (int i = 0; i < 500; i++) {
            fruitContent.append(fruitName);
        }
        return fruitContent.toString();
    }

    //重寫的標題欄返回按鈕的點選事件,結束活動。即返回主活動
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

5、設定RecyclerView的點選事件。

不設定點選事件,自然沒有辦法進入到FruitActivity中。修改FruitAdapter的程式碼:

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    ...
	
    //必須重寫的第一個方法:建立ViewHolder方法
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        
		...
		
        final ViewHolder holder = new ViewHolder(view);

        //設定CardView的點選事件
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //獲取點選項的位置
                int position = holder.getAdapterPosition();
                //獲取水果例項
                Fruit fruit = mFruitList.get(position);

                //啟動FruitActivity,放入水果的名稱、資源ID資訊
                Intent intent = new Intent(mContext, FruitActivity.class);
                intent.putExtra(FruitActivity.FRUIT_NAME, fruit.getName());
                intent.putExtra(FruitActivity.FRUIT_IMAGE_ID, fruit.getImageId());
                mContext.startActivity(intent);
            }
        });

        return holder;
    }

    ...

}

執行程式:


本文總結參考自郭神(郭霖)的《第一行程式碼 第2版》