Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> RecyclerView綜合解析

RecyclerView綜合解析

編輯:關於Android編程

什麼是RecyclerView?

RecyclerView其實就是一個在5.0推出的控件,可以用它來代替ListView和GridView,從這一點也能看出來它的特性和ListView以及GridView類似,注意我說的是整體上類似,既然是更高的版本推出的,豈能再和再和低版本的小崽子們一個層次,所以它加入了很多新的特征,下面會講到。

為什麼叫RecyclerView?

雖然在計算機界,起名字一直都比較個性,比較不符合常理,通常情況下試圖通過名字來了解一件事物的人都會走火入魔,想當年,我就想知道android為啥叫android,是不是什麼縮寫,但是後來確實讓朕很失望,類似的還有apple(這裡指手機),oracle(甲骨文)通過這些名字來了解一些事物真是相當困難,但是RecyclerView和他的功能還是有一些聯系的:

RecyclerView不關心Item是否顯示在正確的位置,以及如何顯示。 RecyclerView不關心Item之間如何間隔。 不關注Item增加與刪除的動畫效果。 它只關注如何回收和復用View(這就是叫RecycleView的原因)。

嗯?什麼都不關心,那還玩個毛線啊?
這位看官說的好,RecyclerView既然敢這麼玩,當然是有手段的:

不關心Item是否顯示在正確的位置,以及如何顯示,此時我們用LayoutManager來解決。 不關心Item之間如何間隔,此時我們用ItemDecoration來解決。 不關心Item的增加與刪除的動畫效果,此時用ItemAnimator來解決。

看到了吧,真正牛逼的人是不需要什麼都管的,只要有人就行。

這位看官又問啦,RecyclerView都有啥人(相關類)啊?看官且看:

Adapter ViewHolder LayoutManager ItemDecoration ItemAnimator

O啦,主公以及大將都悉數登場了,看官可能又要問了,這陣容能干點啥大事呢? 嗯,問的好,以下就是此陣容能干的事:

Just like ListView(實現listview的效果) Just like GridView(實現GridView的效果) 實現橫向的ListView效果 實現橫向的GridView效果 實現瀑布流(此處可以通過名字來理解其效果) 定制Item增加和刪除動畫

都是字啊,是騾子是馬拉出來溜溜,來圖讓我看看!好,看官既然這麼急切,那就來一波:

實現listview的效果

這裡寫圖片描述

實現垂直GridView的效果

這裡寫圖片描述

實現橫向的GridView效果
這裡寫圖片描述

瀑布流:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160429/20160429090227312.gif" title="\" />

動畫效果(可以自己設置各種動畫)

這裡寫圖片描述

好,准備工作完成,開始編寫:

實現Recyclerview

首先:導入android-support-v7-recyclerview.jar包,如果是android studio 直接加入依賴即可。

設置主布局:



    

item布局



    

MainActivity代碼:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private List list;
    private SimpleAdap adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iniDatas();

        iniView();
        adapter = new SimpleAdap(this,list);
        recyclerView.setAdapter(adapter);
        //設置以listview形式顯示
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
        recyclerView.setLayoutManager(layoutManager);
    }

    private void iniView() {
        recyclerView = (RecyclerView) findViewById(R.id.idrecyclerview);
    }

    private void iniDatas() {
        list = new ArrayList<>();
        Random ran = new Random(50);
        for(int i=0;i<50;i++){
            list.add(String.valueOf(ran.nextInt())+i);
        }
    }
}
class SimpleAdap extends RecyclerView.Adapter{

    private LayoutInflater layoutInflater;
    private List mData;
    private Context context;
    public SimpleAdap(Context context, List list) {
        this.context = context;
        mData = list;
        layoutInflater = LayoutInflater.from(context);
    }

    //google將對viewholder的操作分成了兩步,創建和綁定,體現了google對viewholder的強制性
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = layoutInflater.inflate(R.layout.item_recyclerview,parent,false);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    //綁定數據
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.text.setText(mData.get(position));
    }

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

class MyViewHolder extends RecyclerView.ViewHolder {
 public TextView text;
    public MyViewHolder(View itemView) {
        super(itemView);
        text = (TextView) itemView.findViewById(R.id.item_recyclerview);
    }
}

此時的item之間是沒有分割線的
如圖:

這裡寫圖片描述

這怎麼能行呢?跟塊黑板似的,listview得有分割線啊!
看官且看下面,待我添加分割線!

添加分割線

其實對於recyclerView來說,添加分割線很簡單,可以交給它的小弟ItemDecoration來實現:

 //設置listview之間的分割線
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);
        recyclerView.addItemDecoration(dividerItemDecoration);//參數是抽象類itemDecoration的實現類,因為沒有現成的,所以從github download一個

需要注意的是,recyclerView.addItemDecoration(dividerItemDecoration);中傳入的參數系統並沒有為我們提供,我在此是在github上down的一個類,鏈接地址。

現在有了分割線,如圖:

這裡寫圖片描述

