复杂recyclerView封装库

YCRefreshView

  • 自定义支持上拉加载更多,下拉刷新,支持自由切换状态【加载中,加载成功,加载失败,没网络等状态】的控件,拓展功能[支持长按拖拽,侧滑删除]可以选择性添加
    。具体使用方法,可以直接参考demo。
  • 轻量级侧滑删除菜单,支持recyclerView,listView,直接嵌套item布局即可使用,整个侧滑菜单思路是:跟随手势将item向左滑动
  • 该库已经用到了实际开发项目中,会持续更新并且修改bug。如果觉得可以,可以star一下,多谢支持!
  • 感谢前辈大神们案例及开源分享精神。
  • 一行代码集成:compile 'org.yczbj:YCRefreshViewLib:2.4'
  • 项目地址:https://github.com/yangchong211/YCRefreshView
  • GitHub地址:https://github.com/yangchong211

目录介绍

  • 1.关于复杂页面封装库介绍
  • 2.关于该开源库的思路
  • 3.如何使用介绍
  • 4.关于该状态切换工具优点分析
  • 5.实现效果
  • 6.版本更新说明
  • 7.参考资料说明

1.关于复杂页面封装库介绍

  • 1.1 支持上拉加载,下拉刷新,可以自定义foot底部布局,支持添加多个自定义header头部布局。
  • 1.2 支持切换不同的状态,比如加载中[目前是ProgressBar,加载成功,加载失败,加载错误等不同布局状态。当然也可以自定义这些状态的布局
  • 1.3 支持复杂界面使用,比如有的页面包含有轮播图,按钮组合,横向滑动,还有复杂list,那么用这个控件就可以搞定。
  • 1.4 已经用于实际开发项目投资界,新芽,沙丘大学中……
  • 1.5 轻量级侧滑删除菜单,直接嵌套item布局即可使用,使用十分简单。
  • 1.6 支持插入或者删除某条数据,支持CoordinatorLayout炫酷的效果
  • 1.7 支持粘贴头部的需求效果
  • 1.8 RecyclerView实现条目Item拖拽排序与滑动删除
  • 1.9 更多内容可以直接看案例代码

2.关于该开源库的思路

  • 2.0 参考并借鉴了大量的优秀开源库,由于后期业务需求发生变化,因此做了一些功能的延伸与定制。继续完善并修改库bug!!!已经用于实际开发中。
  • 2.1 先来看看布局,实际上只是在recyclerView基础上做了大量拓展……
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ptr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--RecyclerView控件,支持添加头部和底部view-->
        <android.support.v7.widget.RecyclerView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical|horizontal"
            android:clickable="true"
            android:focusable="true" />

        <!--加载数据为空时的布局-->
        <FrameLayout
            android:id="@+id/empty"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusable="true"/>

        <!--正在加载数据中的布局-->
        <FrameLayout
            android:id="@+id/progress"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusable="true"/>

        <!--加载错误时的布局:网络错误或者请求数据错误-->
        <FrameLayout
            android:id="@+id/error"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusable="true"/>

    </FrameLayout>

</android.support.v4.widget.SwipeRefreshLayout>

3.如何使用介绍

  • 3.1 首先在集成:compile 'org.yczbj:YCRefreshViewLib:2.4'
  • 3.2 在布局中:
  <org.yczbj.ycrefreshviewlib.YCRefreshView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_progress="@layout/view_custom_loading_data"
        app:layout_empty="@layout/view_custom_empty_data"
        app:layout_error="@layout/view_custom_data_error"/>
  • 3.3 在代码中
recyclerView.setLayoutManager(new FullyGridLayoutManager(activity, 3));
        adapter = new DouBookAdapter(activity);
        recyclerView.setAdapter(adapter);
        //加载更多
        adapter.setMore(R.layout.view_recycle_more, new RecyclerArrayAdapter.OnMoreListener() {
            @Override
            public void onMoreShow() {
                if (NetworkUtils.isConnected()) {
                    if (adapter.getAllData().size() > 0) {
                        getTopMovieData(mType, adapter.getAllData().size(), adapter.getAllData().size() + 21);
                    } else {
                        adapter.pauseMore();
                    }
                } else {
                    adapter.pauseMore();
                    Toast.makeText(activity, "网络不可用", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onMoreClick() {

            }
        });

        //设置没有数据
        adapter.setNoMore(R.layout.view_recycle_no_more, new RecyclerArrayAdapter.OnNoMoreListener() {
            @Override
            public void onNoMoreShow() {
                if (NetworkUtils.isConnected()) {
                    adapter.resumeMore();
                } else {
                    Toast.makeText(activity, "网络不可用", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onNoMoreClick() {
                if (NetworkUtils.isConnected()) {
                    adapter.resumeMore();
                } else {
                    Toast.makeText(activity, "网络不可用", Toast.LENGTH_SHORT).show();
                }
            }
        });

        //设置错误
        adapter.setError(R.layout.view_recycle_error, new RecyclerArrayAdapter.OnErrorListener() {
            @Override
            public void onErrorShow() {
                adapter.resumeMore();
            }

            @Override
            public void onErrorClick() {
                adapter.resumeMore();
            }
        });

        //刷新
        recyclerView.setRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (NetworkUtils.isConnected()) {
                    getTopMovieData(mType , 0 , 30);
                } else {
                    recyclerView.setRefreshing(false);
                    Toast.makeText(activity, "网络不可用", Toast.LENGTH_SHORT).show();
                }
            }
        });
  • 3.4 如何使用侧滑菜单删除功能呢?
  • 3.4.1 在布局文件中
<?xml version="1.0" encoding="utf-8"?>
<org.yczbj.ycrefreshviewlib.swipeMenu.YCSwipeMenu
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_height="wrap_content"
    android:layout_width="match_parent">

    <!--item内容-->
    <RelativeLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="72dp"
        android:gravity="center_vertical"
        android:foreground="?android:attr/selectableItemBackground"
        android:background="@android:color/white">
    </RelativeLayout>


    <!-- 侧滑菜单 -->
    <Button
        android:id="@+id/btn_del"
        android:layout_width="70dp"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:text="删除"
        android:textColor="@android:color/white"/>
    <Button
        android:id="@+id/btn_top"
        android:layout_width="70dp"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        android:text="置顶"
        android:textColor="@android:color/white"/>

</org.yczbj.ycrefreshviewlib.swipeMenu.YCSwipeMenu>
  • 3.4.2 在代码中设置
  • 在adapter中定义接口
   private OnSwipeMenuListener listener;
    public void setOnSwipeMenuListener(OnSwipeMenuListener listener) {
        this.listener = listener;
    }
  • 在adapter设置点击事件
View.OnClickListener clickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_del:
                if (null != listener) {
                    listener.toDelete(getAdapterPosition());
                }
                break;
            case R.id.btn_top:
                if (null != listener) {
                    listener.toTop(getAdapterPosition());
                }
                break;
        }
    }
};
btn_del.setOnClickListener(clickListener);
btn_top.setOnClickListener(clickListener);
  • 处理置顶或者删除的功能
adapter.setOnSwipeMenuListener(new OnSwipeMenuListener() {
    //删除功能
    @Override
    public void toDelete(int position) {
        adapter.getAllData().remove(position);
        adapter.notifyItemRemoved(position);//推荐用这个
    }

    //置顶功能
    @Override
    public void toTop(int position) {
        //先移除那个位置的数据,然后将其添加到索引为0的位置,然后刷新数据
        if (position > 0 && adapter.getAllData().size()>position) {
            Person person = adapter.getAllData().get(position);
            adapter.getAllData().remove(person);
            adapter.notifyItemInserted(0);
            adapter.getAllData().add(0, person);
            adapter.notifyItemRemoved(position + 1);
            if (linearLayoutManager.findFirstVisibleItemPosition() == 0) {
                recyclerView.scrollToPosition(0);
            }
        }
    }
});
  • 处理长按拖拽,滑动删除的功能。轻量级,自由选择是否实现。
mCallback = new DefaultItemTouchHelpCallback(new DefaultItemTouchHelpCallback.OnItemTouchCallbackListener() {
    @Override
    public void onSwiped(int adapterPosition) {
        // 滑动删除的时候,从数据库、数据源移除,并刷新UI
        if (personList != null) {
            personList.remove(adapterPosition);
            adapter.notifyItemRemoved(adapterPosition);
        }
    }

    @Override
    public boolean onMove(int srcPosition, int targetPosition) {
        if (personList != null) {
            // 更换数据库中的数据Item的位置
            boolean isPlus = srcPosition < targetPosition;
            // 更换数据源中的数据Item的位置
            Collections.swap(personList, srcPosition, targetPosition);
            // 更新UI中的Item的位置,主要是给用户看到交互效果
            adapter.notifyItemMoved(srcPosition, targetPosition);
            return true;
        }
        return false;
    }
});
mCallback.setDragEnable(true);
mCallback.setSwipeEnable(true);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);

