第一行程式碼----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;
}
大功告成!!!