利用github上的源碼自定義分割條

看官心中是否有疑問,這個白色的分割線是設置的顏色?還是圖片?從哪設置的?
這就需要看剛才從github上下載的那個源碼了

在源碼中,有這麼一句代碼:

final TypedArray a = context.obtainStyledAttributes(ATTRS);

通過順籐摸瓜,我們就可以知道,白色分割線就是從style中得到的,哼哼,知道了這些那就好辦了,我們可以自定義我們的分割條了。

只需要在styles.xml中添加這樣的一句代碼:

@drawable/ic_launcher

此時我用系統提供的一張圖片來作為分割線,如圖所示:

這裡寫圖片描述

什麼?沒有看到分割線? android圖標那個就是分割線(確實有點大)

在此只是實例,在正式使用的時候,我們完全可以自定義一個drawale,然後進行設置。

實現GridView

在實現之前先說一點,當我們使用recyclerview的時候,要把它作為listview和gridview的綜合體,不要總想著以前的listview和gridview是兩個不同的控件,這是一個思想上的轉變(思想是最重要的)。

豎直gridview

//第二個參數為gridview的列數
recyclerView.setLayoutManager(new GridLayoutManager(this,4));

橫向gridview

recyclerView.setLayoutManager(new StaggeredGridLayoutManager(5,StaggeredGridLayoutManager.HORIZONTAL));

注意:在使用水平的gridview的是有,itemview的寬不能為match_parent,並且上面分割線的設置在此也不適用了。

瀑布流

瀑布流,其實就是item的寬或者高不一樣,造成參差不齊的效果而已!

設置瀑布管理器:

        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));

在適配器中初始化一個數據集合:

mHeight = new ArrayList<>();
        for(int i=0;i

在onBindViewHolder中設置item高度:

public void onBindViewHolder(seViewHolder holder, int position) {
        holder.text.setText(mData.get(position));
        ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
        layoutParams.height = mHeight.get(position);
        holder.itemView.setLayoutParams(layoutParams);
    }

增加刪除動畫

設置動畫:

recyclerView.setItemAnimator(new DefaultItemAnimator());

在適配器中添加兩個方法:

public void add(int position){
        mData.add(position,"Insert data");
        notifyItemInserted(position);//此處要注意,和listview不一樣
    }

    public void delete(int position){
        mData.remove(position);
        notifyItemRemoved(position);
    }

在onOptionsItemSelected中調用方法:

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.listview:
                recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
                break;
            case R.id.heng_listview:
                break;
            case R.id.gridview:
                recyclerView.setLayoutManager(new GridLayoutManager(this,4));
                //recyclerView.addItemDecoration(dividerItemDecoration);
                break;
            case R.id.heng_grid:
                recyclerView.setLayoutManager(new StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.HORIZONTAL));
                break;
            case R.id.pubu:
                Intent intent = new Intent(this,PubuActivity.class);
                startActivity(intent);
                break;
            case R.id.delete:
                adapter.delete(1);
                break;
            case R.id.add:
                adapter.add(1);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

添加監聽

說到recyclerview的監聽,我要告訴看官一個悲傷的故事—-recyclerview的監聽需要自己實現

實現監聽的方式有很多,在此,利用在適配器中設置接口回調的方法!

在適配器中定義接口:

public interface  OnItemClickListener{
        void onItemClick(View view,int position);
        void onItemLongClick(View view,int position);
    }

對外提供方法:

private OnItemClickListener onItemClickListener;
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

在中定義監聽:

public void onBindViewHolder(MyViewHolder holder, final int position) {
        holder.text.setText(mData.get(position));
//        ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
//        layoutParams.height = mHeight.get(position);
//        holder.itemView.setLayoutParams(layoutParams);
        if(onItemClickListener!=null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onItemClick(v, position);
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    onItemClickListener.onItemLongClick(v, position);
                    return false;
                }
            });
        }
    }

使用回調方法設置監聽:

adapter.setOnItemClickListener(new SimpleAdap.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this, "item"+position, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemLongClick(View view, int position) {
                Toast.makeText(MainActivity.this, "long"+position, Toast.LENGTH_SHORT).show();
            }
        });

注意:如果我們此時利用上面介紹的添加刪除item的方法,添加了或者刪除了item,這是我們點擊item的時候,會發現position會不正常,具體表現在當我們添加多個item的時候,會發現所添加的每個item點擊的時候都是同一個position。

解決方法:

public void onBindViewHolder(final MyViewHolder holder, final int position) {
        holder.text.setText(mData.get(position));
        if(onItemClickListener!=null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();//用此方法得到全局position,傳入點擊事件中
                    onItemClickListener.onItemClick(v, layoutPosition);
                }
            });
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int layoutPosition = holder.getLayoutPosition();
                    onItemClickListener.onItemLongClick(v, layoutPosition);
                    return false;
                }
            });
        }
    }

OK,散會!

相關知識點,是本人對慕課網相關課程的總結,也是作為自己的學習記錄

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved