如何快速写一款小而美的“上滑无限加载的控件”?-阿里云开发者社区

开发者社区> 开发与运维> 正文

如何快速写一款小而美的“上滑无限加载的控件”?

简介: 在日常从事Android开发工作时,经常会遇到下拉刷新列表页面,上拉自动加载列表的需求, GitHub上已经有很多关于这方面的功能极其强大的类库了,那我们还有必要自己写一个吗?

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

在日常从事Android开发工作时,经常会遇到下拉刷新列表页面,上拉自动加载列表的需求, GitHub上已经有很多关于这方面的功能极其强大的类库了,那我们还有必要自己写一个吗?

答案是:也许。因为那些类库实在是太重了!很多时候我们只使用了其5%的功能,但却不得不忍受剩下那95%的“无用”功能和复杂性。

UI方面,自己实现某些效果很多时候比直接使用现存类库更合适,关于这个话题这个不能深杠,世界上没有最好的东西,只有最适合的东西。
今天我们就简单介绍如何快速写一个一个既可下拉刷新,又可上滑无限加载的小巧灵活的UI控件。

InfiniteRecyclerView

一般情况下我们只使用Android原生提供的那些控件稍作组合或修改即可完成绝大部分UI需求,让我们看一下如何通过简单的组合Android原生的 SwipeRefreshLayout 和RecyclerView来制作一个非常轻量而实用的控件。

准备实现的实用功能

下滑可以刷新页面

上滑可以无限加载

其实日常工作需求最多的也就上面两条。

实现思想

使用SwipeRefreshLayout套一个RecyclerView。如下所示:

image

SwipeRefreshLayout 负责下滑刷新,RecyclerView, 负责上滑加载。
通过RecyclerView的RecyclerView.OnScrollListener 来监听是否滑动到了最后一个item,如果滑动到了最后一个item则触发加载更多操作。

private class OnScrollToBottomListener extends RecyclerView.OnScrollListener {

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    ...

    if (manager instanceof LinearLayoutManager) {
        int lastCompletelyVisibleItemPosition = ((LinearLayoutManager) manager).findLastCompletelyVisibleItemPosition();
        if (adapter.getItemCount() > 1 && lastCompletelyVisibleItemPosition >= adapter.getItemCount() - 1) {
            adapter.loadingMore();
        }
    } else if (manager instanceof StaggeredGridLayoutManager) {
        int[] itemPositions = new int[2];
        ((StaggeredGridLayoutManager) manager).findLastVisibleItemPositions(itemPositions);
        int lastVisibleItemPosition = (itemPositions[1] != 0) ? ++itemPositions[1] : ++itemPositions[0];
        if (lastVisibleItemPosition >= adapter.getItemCount()) {
            adapter.loadingMore();
        }
    }
}

...
}
当处于加载过程中时,在最后一行展示一个加载更多的 view。

具体实现我觉得还是的自己看源代码吧,源代码就是我们程序员有效交流的最好语言。

如何使用?

第一步:自定义一个Adapter,其需要继承RefreshRecycleAdapter, 例如下面这样:
public class BeautyListAdapter extends RefreshRecycleAdapter {

public BeautyListAdapter(List<Beauty> dataSource) {
    super(dataSource);
}

@Override
public RecyclerView.ViewHolder onCreateCustomViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_beauty,parent,false);
    return new BeautyViewHolder(view);
}

@Override
public void onBindCustomViewHolder(RecyclerView.ViewHolder holder, int position) {
    BeautyViewHolder beautyViewHolder= (BeautyViewHolder) holder;
    final Beauty beauty=getList().get(position);
    beautyViewHolder.binding.ivBeautyHead.setImageResource(beauty.getPhotoId());
    beautyViewHolder.binding.tvBeautyTitle.setText(beauty.getName());
    beautyViewHolder.binding.tvBeautyIntroduction.setText(beauty.getIntroduction());
}

static class BeautyViewHolder extends RecyclerView.ViewHolder{
    private final ItemBeautyBinding binding;
    public BeautyViewHolder(@NonNull View itemView) {
        super(itemView);
        binding= ItemBeautyBinding.bind(itemView);
    }
}

}
Note:上面的代码使用了viewBinding功能,对此不熟悉的同学,推荐阅读Android开发之秒懂ViewBinding,一代神器ButterKnife的终结者。
第二步:初始化控件并为其设置Adapter和LayoutManager:
mAdapter = new BeautyListAdapter(mViewModel.dataSource);
mBinding.pullRefreshList.setLayoutManager(new LinearLayoutManager(context));
mBinding.pullRefreshList.setAdapter(mAdapter);
mAdapter.setOnRefreshLoadMoreListener(new AdapterLoader.OnRefreshLoadMoreListener() {

  @Override
  public void onRefresh() {
      //此处调用刷新逻辑
  }

  @Override
  public void onLoadMore() {
      //此处调用加载更多逻辑
  }

});
第三步:处理结果。
当刷新完成后使用如下代码告知控件刷新完成,去掉刷新的标志:

mBinding.pullRefreshList.setRefresh(false);

当加载一页完成后,向数据源增加数据并刷新视图:

mAdapter.notifyDataSetChanged();

当返回的列表为空时,说明已经没有数据了,此时使用如下方法通知控件已经到底了:

mAdapter.setHasMore(false);

优势:

轻量级

强可扩展性,你完全可以获取到SwipeRefreshLayout和RecyclerView,然后对他们进行各种骚操作。

使用简单,与RecyclerView的使用方法保持一致,只要会用RecyclerView就可轻松使用(如果你说你只会用ListView,不会用RecyclerView,我只能对你漏出鄙夷的微笑了)。

总结

2020年突入其来的新冠病毒疫情已经肆虐了4个月了,很多受疫情影响的公司都快撑不住了,身边开始出现很多被裁员的同事和朋友,前两天亲眼目睹了一位被裁的同事情绪崩溃的样子,这件事也给自己敲响了警钟,单纯出卖自己的时间真的是一件很危险的事情,还是要不断的使自己增值,同时去找一件自己喜欢的事情,并坚持做下去。

耳边又想起了那个什么夫斯基的《钢铁是怎样炼成的》:当他回首往事的时候,他不会因虚度年华而悔恨,也不会因碌碌无为而羞耻!当我们回首往事的时候,往往会遗憾没有做过的事情,而不会悔恨做了什么事情。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-05-18
本文作者:ShuSheng007
本文来自:“CSDN”,了解相关信息可以关注“CSDN

版权声明:本文首发在云栖社区,遵循云栖社区版权声明:本文内容由互联网用户自发贡献,版权归用户作者所有,云栖社区不为本文内容承担相关法律责任。云栖社区已升级为阿里云开发者社区。如果您发现本文中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,阿里云开发者社区将协助删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章