SwipeRefreshLayout与RecyclerView的巧夺天工(二)

简介: SwipeRefreshLayout与RecyclerView的巧夺天工(二)

3.实现下拉刷新,上滑加载


为了代码的重用效率高,我写了一个基类BaseActivity:

public abstract class BaseActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
    /***
     * 处理下拉和刷新滴
     */
    protected SwipeRefreshLayout swipeRefreshLayout;
    /***
     * 进化的ListView
     */
    protected RecyclerView recyclerView;
    /***
     * 该布局在没有网络的时候,显示的布局
     */
    protected LinearLayout linearLayout;
    /***
     * RecyclerView的样式(网格,瀑布,线性)
     */
    protected LinearLayoutManager mLayoutManager;
    /***
     * 记录最后一项的位置
     */
    protected int lastVisibleItem=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.activity_main_swipe);
        this.recyclerView=(RecyclerView)findViewById(R.id.activity_main_recyclerview);
        this.linearLayout=(LinearLayout)findViewById(R.id.activity_main_linearlayout);
        initView();
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
            }
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                onRecyclerViewStateChanged(newState);
            }
        });
    }
    @Override
    public void onRefresh() {
        onRecyclerViewRefresh();
    }
    /***
     * 初始化界面
     */
    public abstract void initView();
    /***
     * 监听RecyclerView滑动事件
     * @param newState 滑动状态
     */
    public abstract void onRecyclerViewStateChanged(int newState);
    /***
     * 下拉刷新处理
     */
    public abstract void onRecyclerViewRefresh();
}


注释非常明确,布局中有一个linearlayout其中无任何控件,是为了扩展任何你需要的无网络时显示的界面的。你只需要继承该类实现这几个抽象方法。


㈠自定义适配器


代码如下:

public class LYJRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    /***
     * 每项的数据集合
     */
    private List<String> messageItems;
    /***
     * 监听item点击事件。
     */
    private LYJItemClickListener mItemClickListener;
    /***
     * 一共显示多少条数据
     */
    private int totalSize;
    public LYJRecyclerViewAdapter(List<String> messageItems,int size){
        this.messageItems=messageItems;
        this.totalSize=size;
    }
    /***
     * 监听点击事件接口
     */
    public interface LYJItemClickListener {
        public void onItemClick(View view, int postion);
    }
    /***
     * 设置item点击事件
     * @param listener
     */
    public void setOnItemClickListener(LYJItemClickListener listener) {
        this.mItemClickListener = listener;
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        if (i == Constants.TYPE_ITEM) {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(
                    R.layout.activity_main_adapter_item, null);
            view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            return new ItemViewHolder(view,this.mItemClickListener);
        }
        //滑动到底部返回footview
        else if (i == Constants.TYPE_FOOTER) {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(
                    R.layout.activity_main_adapter_footview, null);
            view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            return new FooterViewHolder(view);
        }
        return null;
    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
        if(viewHolder instanceof ItemViewHolder){
            ((ItemViewHolder) viewHolder).name.setText(messageItems.get(i));
        }else{
            if(this.totalSize==(getItemCount()-1)){
                ((FooterViewHolder)viewHolder).flagTxt.setText("已经加载完全部内容");
            }else{
                ((FooterViewHolder)viewHolder).flagTxt.setText("正在加载中........");
            }
        }
    }
    @Override
    public int getItemCount() {
        return messageItems.size()+1;//加1是多的footview那一项,也就是滑动到footview就加载,而不是最后数据项。
    }
    @Override
    public int getItemViewType(int position) {
        if (position + 1 == getItemCount()) {
            return Constants.TYPE_FOOTER;
        } else {
            return Constants.TYPE_ITEM;
        }
    }
    /***
     * 底部布局
     */
    public class FooterViewHolder extends RecyclerView.ViewHolder {
        private TextView flagTxt;
        public FooterViewHolder(View itemView) {
            super(itemView);
            this.flagTxt=(TextView)itemView.findViewById(R.id.activity_main_adapter_footview_txt);
        }
    }
    /***
     * 数据项布局
     */
    class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private TextView name;
        private LYJItemClickListener mListener;//设置点击事件
        public ItemViewHolder(View itemView, LYJItemClickListener listener) {
            super(itemView);
            this.name = (TextView) itemView.findViewById(R.id.activity_main_adapter_item_name);
            this.mListener = listener;
            itemView.setOnClickListener(this);//设置点击事件
        }
        @Override
        public void onClick(View v) {
            if (mListener != null) {
                mListener.onItemClick(v, getPosition());
            }
        }
    }
}