4.关于该状态切换工具优点分析

  • 4.1 不仅可以实现上拉加载,下拉刷新。还可以根据获取数据来切换页面的状态,可以自定义状态页面,如下所示:
//设置加载中
recyclerView.showProgress();

//设置有数据展示
recyclerView.showRecycler();

//设置为空
recyclerView.setEmptyView(R.layout.view_custom_empty_data);
recyclerView.showEmpty();

//设置错误
recyclerView.setErrorView(R.layout.view_custom_data_error);
recyclerView.showError();
LinearLayout ll_error_view = (LinearLayout) recyclerView.findViewById(R.id.ll_error_view);
ll_error_view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

    }
});

//设置网络错误
recyclerView.setErrorView(R.layout.view_custom_network_error);
recyclerView.showError();
LinearLayout ll_set_network = (LinearLayout) recyclerView.findViewById(R.id.ll_set_network);
ll_set_network.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        if(NetworkUtils.isConnected()){
            initData();
        }else {
            Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
            startActivity(intent);
        }
    }
});

5.实现效果

5.1 使用过YCRefreshView库的案例代码

5.2 图片展示效果

  • demo效果图展示


    image

    image

    image

    image

    image

    image
  • 案例图展示


    image

    image

    image

6.版本更新说明

  • v1.0 更新于2017年4月22日
  • v1.1 更新于2017年8月9日
  • v1.…… 更新于2018年1月5日
  • v2.2 更新于2018年1月17日
  • v2.3 更新于2018年2月9日
  • v2.4 更新于2018年3月19日

7.参考资料说明

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,465评论 25 707
  • 2月26号既是一个365天里平凡得不过的一个日子,又是一个独一无二的日子,是新学期的第二天,是四六级成绩查询的日...
    何悠哈阅读 210评论 2 2
  • 朋友的儿子读高二,有天晚上打电话给女同学,被女孩的母亲接到。正为女儿成绩下降而苦恼的母亲一听是个男生,就非常警惕,...
    梓毓爸阅读 256评论 -2 1