1.Android RecyclerView

A flexible view for providing a limited window into a large data set

RecyclerView是support.v7包中的控件,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件还有ListView、GridView。
整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator可以实现极棒的效果,可以说是ListView和GridView的增强升级版

2.Android RecyclerView工作原理

RecyclerView的工作原理与循环有关,视图中滚动的列表项,其实并非在滚动的同时创建这些列表项(这可能会导致故障和性能问题),而是将一些项保持在队列或循环箱中以供再用,当我们滚动时,RecyclerView会将之前创建好的这些列表项中的一个返回给用户,然后代码将列表项视图与新内容绑定起来,然后就可以滚入了,滚出的视图会放回队列中以供再用。

Android recyclerview默认在底部 android recyclerview原理_Android

RecyclerView几乎每个部分都是模块化的。

Adaper是RecyclerView具有的适配器,用于在需要时向RecyclerView提供新视图,还用于将来自数据源的数据绑定到视图

适配器在一个叫做ViewHolder的对象内将视图发送给RecyclerView,ViewHolder包含对项目的根视图对象的引用,并且可用来缓存布局中表示的视图对象以降低使用新数据更新视图的成本,这样将仅在创建新项目时为每个视图调用findViewByID,而无需在每次使用数据填充项目中的视图时调用。

LayoutManager告诉RecyclerView如何布局,可以是垂直滚动列表,水平滚动列表,交错列表或网格列表

3.Android RecyclerView简单使用示例

MainActivity:

package com.example.android.recyclerview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements GreenAdapter.ListItemClickListener{

    private static final int NUM_LIST_ITEMS = 100;

    
    private GreenAdapter mAdapter;
    private RecyclerView mNumbersList;

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

        mNumbersList = (RecyclerView) findViewById(R.id.rv_numbers);

        
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mNumbersList.setLayoutManager(layoutManager);

        mNumbersList.setHasFixedSize(true);

        mAdapter = new GreenAdapter(NUM_LIST_ITEMS,this);
        mNumbersList.setAdapter(mAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int itemId = item.getItemId();

        switch (itemId) {
            case R.id.action_refresh:
                mAdapter = new GreenAdapter(NUM_LIST_ITEMS,this);
                mNumbersList.setAdapter(mAdapter);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onListItemClick(int parameter) {
        if(toast!=null)
            toast.cancel();
        String toastMessage="Item #"+parameter+"clicked.";
        toast=Toast.makeText(this,toastMessage,Toast.LENGTH_LONG);
        toast.show();
    }
}适配器:
package com.example.android.recyclerview;

import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {

    private static final String TAG = GreenAdapter.class.getSimpleName();

    
    private ListItemClickListener mOnClickListener;
    
    private static int viewHolderCount;

    private int mNumberItems;

    
    public interface ListItemClickListener{
        public void onListItemClick(int parameter);
    }
    
    public GreenAdapter(int numberOfItems,ListItemClickListener listItemClickListener) {
        mNumberItems = numberOfItems;
        viewHolderCount = 0;
        mOnClickListener=listItemClickListener;
    }

    
    @Override
    public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.number_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;

        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        NumberViewHolder viewHolder = new NumberViewHolder(view);

        viewHolder.viewHolderIndex.setText("ViewHolder index: " + viewHolderCount);

        viewHolderCount++;
        Log.d(TAG, "onCreateViewHolder: number of ViewHolders created: "
                + viewHolderCount);
        return viewHolder;
    }

    
    @Override
    public void onBindViewHolder(NumberViewHolder holder, int position) {
        Log.d(TAG, "#" + position);
        holder.bind(position);
    }

    
    @Override
    public int getItemCount() {
        return mNumberItems;
    }

    
    class NumberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        TextView listItemNumberView;
        
        TextView viewHolderIndex;

        public NumberViewHolder(View itemView) {
            super(itemView);

            listItemNumberView = (TextView) itemView.findViewById(R.id.tv_item_number);
            viewHolderIndex = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);
            
            itemView.setOnClickListener(this);
        }

        
        void bind(int listIndex) {
            listItemNumberView.setText(String.valueOf(listIndex));
        }

        @Override
        public void onClick(View view) {
            int clickedPosition=getAdapterPosition();
            mOnClickListener.onListItemClick(clickedPosition);
        }
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--添加-RecyclerView->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_numbers"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>


列表项:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">

    <TextView
        android:id="@+id/tv_item_number"
        style="@style/TextAppearance.AppCompat.Title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|start"
        android:fontFamily="monospace"
        android:textSize="42sp"
        tools:text="#42" />

    <TextView
        android:id="@+id/tv_view_holder_instance"
        style="@style/TextAppearance.AppCompat.Title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|end"
        android:fontFamily="monospace"
        android:textColor="#000"
        tools:text="ViewHolder instance: 7" />
</FrameLayout>

附加:
分割线:mRecyclerView.addItemDecoration() 我们可以通过该方法添加分割线;

布局:RecyclerView.LayoutManager是一个抽象类,系统提供了3个实现类:

LinearLayoutManager 现行管理器,支持横向、纵向。

GridLayoutManager 网格布局管理器

StaggeredGridLayoutManager 瀑布就式布局管理器

设置Item增加、移除动画:mRecyclerView.setItemAnimator(new DefaultItemAnimator());ItemAnimator也是一个抽象类,好在系统为我们提供了一种默认的实现类

参考:RecyclerView | Android Developers