㈡MainActivity的实现


其继承自BaseActivity,并且实现item点击事件接口LYJRecyclerViewAdapter.LYJItemClickListener:

public class MainActivity extends BaseActivity implements LYJRecyclerViewAdapter.LYJItemClickListener{
    /***
     * 数据项
     */
    private List<String> messageItems=new ArrayList<>();
    /***
     * 自定义adapter
     */
    private LYJRecyclerViewAdapter adapter;
    /***
     * 获取资源文件字符串中间转换集合
     */
    private List<String> strFlag;
    @Override
    public void initView() {
        Toolbar toolbar=(Toolbar)findViewById(R.id.activity_main_toolbar);
        toolbar.setTitle("");
        setSupportActionBar(toolbar);
        this.swipeRefreshLayout.setColorSchemeColors(Color.RED);//设置加载内圈颜色
        this.swipeRefreshLayout.setOnRefreshListener(this);//设置下拉刷新事件
        this.swipeRefreshLayout.setProgressBackgroundColorSchemeColor(getResources().getColor(R.color.activity_main_tablayout_bg));//设置加载外圈颜色
        // 这句话是为了,第一次进入页面的时候显示加载进度条
        swipeRefreshLayout.setProgressViewOffset(false, 0, (int) TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()
                        .getDisplayMetrics()));
        mLayoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);//设置布局样式
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(mLayoutManager);
        loadingRecyclerView(Constants.LISTVIEW_INIT);//初始化RecyclerView
    }
    @Override
    public void onRecyclerViewStateChanged(int newState) {
        if (messageItems == null || messageItems.size() <= 0) {
            Snackbar.make(swipeRefreshLayout, "没有数据得先下拉刷新", Snackbar.LENGTH_SHORT).show();
            return;
        }
        //滚动事件结束并且到达最底端
        if (newState == RecyclerView.SCROLL_STATE_IDLE
                && lastVisibleItem + 1 == adapter.getItemCount()) {
            loadingRecyclerView(Constants.LISTVIEW_DOWNLOAD);//下滑RecyclerView
        }
    }
    @Override
    public void onRecyclerViewRefresh() {
        loadingRecyclerView(Constants.LISTVIEW_REFRESH);//下拉刷新RecyclerView
    }
    public void loadingRecyclerView(int recyclerViewState){
        swipeRefreshLayout.setRefreshing(true);//打开加载动画
        if (!LYJNetwork.isNetworkAvailable(MainActivity.this)) {
            Snackbar.make(swipeRefreshLayout, "没有网络你逗我玩啊?", Snackbar.LENGTH_SHORT).show();
            swipeRefreshLayout.setRefreshing(false);//没有网络时候直接关闭加载动画
            return;
        }
        //当为初始化的时候
        if(recyclerViewState==Constants.LISTVIEW_INIT){
            addStringToList();
            adapter=new LYJRecyclerViewAdapter(messageItems,100);
            recyclerView.setAdapter(adapter);
        }else if(recyclerViewState==Constants.LISTVIEW_REFRESH){
            //当为下拉刷新的时候
            messageItems.clear();
            addStringToList();
            recyclerView.setAdapter(null);
            adapter = new LYJRecyclerViewAdapter(messageItems,100);
            adapter.setOnItemClickListener(MainActivity.this);
            recyclerView.setAdapter(adapter);
        }else{
            //当为下滑加载的时候
            if(messageItems.size()!=100){
                addStringToList();
                adapter.notifyDataSetChanged();
            }
        }
        swipeRefreshLayout.setRefreshing(false);//执行完成也要关闭加载动画
    }
    @Override
    public void onItemClick(View view, int postion) {
        //每项的点击事件
    }
    //模拟增加数据
    public void addStringToList(){
        strFlag= Arrays.asList(getResources().getStringArray(R.array.welltest_array_string));
        for(int i=0;i<strFlag.size();i++){
            messageItems.add(strFlag.get(i));
        }
    }
}

这样谷歌官方控件的下拉刷新,上滑动加载就完成了。


从这里可以看到,虽然说ListView有点击事件,有许多扩展,但你想扩展ListView就必须重构很多地方。而RecyclerView,虽然什么都没有,但你扩展起来要方便的多。这就是从0开始的优势。当一个框架继承了很多很多东西,那么你要修改其中的东西,那么就是牵一发而动全身。没有最适合的框架,只有最优解。


