Android开发---RecycleView的上拉加载和下拉刷新

最近在做一个新的app,有一个分页加载的功能需要用到上拉加载。自己搜了很多关于RecycleView上拉加载的资料,代码都写了很多,引用这些第三方,徒增apk的体积。所以情急之下,自己写了一个上拉加载(该方案也实现了下拉刷新)。废话不多说,先看效果图:

                                                                      

      是不是有点上拉加载的意思?

      思路:其实很简单,我在当前的Fragment里做了2个标签,一个是isShowBottom用来判断是否显示“已下拉到底部”,一个是isLoadBottom用来判断是否进行上拉加载。然后在适配器里做了个布局的判断加载,来控制进度条和文本的显隐,就是如果有数据需要上拉加载就显示进度条,否则显示文本“已下拉到底部”。代码如下:

    1. Fragment相关代码:

public class VisitFragment extends BaseFragment {

    private Gson gson;
    private VisitAdapter visitAdapter;
    private List<jsonVisit> lists = new ArrayList<jsonVisit>();
    private List<jsonVisit> list = new ArrayList<jsonVisit>();
    private int maxCount = Constants.MAX_COUNT;
    private int offset = Constants.OFFSET;
    private int currentIndex = 0;
    private boolean isFirst = true;
    public static boolean isLoadBottom = false;
    public static boolean isShowBottom = false;

    @ViewInject(R.id.rv_layout_recyclerView_srl)
    private RecyclerView recyclerView;
    @ViewInject(R.id.srl_layout_recyclerView)
    private SwipeRefreshLayout srl;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        gson = gson == null ? new Gson() : gson;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View visitFragment = inflater.inflate(R.layout.fragment_visit, container, false);
        return visitFragment;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        x.view().inject(this, view);
        setViews();
        setListeners();
    }

    private void setViews() {
                srl.setColorSchemeColors(x.app().getResources().getColor(R.color.color_jcdecaux));
        srl.setRefreshing(true);
        LinearLayoutManager manager = new LinearLayoutManager(getActivity());
//        recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
        recyclerView.setLayoutManager(manager);
        setServerData();
    }


    private void setServerData() {
        if (OtherAction.hasNet()) {
            setData();
        } else {
            llRefresh.setVisibility(View.VISIBLE);
        }
    }

    private void setData() {
        String url = ServerConfig.getFullURL(x.app().getString(R.string.url_visit));
        RequestParams params = OtherAction.createParams(url);
        params.addQueryStringParameter("offset", String.valueOf(offset));
        params.addQueryStringParameter("maxCount", String.valueOf(maxCount));
        if (getArguments() == null) return;
        try {
            x.http().get(params, new Callback.CommonCallback<String>() {
                @Override
                public void onSuccess(String result) {
                    jsonBase jsonBase = gson.fromJson(result, jsonBase.class);
                    srl.setRefreshing(false);
                    list = gson.fromJson(gson.toJson(jsonBase.getList()), new TypeToken<List<jsonVisit>>() {
                    }.getType());
                    if (list.size() != 0) {
                        isShowBottom = true;
                        lists.addAll(list);
                        if (lists.size() <= 5) {//页面少于5条数据显示 加载到底部
                            isLoadBottom = true;
                        } else {
                            isLoadBottom = false;
                        }
                        if (list.size() < maxCount) {
                            currentIndex = list.size();
                        } else {
                            currentIndex = maxCount;
                        }
                        offset += currentIndex;
                    } else {
                        if (lists.size() == 0) {
                            isShowBottom = false;
                        } else {
                            isShowBottom = true;
                            isLoadBottom = true;
                        }
                    }
                    if (isFirst) {// 首次加载初始化适配器,否则刷新数据
                        visitAdapter = new VisitAdapter(list);
                        recyclerView.setAdapter(visitAdapter);
                        isFirst = false;
                    } else {
                        visitAdapter.notifyDataSetChanged();
                    }
                    setRvListener();
                }

                @Override
                public void onError(Throwable ex, boolean isOnCallback) {
                }

                @Override
                public void onCancelled(CancelledException cex) {

                }

                @Override
                public void onFinished() {

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setRvListener() {
        if (visitAdapter != null) {
            visitAdapter.setOnItemClickListener(new VisitAdapter.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                   
                }
            });
        }
    }

    private void setListeners() {
        srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (OtherAction.hasNet()) {
                    refreshData();
                } else {
                    srl.setRefreshing(false);
                }
            }
        });


        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
                    int lastPos = manager.findLastVisibleItemPosition();
                    if (lastPos == manager.getItemCount() - 1) {
                        if (list.size() != 0) {
                            offset += currentIndex;
                            setData();
                        }
                    }
                }
            }
        });

    }

    /**
     * 下拉更新数据
     */
    private void refreshData() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(Constants.SLEEPTIME_REFRESH);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                setData();
            }
        }).start();
    }

}

      2. 适配器相关代码:

/**
 * Create by ah , date on 2019/8/2
 * 待拜访
 */
public class VisitAdapter extends RecyclerView.Adapter<VisitAdapter.ViewHolder> implements View.OnClickListener {

    private OnItemClickListener itemClick = null;
    private List<jsonVisit> list = new ArrayList<jsonVisit>();
    private static final int NORMAL_VIEW = 1;
    private static final int FOOT_VIEW = 2;

    public VisitAdapter(List<jsonVisit> list) {
        this.list = list;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        @ViewInject(R.id.tv_item_visit_title)
        private TextView tvTitle;
        @ViewInject(R.id.tv_item_visit_brand)
        private TextView tvBrand;
        @ViewInject(R.id.tv_item_visit_address)
        private TextView tvAddress;
        @ViewInject(R.id.tv_item_visit_title1)
        private TextView tvTitle1;
        @ViewInject(R.id.tv_item_visit_date1)
        private TextView tvDate1;
        @ViewInject(R.id.tv_item_visit_content1)
        private TextView tvContent1;
        @ViewInject(R.id.tv_item_visit_detail1)
        private TextView tvDetail1;
        @ViewInject(R.id.tv_item_visit_title2)
        private TextView tvTitle2;
        @ViewInject(R.id.tv_item_visit_date2)
        private TextView tvDate2;
        @ViewInject(R.id.tv_item_visit_content2)
        private TextView tvContent2;
        @ViewInject(R.id.tv_item_visit_detail2)
        private TextView tvDetail2;
        @ViewInject(R.id.ll_item_visit_content2)
        private LinearLayout llContent2;
        private PercentFrameLayout view;
        private LinearLayout footView;
        private TextView tvBottom;
        private ProgressBar pb;

        public ViewHolder(View itemView, int viewType) {
            super(itemView);
            if (viewType == NORMAL_VIEW) {
                x.view().inject(this, itemView);
            } else if (viewType == FOOT_VIEW) {
                footView = (LinearLayout) itemView;
                tvBottom = footView.findViewById(R.id.tv_layout_recyclerview_bottom);
                pb = footView.findViewById(R.id.pb_layout_recyclerview_bottom);
            }
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View visitView;
        visitView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_visit, parent, false);
        if (viewType == FOOT_VIEW)
            visitView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_recyclerview_bottom, parent, false);
        ViewHolder holder = new ViewHolder(visitView, viewType);
        visitView.setOnClickListener(this);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (getItemViewType(position) == NORMAL_VIEW) {
            jsonVisit jsonVisit = list.get(position);
            holder.tvTitle.setText(jsonVisit.getUserName());
            holder.tvBrand.setText(jsonVisit.getCompanyName());
            holder.tvAddress.setText(jsonVisit.getAddress());
            holder.tvTitle1.setText(jsonVisit.getVisitPlanTitle());
            holder.tvDate1.setText(jsonVisit.getVisitPlanDate());
            holder.tvContent1.setText(jsonVisit.getVisitPlanPurpose() + Constants.LINE + jsonVisit.getVisitPlanMethod());
            holder.tvDetail1.setText(jsonVisit.getVisitPlanSummary());
            if (jsonVisit.getVisitPurpose() != null) {
                holder.llContent2.setVisibility(View.VISIBLE);
                holder.tvTitle2.setText(jsonVisit.getVisitTitle());
                holder.tvDate2.setText(jsonVisit.getVisitDate());
                holder.tvContent2.setText(jsonVisit.getVisitPurpose() + Constants.LINE + jsonVisit.getVisitMethod());
                holder.tvDetail2.setText(jsonVisit.getVisitSummary());
            } else {
                holder.llContent2.setVisibility(View.GONE);
            }
            holder.itemView.setTag(position);
        } else {
            if (VisitFragment.isShowBottom) {
                holder.footView.setVisibility(View.VISIBLE);
                if (VisitFragment.isLoadBottom) {
                    holder.tvBottom.setVisibility(View.VISIBLE);
                    holder.pb.setVisibility(View.GONE);
                } else {
                    holder.tvBottom.setVisibility(View.GONE);
                    holder.pb.setVisibility(View.VISIBLE);
                }
            }else {
                holder.footView.setVisibility(View.GONE);
            }
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (position == getItemCount() - 1) {
            return FOOT_VIEW;
        }
        return NORMAL_VIEW;
    }

    @Override
    public int getItemCount() {
        return list.size() + 1;
    }

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }


    @Override
    public void onClick(View v) {
        if (itemClick != null) {
            if (v.getTag() == null) {
                return;
            } else
                itemClick.onItemClick(v, (int) v.getTag());
        }
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.itemClick = listener;
    }

}

    3. item_visit.xml的布局里的style我就不做公布了,其实这个item都是可以换成自己的item的。

