打造可上拉下拉收起展开+悬浮头部的RecyclerView

由于项目需求一个可上拉下拉收起展开+悬浮头部的RecyclerView,然后在开源社区也没有找到功能这么多的现成的控件。所以只能自己造轮子,总的来说实现起来难度不算太大。能力一般水平有限,写篇博客记录一下方便日后查看改进,当然如果能有幸帮助到各位小伙伴当然最好。

项目简介:

这是一个可以帮助你实现伴有悬浮头部、折叠展开且带有上拉下拉功能的列表的帮助类。你只需要提供原生的RecyclerView,
以及SwipeRefreshLayout就能达到你想要的效果。 如果不进行任何设置,它会是一个ExpandableListView效果的列表。

接下来看下效果图吧

悬浮头效果

这里写图片描述


展开收起效果

这里写图片描述


下拉刷新演示

这里写图片描述


使用方法:


下载类库,Android studio下直接导入,添加依赖即可使用

1.

这里写图片描述

2.

这里写图片描述

3.

这里写图片描述

4.

这里写图片描述


核心类与方法:


//核心功能类,初始化实例时要注意初始化泛型。(T:二级列表的数据类型,K:一级列表的数据类型)
class StickyExpandableRefreshRecyclerViewHelper<T extends Section,K extends Items>

//传入StickyExpandableRefreshRecyclerViewHelper的RecyclerView所使用的适配器要继承此类
abstract class StickyCommonAdapter<T extends CommonViewHolder> extends RecyclerView.Adapter<T>

//创建StickyCommonAdapter实现类所需要的泛型参数。传入适配器的ViewHolder要继承此类
class CommonViewHolder extends RecyclerView.ViewHolder

//二级列表item项的数据一定要实现此接口
interface Items

//一级列表group项的数据一定要继承于该抽象类
abstract class Section

//*****************方法*******************


//设置adapter
setAdapter(RecyclerView.Adapter adapter);

//添加上拉监听
setOnLoadMoreListener(StickyExpandableRefreshRecyclerViewHelper.OnLoadMoreListener listener);

//添加下拉监听
setOnRefreshListener(SwipeRefreshLayout swipeRefreshLayout,StickyExpandableRefreshRecyclerViewHelper.OnRefreshListener listener);

//添加悬浮头
setStickyBar(ViewGroup stickyBar);

//添加数据(添加到原有list尾部)
addSection(section, arrayList);

//将加载的数据添加到原有list头部
addSectionOnHead(section, arrayList);

//刷新列表
notifyDataSetChanged();

//刷新列表并定位到指定位置并伴随滚动动画效果
notifyDataSetChangedWithScroll(int position);

//刷新列表并立即定位到指定位置
notifyDataSetChangedToPosition(int position);

//上拉加载无更多数据
setNotAnyMoreData();

//下拉刷新结束
setRefreshEnd();

使用实例:


首先是在布局文件中

<?xml version="1.0" encoding="utf-8"?>
<!--下拉刷新是借助SwipeRefreshLayout实现的,根部局要设置为SwipeRefreshLayout-->
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fafafa">
 <!--如果要添加悬浮头要注意把RecyclerView与StickyBar平级摆放-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/recycler_view"/>
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ffffffff"
            android:id="@+id/sticky_bar"
            >
            <android.support.v7.widget.CardView
                app:cardBackgroundColor="#f3f3f3"
                app:cardElevation="2dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="30dp"
                    >
                    <View
                        android:layout_width="4dp"
                        android:layout_height="20dp"
                        android:layout_alignParentLeft="true"
                        android:background="#000"
                        android:layout_centerVertical="true"
                        />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:gravity="center"
                        android:text="Pro9"
                        android:textSize="13sp"
                        android:textColor="#949494"
                        android:id="@+id/text_section"
                        />

                </RelativeLayout>
            </android.support.v7.widget.CardView>
        </RelativeLayout>

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

接下来是Activity


package......

public class MainActivity extends AppCompatActivity  {
    //需要传入RecyclerView
    RecyclerView mRecyclerView;
    //StickyBar布局
    RelativeLayout mStickyBar;
    //帮助类对象 这里要注意传递泛型参数LiveSection为继承Section的实体类,Item为实现了Items接口的实体类
            StickyExpandableRefreshRecyclerViewHelper<LiveSection,Item> stickyExpandableRefreshRecyclerViewHelper;
    TestAdapter adapter;
    private SwipeRefreshLayout swipeRefreshLayout;

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