本文源码:(MainActivity为本文源码,自行修改)


http://download.csdn.net/detail/liyuanjinglyj/9418932


看看最后实现的效果:

60.png


相关文章
|
存储 算法 Android开发
Jetpack-Compose 学习笔记(三)—— Compose 的自定义“View”(下)
Jetpack-Compose 学习笔记(三)—— Compose 的自定义“View”(下)
257 0
|
小程序 JavaScript
微信小程序--动态时间实现
微信小程序--动态时间实现
372 0
|
缓存 Java 容器
【Spring IOC容器加载过程】
【Spring IOC容器加载过程】
328 1
|
8月前
|
存储 监控 druid
Druid、ClickHouse、Doris、StarRocks 的区别与分析
本文对比了 Druid、ClickHouse、Doris 和 StarRocks 四款大数据分析引擎。它们均为 OLAP 引擎,采用列式存储和分布式架构,适用于海量数据分析。Druid 擅长实时分析与高并发查询;ClickHouse 以超高性能著称,适合复杂查询;Doris 提供易用的 SQL 接口,性能均衡;StarRocks 则以其极速查询和实时更新能力脱颖而出。各引擎在数据模型、查询性能、数据更新和存储方面存在差异,适用于不同的业务场景。选择时需根据具体需求综合考虑。
3645 20
|
8月前
|
存储 人工智能 数据管理
云端问道17期方案教学-AI场景下的对象存储OSS数据管理实践
本文介绍了AI场景下的对象存储OSS数据管理实践,由阿里云技术专家明锦分享。主要内容分为两部分:1) AI场景下对象存储实践方案,包括对象存储的应用、优势及在模型推理中的优化;2) OSS常用工具介绍,如OSSFS、Python SDK、Go SDK等,并详细说明了这些工具的特点和使用场景。文中还探讨了不同模式下的性能优化,以及即将推出的OS Connector for AI/ML工具,旨在提升数据下载速度和IO性能。
176 0
|
9月前
|
API 索引
HarmonyOs开发:导航tabs组件封装与使用
主页的底部导航以及页面顶部的切换导航,无论哪个系统,哪个App,都是最常见的功能之一,虽然说在鸿蒙中有现成的组件tabs可以很快速的实现,但是在使用的时候,依然有几个潜在的问题存在,第一,当导航较少时,tabs是默认居中模式,目前无法进行居左,在有这样功能的时候,难以满足需求;第二,导航右侧需要展示按钮的时候,tabs也是无法满足的;除此之外,还有很多人都非常关心的问题,底部的指示器可以跟随页面的滑动而滑动;面对着种种问题的存在,系统的tabs改进之路仍然很艰巨。
230 5
HarmonyOs开发:导航tabs组件封装与使用
|
SQL 存储 NoSQL
数据模型与应用场景对比:SQL vs NoSQL
【8月更文第24天】随着大数据时代的到来,数据存储技术也在不断演进和发展。传统的SQL(Structured Query Language)数据库和新兴的NoSQL(Not Only SQL)数据库各有优势,在不同的应用场景中发挥着重要作用。本文将从数据模型的角度出发,对比分析SQL和NoSQL数据库的特点,并通过具体的代码示例来说明它们各自适用的场景。
302 0
|
Shell Linux 开发工具
Anaconda安装后报错 -bash: conda: command not found 如何处理
【6月更文挑战第17天】Anaconda安装后报错 -bash: conda: command not found 如何处理
740 4
|
机器学习/深度学习 数据挖掘
机器学习模型的选择与评估:技术深度解析
【8月更文挑战第21天】机器学习模型的选择与评估是一个复杂而重要的过程。通过深入理解问题、选择合适的评估指标和交叉验证方法,我们可以更准确地评估模型的性能,并选择出最适合当前问题的模型。然而,机器学习领域的发展日新月异,新的模型和评估方法不断涌现。因此,我们需要保持对新技术的学习和关注,不断优化和改进我们的模型选择与评估策略。
|
设计模式 uml
在电脑主机(MainFrame)中只需要按下主机的开机按钮(on()),即可调用其它硬件设备和软件的启动方法,如内存(Memory)的自检(check())、CPU的运行(run())、硬盘(Hard
该博客文章通过一个电脑主机启动的示例代码,展示了外观模式(Facade Pattern)的设计模式,其中主机(MainFrame)类通过调用内部硬件组件(如内存、CPU、硬盘)和操作系统的启动方法来实现开机流程,同时讨论了外观模式的优缺点。