<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/style_MW"
    android:background="@color/color_white"
    android:orientation="vertical">

    <!--<android.support.v7.widget.CardView-->
    <!--style="@style/style_card_home"-->
    <!--app:cardCornerRadius="@dimen/size_5">-->

    <RelativeLayout
        style="@style/style_MW"
        android:background="@color/color_white"
        android:padding="@dimen/size_10">

        <ImageView
            android:id="@+id/iv_item_visit_head"
            android:layout_width="@dimen/size_40"
            android:layout_height="@dimen/size_40"
            android:src="@mipmap/ic_launcher_round" />

        <LinearLayout
            style="@style/style_MW"
            android:layout_marginStart="@dimen/size_20"
            android:layout_toRightOf="@id/iv_item_visit_head"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_item_visit_title"
                style="@style/style_WW"
                android:textColor="@color/color_jcdecaux"
                android:textSize="@dimen/size_16_text" />

            <LinearLayout
                style="@style/style_MW"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <ImageView
                    android:layout_width="@dimen/size_10"
                    android:layout_height="@dimen/size_10"
                    android:src="@drawable/iv_brand" />

                <TextView
                    android:id="@+id/tv_item_visit_brand"
                    style="@style/style_text_visit"
                    android:layout_marginStart="@dimen/size_5" />
            </LinearLayout>

            <LinearLayout
                style="@style/style_MW"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <ImageView
                    android:layout_width="@dimen/size_12"
                    android:layout_height="@dimen/size_12"
                    android:src="@drawable/iv_position" />

                <TextView
                    android:id="@+id/tv_item_visit_address"
                    style="@style/style_text_visit"
                    android:layout_marginStart="@dimen/size_5" />
            </LinearLayout>

            <LinearLayout
                style="@style/style_MW"
                android:layout_marginTop="@dimen/size_10"
                android:background="@color/color_grey"
                android:orientation="vertical"
                android:padding="@dimen/size_2">

                <RelativeLayout style="@style/style_MW">

                    <TextView
                        android:id="@+id/tv_item_visit_title1"
                        style="@style/style_text_visit" />

                    <TextView
                        android:id="@+id/tv_item_visit_date1"
                        style="@style/style_text_visit"
                        android:layout_alignParentEnd="true" />
                </RelativeLayout>

                <TextView
                    android:id="@+id/tv_item_visit_content1"
                    style="@style/style_text_visit" />

                <TextView
                    android:id="@+id/tv_item_visit_detail1"
                    style="@style/style_text_visit"
                    android:textColor="@color/color_jcdecaux"
                    android:textSize="@dimen/size_12_text" />

            </LinearLayout>

            <View
                style="@style/style_apart_me_match"
                android:background="@color/color_white" />

            <LinearLayout
                android:id="@+id/ll_item_visit_content2"
                style="@style/style_MW"
                android:background="@color/color_grey"
                android:orientation="vertical"
                android:padding="@dimen/size_2">

                <RelativeLayout style="@style/style_MW">

                    <TextView
                        android:id="@+id/tv_item_visit_title2"
                        style="@style/style_text_visit" />

                    <TextView
                        android:id="@+id/tv_item_visit_date2"
                        style="@style/style_text_visit"
                        android:layout_alignParentEnd="true" />
                </RelativeLayout>

                <TextView
                    android:id="@+id/tv_item_visit_content2"
                    style="@style/style_text_visit" />

                <TextView
                    android:id="@+id/tv_item_visit_detail2"
                    style="@style/style_text_visit"
                    android:textColor="@color/color_jcdecaux"
                    android:textSize="@dimen/size_12_text" />

            </LinearLayout>


        </LinearLayout>
    </RelativeLayout>

    <View style="@style/style_line_horizontal" />
    <!--</android.support.v7.widget.CardView>-->
</android.support.percent.PercentFrameLayout>

    4. layout_recyclerview_bottom.xml里的TextView和ProgressBar放到了相对布局里,作为重叠布局来用。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl_layout_recyclerview_bottom"
    style="@style/style_MW"
    android:background="@color/bg_page"
    android:orientation="vertical">

    <RelativeLayout style="@style/style_MW">

        <TextView
            android:id="@+id/tv_layout_recyclerview_bottom"
            style="@style/style_text"
            android:layout_width="match_parent"
            android:layout_height="@dimen/size_40"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:text="@string/text_baseline"
            android:textColor="@color/color_333" />

        <ProgressBar
            android:id="@+id/pb_layout_recyclerview_bottom"
            android:layout_width="match_parent"
            android:layout_height="@dimen/size_30"
            android:layout_alignParentBottom="true"
            android:indeterminateTint="@color/color_jcdecaux"
            android:indeterminateTintMode="src_atop" />
    </RelativeLayout>

    <View style="@style/style_line_horizontal" />

</LinearLayout>

好了,上拉加载和下拉刷新就这么简单得实现了,有木有简单到你?

公司内部代码仅公开部分代码,不做代码共享哦!其实啊,明白了这个思路,你就已经能实现了。

哈哈,加油!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值