1. 程式人生 > >第一行程式碼----Material Design(6-7)

第一行程式碼----Material Design(6-7)

6.下拉重新整理

本節我們繼續在前面的基礎上進行改進,加入下拉重新整理功能,該功能的實現需要使用SwipeRefreshLayout,對誰使用呢?當然是我們的RecycleView控制元件啦!

修改activity_main.xml程式碼,在RecycleView外面巢狀一層SwipeRefreshLayout:

<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.v4.widget.SwipeRefreshLayout>

這樣RecycleView就有了下拉重新整理的功能了,這裡要注意的是,現在RecycleView成了SwipeRefreshLayout的子控制元件,所以之前的app:layout_behavior="@string/appbar_scrolling_view_behavior要移到SwipeRefreshLayout中。

接著在MainActivity中處理具體的重新整理邏輯:

在MainActivity中加入:

private SwipeRefreshLayout swipeRefreshLayout;
...
private void refreshFruits() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    initFruits();
                    adapter.notifyDataSetChanged();
                    swipeRefreshLayout.setRefreshing(false);
                }
            });
        }
    }).start();
}

在onCreate()中加入程式碼:

swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.swipe_refresh);
swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
 swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){
     @Override
     public void onRefresh() {
         refreshFruits();
     }
 });

其中setColorSchemeResources是設定進度條的顏色,好了,做完這些後執行程式並下拉就會出現一個停留兩秒鐘的進度條,同時水果資料也會重新整理!

7.可摺疊式標題欄

這裡我們需要用到的是CollapsingToolbarLayout,它是一個作用於Toolbar的佈局,可以讓Toolbar的效果變的更加豐富,但是它不能獨立存在,只能作為AppBarLayout的直接子佈局使用,而AppBarLayout又必須是CoordinatorLayout的子佈局!

首先做一個用於展示水果詳情資訊的介面,新建一個FruitActivity,並在其佈局檔案activity_fruit.xml中新增以下程式碼:

<!--CoordinatorLayout相當於一個加強版的FrameLayout,可以監聽其所有子控制元件的各種事件,並自動做出最優化的響應-->
<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:fitsSystemWindows="true">
    <!--AppBarLayout實際上是一個垂直方向上的LinearLayout內部封裝了很多滾動時間,並應用了一些Material Design的設計理念-->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:fitsSystemWindows="true">
        <!--可摺疊標題欄,能夠實現更華麗的效果,必須作為AppBarLayout的直接子佈局來使用-->
        <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"
            android:fitsSystemWindows="true"
            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"
                android:fitsSystemWindows="true"
                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>
    </android.support.design.widget.AppBarLayout>
    <!--和AppBarLayout是平級的,在這裡用是因為它可以巢狀響應滾動事件,正好可以在CoordiatorLayout內部使用,其內部只允許存在一個直接子佈局-->
    <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_content_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"/>

            </android.support.v7.widget.CardView>
        </LinearLayout>
    </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.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>

這裡app:contentScrim屬性用於指定CollpsingToolbarLayout在趨於摺疊狀態以及摺疊之後的背景色

之前我們見過這個屬性,它是用於指定滾動時標題欄的顯示與隱藏狀態 app:layout_scrollFlags="scroll|exitUntilCollapsed",這裡exitUntilCollapsed表示當CollapsingToolbarLayout完成摺疊後會保留在介面上,不移出螢幕

其中CollpsingToolbarLayout由一個ImageView和一個Toolbar組成,它們兩個都有一個屬性 :app:layout_collapseMode,用於指定當前控制元件在CollapsingToolbarLayout摺疊過程中的摺疊模式,其中值為parallax的代表會在摺疊過程中產生一定的錯位偏移,而pin表示始終不變

至於NestedScrollView,它和AppBarLayout是平級的,在這裡用是因為它可以巢狀響應滾動事件,正好可以在CoordiatorLayout內部使用,其內部只允許存在一個直接子佈局

懸浮按鈕中有個屬性app:layout_anchor,用於指定一個錨點,就是放置懸浮按鈕的區域

這樣介面就弄好了,下面修改FruitActivity的程式碼:

package com.example.qw.materialtest;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBar;
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";
    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);
        setSupportActionBar(toolbar);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.setDisplayHomeAsUpEnabled(true);//設定顯示導航按鈕圖示
        }
        collapsingToolbar.setTitle(fruitName);
        Glide.with(this).load(fruitImageId).into(fruitImageView);
        String fruitContext=generateFruitContent(fruitName);
        fruitContentText.setText(fruitContext);
    }
    private String generateFruitContent(String fruitName){
        StringBuilder fruitContent=new StringBuilder();
        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);
    }
}

最後修改FruitAdapter的程式碼,如下所示:

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
		...
		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);
        final ViewHolder holder=new ViewHolder(view);
        holder.cardView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                int position=holder.getAdapterPosition();
                Fruit fruit=mFruitList.get(position);
                Intent intent=new Intent(mContext,FruitActivity.class);
                intent.putExtra(FruitActivity.FRUIT_NAME,fruit.getName());
                intent.putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.getImagedId());
                mContext.startActivity(intent);
            }
        });
        return holder;
    }

大功告成!!!