        mStickyBar = (RelativeLayout) findViewById(R.id.sticky_bar);
              mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        //random data
        ArrayList<Item> arrayList = new ArrayList<>();
        arrayList.add(new Item("iPhone", 100));
        arrayList.add(new Item("iPad", 200));
        LiveSection section = new LiveSection("ProV");
        stickyExpandableRefreshRecyclerViewHelper = new StickyExpandableRefreshRecyclerViewHelper(this,
                mRecyclerView);
         //创建adapter 参数1为帮助类对象 参数2为二级列表的xml布局文件 参数3为一级列表的xml布局文件
        adapter=new TestAdapter(     stickyExpandableRefreshRecyclerViewHelper,R.layout.item_livescore_foot,R.layout.layout_section);
//设置适配器    
 stickyExpandableRefreshRecyclerViewHelper.
        setAdapter(adapter);
       //设置数据stickyExpandableRefreshRecyclerViewHelper.addSection(section, arrayList);
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);

        //下拉刷新监听
        stickyExpandableRefreshRecyclerViewHelper.
        setOnRefreshListener(swipeRefreshLayout, new OnRefreshListener() {
            @Override
            public void onRefresh() {
                stickyExpandableRefreshRecyclerViewHelper.setRefreshEnd();
                List<Item> arrayList = new ArrayList<>();
                arrayList.add(new Item("Mac", 3));
                arrayList.add(new Item("Mac", 3));
                arrayList.add(new Item("Mac", 3));

                LiveSection section = new LiveSection("OnRefresh flying~");

addSectionOnHead(section, arrayList);

    //刷新列表并定位到原数据的位置     stickyExpandableRefreshRecyclerViewHelper
        .notifyDataSetChangedToPosition(arrayList.size()+1);
            }
        });
        //设置上拉加载监听
        stickyExpandableRefreshRecyclerViewHelper
        .setOnLoadMoreListener(new StickyExpandableRefreshRecyclerViewHelper.OnLoadMoreListener() {
            @Override
            public void onLoadMore(){
                ArrayList<Item> arrayList = new ArrayList<>();
                arrayList = new ArrayList<>();
                arrayList.add(new Item("Samsung", 2));
                arrayList.add(new Item("Samsung", 2));
                arrayList.add(new Item("Samsung", 2));

                LiveSection section = new LiveSection("OnLoadMore fighting!");
                stickyExpandableRefreshRecyclerViewHelper.addSection(section, arrayList);
                stickyExpandableRefreshRecyclerViewHelper.notifyDataSetChanged();
//   设置没有更多数据,此时上拉监听不会在触发             stickyExpandableRefreshRecyclerViewHelper.setNotAnyMoreData();
            }
        });

        //设置悬浮头此处设计灵感源自万能适配器stickyExpandableRefreshRecyclerViewHelper.
        setStickyBar(mStickyBar, new StickyBarHolder() {
            TextView textView;
            @Override
            public void getView(StickyBarViewHolder holder) {
                textView=holder.getView(R.id.text_section);
            }

            @Override
            public void updateStickyBar(Object section) {
                LiveSection msection = (LiveSection) section;
                textView.setText(msection.getName());

            }
        });
        stickyExpandableRefreshRecyclerViewHelper.notifyDataSetChanged();
    }


}




接着是Adapter的相关代码

package .......
/**
 * Author: by Jiangsir
 * <p>
 * Date: at 2017/1/3.
 * <p>
 * Description: adapter示例
 */
public class TextAdapter extends extends StickyCommonAdapter<TextAdapter.ViewHolder> {


    //data array
    private ArrayList<Object> mDataArrayList;

    //context
    private  Context mContext;


    //view type
    private static int SubSectionType;
    private static int SubItemType;

    public TextAdapte(StickyExpandableRefreshRecyclerViewHelper stickyExpandableRefreshRecyclerViewHelper, int subItemType, int subSectionType) {
        super(stickyExpandableRefreshRecyclerViewHelper, subItemType, subSectionType);
        this.SubSectionType = subSectionType;
        this.SubItemType = subItemType;

        mContext = stickyExpandableRefreshRecyclerViewHelper.mContext;
        mDataArrayList = stickyExpandableRefreshRecyclerViewHelper.mDataArrayList;
    }


//实现onCreateViewHolder方法,返回ViewHolder实例
   @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType, Object obj) {
        return new ViewHolder(LayoutInflater.from(mContext).inflate(viewType, parent, false), viewType);
    }

    @Override
    public void onBindItemView(final ViewHolder holder, int position) {
        //此方法中为二级item设置数据
        holder.tv_mid.setText(mDataArrayList.get(position));

    }

    @Override
    public void onBindSectionView(ViewHolder holder, int position) {
     此方法为一级列表设置数据

    }

    protected static class ViewHolder extends CommonViewHolder {

     //for section
        TextView text_section;
        //for item
        TextView tv_league_name;
        TextView tv_time;
        TextView tv_mid;
       public ViewHolder(View itemView, int viewType) {
            super(itemView, viewType);
            if (viewType == SubItemType) {
                tv_league_name = (TextView)view.findViewById(R.id.tv_league_name);
                tv_mid = (TextView)view.findViewById(R.id.tv_mid);
                tv_time = (TextView)view.findViewById(R.id.tv_time);


            }  else if (viewType == SubSectionType) {
                text_section = (TextView) view.findViewById(R.id.text_section);

            }
        }
}

最后

最新库就不上传了,有需要的朋友留下联系方式,我发给你们吧。

[转载请注明出处:http://blog.csdn.net/qq_23347751/article/details/54177401 ]

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值