『Material Design入門學習筆記』RecyclerView與CardView(附demo)

此次要說的內容用到的會很普遍,我儘量多的講到一些細節性的東西。
該專題的其它文章:
『Material Design入門學習筆記』前言
『Material Design入門學習筆記』動畫(含demo)
『Material Design 入門學習筆記』主題與 AppCompatActivity(附 demo)
demo下載javascript

RecyclerView

佈局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <include layout="@layout/toolbar_test"/> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:id="@+id/recycler" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </LinearLayout>複製代碼

看到上面佈局文件可知,RecyclerView是v7裏的東西,因此理所固然的要依賴v7。其次include的佈局是上一節講過的toolbar。java

Adapter

RecyclerView與ListView同樣,也須要一個Adapter,只是Adapter有些不一樣,RecyclerView的Adapter自帶了性能優化機制,包括ViewHolder。android

public class CardListAdapter extends RecyclerView.Adapter<CardListAdapter.MyViewHolder>{
private Context context;
private ArrayList<String> list ;
    private IcardViewChanger icardViewChanger;
public CardListAdapter(Context context,ArrayList<String> list){
    this.context = context;
    this.list = list;
    }
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
    context).inflate(R.layout.item_cardview, parent,
    false));
    return holder;
    }

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.tv.setText(list.get(position));
    if (icardViewChanger!=null){
        icardViewChanger.changeCardView(holder.cardView);
    }

    }


    @Override
public int getItemCount() {
    return list.size();
    }
class MyViewHolder extends RecyclerView.ViewHolder {

    TextView tv;
    CardView cardView;
    public MyViewHolder(View view)
    {
        super(view);
        tv = (TextView) view.findViewById(R.id.text);
        cardView = (CardView) view.findViewById(R.id.cardView);
    }
}
}複製代碼

構造方法我就很少說了,onCreateViewHolder至關與BaseAdapter的getView中的View構建。ListView的Adapter須要手動判斷,view是否爲空,而後決定是否創建。如今只要在onCreateViewHolder方法中寫view的構建便可。
onBindViewHolder是用來處理界面邏輯,至關於BaseAdapter的getView中的界面處理邏輯。每次刷新界面,都會被動調用該方法。
getItemCount就是返回Item的數量。
而後就是ViewHolder的構建了。要注意這要繼承RecyclerView.ViewHolder
關於這裏面所用的佈局文件,下文中講解CardView的時候會提。
而後就是設置RecyclerView了。git

recyclerView = (RecyclerView)findViewById(R.id.recycler);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setItemAnimator(new DefaultItemAnimator());複製代碼

RecyclerView.LayoutManager吧,這是一個抽象類,好在系統提供了3個實現類:github

  • LinearLayoutManager 現行管理器,支持橫向、縱向。
  • GridLayoutManager 網格佈局管理器
  • StaggeredGridLayoutManager 瀑布就式佈局管理器
    setItemAnimator是刪減動畫。
    咱們能夠經過該方法添加分割線mRecyclerView.addItemDecoration()
    關於動畫和分割線,均可以經過繼承的方式設置成你想要的效果。這裏再也不細說。性能優化

    CardView

    CardView支持多種效果,咱們可讓RecyclerView中的Item都使用CardView。app

    依賴

    若是須要使用CardView,須要依賴:ide

    compile 'com.android.support:cardview-v7:25.3.1'複製代碼

    如今回到CardListAdapter,看一下佈局文件item_cardview佈局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:orientation="vertical"
                android:layout_width="match_parent"
    
                android:layout_height="wrap_content">
    <android.support.v7.widget.CardView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:background="#558b2f"
      android:layout_margin="10dp"
      app:cardBackgroundColor="#558b2f"
      android:id="@+id/cardView">
      <RelativeLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
          <ImageView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentLeft="true"
              android:src="@mipmap/ic_launcher_round"
              android:id="@+id/logo"/>
          <TextView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text=""
              android:layout_alignParentRight="true"
              android:id="@+id/text"/>
      </RelativeLayout>
    </android.support.v7.widget.CardView>
    </LinearLayout>複製代碼

    CardView有一些基本屬性:post

app:cardBackgroundColor這是設置背景顏色
app:cardCornerRadius這是設置圓角大小
app:cardElevation這是設置z軸的陰影
app:cardMaxElevation這是設置z軸的最大高度值
app:cardUseCompatPadding是否使用CompatPadding
app:cardPreventCornerOverlap是否使用PreventCornerOverlap
app:contentPadding 設置內容的padding
app:contentPaddingLeft 設置內容的左padding
app:contentPaddingTop 設置內容的上padding
app:contentPaddingRight 設置內容的右padding
app:contentPaddingBottom 設置內容的底padding

至此CardView的相關屬性已經介紹完畢。而後咱們會根據屬性值,設置幾種CardView,進行對比。

拓展

首先咱們增長一個接口

public interface IcardViewChanger {
    public void changeCardView(CardView cardView);
}複製代碼

用這個接口來設置CardView,首先在CardListAdapter中添加一個方法:

public void setIcardViewChanger(IcardViewChanger icardViewChanger) {
        this.icardViewChanger = icardViewChanger;
    }複製代碼

修改onBindViewHolder

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.tv.setText(list.get(position));
    if (icardViewChanger!=null){
        icardViewChanger.changeCardView(holder.cardView);
    }
    Log.e("xxxxxx" ,"onBindViewHolder");
    }複製代碼

而後咱們在使用RecyclerView的Activity中設置調用:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_card,menu);
        return  true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.btn_changeElevation:
               adapter.setIcardViewChanger(new IcardViewChanger() {
                   @Override
                   public void changeCardView(CardView cardView) {
                       cardView.setCardElevation(80);
                   }
               });
                adapter.notifyDataSetChanged();
                break;
            case R.id.btn_changeRadius:
                adapter.setIcardViewChanger(new IcardViewChanger() {
                    @Override
                    public void changeCardView(CardView cardView) {
                        cardView.setRadius(80);
                    }
                });
                adapter.notifyDataSetChanged();
                break;
            case R.id.btn_changeColor:
                adapter.setIcardViewChanger(new IcardViewChanger() {
                    @Override
                    public void changeCardView(CardView cardView) {
                        cardView.setCardBackgroundColor(getResources().getColor(R.color.cardBackground));
                    }
                });
                adapter.notifyDataSetChanged();
                break;
        }

        return super.onOptionsItemSelected(item);
    }複製代碼

最後給你們貼出一張展現圖:

總結

RecyclerView與CardView並不必定要連起來使用,若是有須要能夠拆開使用,我這裏是爲了方便作demo一塊兒展現。
對於RecyclerView與CardView的更多設置,能夠在我demo的基礎上進行修改實驗。
不得不說有了這兩個組件,Android不少界面處理起來簡單多了,不只由於接口設置多了,同時,對於操做進行了解耦,例如動畫和分割線ViewHolder等。
有問題能夠給我留言,或者關注個人公衆號留言。

相關文章
相關標籤/搜索