目前,随着Material Design的使用越来越多,RecyclerView 基本上全面替换了ListView,GridView. 使用RecyclerView确实更加灵活,功能也更加强大,本文不讲解RecyclerView的基础使用,说一下RecyclerView的进阶使用。
使用过RecyclerView的同学可能都会感觉到设置Adapter很麻烦,这里推荐一下张鸿洋大神的通用Adapter,具体的使用请看大神的博客,这里就不赘述了,具体使用请看大神的博客,http://blog.csdn.net/lmj623565791/article/details/47251585。
RecyclerView的上拉刷新和下拉加载更多参考 zhuliyuan丶大神的博客,这里借鉴一下。
RecyclerView的下拉刷新可以使用SwipeRefreshLayout。
public class MainActivity extends AppCompatActivity {
private List<String> dataList = new ArrayList<>();
private RefreshRecyclerView rv;
private MyAdapter myAdapter;
private SwipeRefreshLayout srl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
private void initView() {
srl = (SwipeRefreshLayout) findViewById(R.id.srl);
srl.setColorSchemeResources(android.R.color.holo_red_light, android.R.color.holo_blue_light, android.R.color.holo_green_light);
rv = (RefreshRecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setLoadMoreEnable(true);//允许加载更多
rv.setFooterResource(R.layout.item_footer);//设置脚布局
myAdapter = new MyAdapter(dataList);
rv.setAdapter(myAdapter);
}
private void initData() {
for (int i = 0; i < 20; i++) {
dataList.add("数据" + i);
}
rv.notifyData();
}
private void initListener() {
rv.setOnLoadMoreListener(new RefreshRecyclerView.OnLoadMoreListener() {
@Override
public void loadMoreListener() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
dataList.add("更多数据" + i);
}
rv.notifyData();//刷新数据
}
}, 2000);
}
});
srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
srl.setRefreshing(false);
dataList.add(0, "最新数据");
rv.notifyData();//刷新数据
}
}, 2000);
}
});
}
private Handler handler = new Handler();
}
在Activity
中,Re
cyclerview的写法没有太大变化,只是有如下几点需要注意1.如果想要加载更多需要调用(必须)
rv.setLoadMoreEnable(true)
2.如果希望加载更多时候有脚布局提示需要调用(不是必须的)
rv.setFooterResource(int res)
3.实现加载更多回调(必须)
rv.setOnLoadMoreListener()
4.刷新数据调用(必须)
rv.notifyData()
上拉加载更多使用的是自己封装的RecyclerView.
public class RefreshRecyclerView extends RecyclerView {
private AutoLoadAdapter autoLoadAdapter;
public RefreshRecyclerView(Context context) {
this(context, null);
}
public RefreshRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private boolean isLoadingMore = false;//是否正在加载更多
private OnLoadMoreListener loadMoreListener;//加载数据监听
private boolean loadMoreEnable = false;//是否允许加载更多
private int footerResource = -1;//脚布局
private boolean footer_visible = false;//脚部是否可以见
private void init() {
setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (getAdapter() != null && getLayoutManager() != null) {
int lastVisiblePosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
int itemCount = getAdapter().getItemCount();
/**
* 控制下拉刷新回调
* itemCount != 0 排除没有数据情况
* lastVisiblePosition + 4 >= itemCount - 1 最后可见+4 >= 总条数 加载更多
* distanceY < 0 为上拉的时候才刷新
*/
if (distanceY < 0 && itemCount != 0 && lastVisiblePosition + 4 >= itemCount - 1 && !isLoadingMore && loadMoreEnable) {
Log.i("test","加载更多");
//正在加载更多
loading();
if (footerResource != -1){//有脚布局
//显示脚布局
footer_visible = true;
getAdapter().notifyItemChanged(itemCount - 1);
}
if (loadMoreListener != null) {
loadMoreListener.loadMoreListener();
}
}
}
}
});
}
/**
* 判断滑动方向
*/
private float distanceY = 0;
float startY = 0;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
float y = ev.getRawY();
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
startY = y;
break;
case MotionEvent.ACTION_MOVE:
distanceY = y - startY;
startY = y;
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public void setAdapter(Adapter adapter) {
SlideInBottomAnimationAdapter slideInBottomAnimationAdapter = new SlideInBottomAnimationAdapter(adapter);
slideInBottomAnimationAdapter.setDuration(600);
autoLoadAdapter = new AutoLoadAdapter(slideInBottomAnimationAdapter);//添加动画
super.setAdapter(autoLoadAdapter);
}
/**
* 设置是否允许加载更多
*
* @param isEnable
*/
public void setLoadMoreEnable(boolean isEnable) {
this.loadMoreEnable = isEnable;
}
/**
* 设置脚布局
*/
public void setFooterResource(int footerResource) {
this.footerResource = footerResource;
}
/**
* 加载完成
*/
private void loadMoreComplete() {
this.isLoadingMore = false;
}
/**
* 正在刷新
*/
private void loading(){
this.isLoadingMore = true;//设置正在刷新
}
/**
* 加载更多数据回调
*
* @param listener
*/
public void setOnLoadMoreListener(OnLoadMoreListener listener) {
this.loadMoreListener = listener;
}
public interface OnLoadMoreListener {
void loadMoreListener();//上拉刷新
}
/**
* 刷新数据
*/
public void notifyData() {
if (getAdapter() != null) {
loadMoreComplete();
if(footerResource != -1 && loadMoreEnable){
//隐藏脚布局
footer_visible = false;
}
getAdapter().notifyDataSetChanged();
}
}
public class AutoLoadAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Adapter dataAdapter;//数据adapter
private final int TYPE_FOOTER = Integer.MAX_VALUE;//底部布局
public AutoLoadAdapter(RecyclerView.Adapter adapter) {
this.dataAdapter = adapter;
}
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1 && loadMoreEnable && footerResource != -1 && footer_visible) {
return TYPE_FOOTER;
}
if (dataAdapter.getItemViewType(position) == TYPE_FOOTER) {
throw new RuntimeException("adapter中itemType不能为:" + Integer.MAX_VALUE);
}
return dataAdapter.getItemViewType(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder holder = null;
if (viewType == TYPE_FOOTER) {//脚部
holder = new FooterViewHolder(LayoutInflater.from(getContext()).inflate(footerResource, parent, false));
} else {//数据
holder = dataAdapter.onCreateViewHolder(parent, viewType);
}
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
int itemViewType = getItemViewType(position);
if (itemViewType != TYPE_FOOTER) {
dataAdapter.onBindViewHolder(holder, position);
}
}
@Override
public int getItemCount() {
if (dataAdapter.getItemCount() != 0) {
int count = dataAdapter.getItemCount();
if (loadMoreEnable && footerResource != -1 && footer_visible) {
count++;
}
return count;
}
return 0;
}
public class FooterViewHolder extends RecyclerView.ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
}
}
}
}
项目中recyclerview动画地址https://github.com/wasabeef/recyclerview-animators。