Recylerview上拉加载与下拉刷新(一)

这篇博客记载了,recylerview上拉加载下拉刷新当recylerview是GridLayout时设置显示footView[提示正在加载中的布局]占满一行和监听recylerview滑到最后一项就加载数据

在用Recylerview展示数据时,不可能一次性获取全部数据,而是用户需要多少就从网络获取多少,因此在RecylerView里经常时滑到最后一条数据时就去加载更多的数据。

如下图:

首先讲 下拉刷新:

在RecylerView外层套个SwipeRefreshLayout就行,然后给SwipeRefreshLayout加上侦听:

 

代码加上侦听控制刷新时的显示:

 

mRefreshLayout = view.findViewById(R.id.swipeRefresh); 
      //设置显示刷新时的颜色                                                       mRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,
                android.R.color.holo_orange_light, android.R.color.holo_green_light);
        mRefreshLayout.setOnRefreshListener(this);  //添加监听,重写onFresh()方法   //设置显示刷新时的颜色                                                       mRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,
                android.R.color.holo_orange_light, android.R.color.holo_green_light);
        mRefreshLayout.setOnRefreshListener(this);  //添加监听,重写onFresh()方法

可以看到,当下拉时,onRefresh会触发,然后我通过mRefreahLayout.setRefreshing(true)控制使它显示刷新

之后在onPostExecute里面,即网络请求数据完成后,通过setRefreshing(false)来停止刷新,并notifyDataChanged().

 

上拉加载

首先我们定义两个布局,一个是正常的盛装item布局,一个是提示在加载的布局

正常item布局

 

 

提示在加载的布局文件:

 

然后创建两个ViewHolder:

 

重写getItemViewType,

如果滑到最后一项,就返回 FootView(定义的一个int变量,值为 1),否则返回正常的NormalView(值为  0)。

 

 

在onCreateViewHolder里面根据viewType来判断到底加载哪个layout:

 

然后在onBindViewHolder里面根据holder的类型,来显示不同的内容【显示正常item内容或是 加载提示内容】

 

因为你最后显示到最后一条多显示的一个footView,所以在getItemCount里面要多+1;

.

这样就能够实现,当显示item时,根据itemType返回的type的不同,进而返回的ViewHolder不同,然后在onBindViewHolder里面根据不同的holder显示不同的内容,因此在最后一项,会显示加载的布局,否则显示正常的item布局啦.

 

 

 

然后因为我是GridLayoutManager,所以在显示加载中的布局时要设置它占3列,其余的就让它占一列就好

根据position是否是最后一个来决定占的列数。

 

 

在recylerview添加滑动侦听,如果当前是最后一项就加载更多数据:

完整代码:

public class Fragment_Movie_Types extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
    private static String TAG = "Fragment_Movie_Types";
    private RecyclerView mRecyclerView;
    private SwipeRefreshLayout mRefreshLayout;
    private String tag;
    private int lastItemPosition;  //最后一个item的位置
    private int mCurrentStart = 0;  //请求电影的起始位置
    private int NormalView = 0;  //正常item
    private int FootView = 1;    //加载view
    private List<MovieInfo> mMovieInfos = new ArrayList<>();
    private TypeAdapter adapter;
    public int mMovieType;  //电影种类

    /*1. 爱情篇
     *2. 喜剧
     *3. 动画
     *4. 科幻
     *5. 动作
     *6. 经典
* */
    public Fragment newInstance(int movieType) {
        Fragment_Movie_Types fragment = new Fragment_Movie_Types();
        fragment.mMovieType = movieType;
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        adapter = new TypeAdapter();
        Log.i(TAG, "mMovieType====>" + mMovieType + "onCreate");
        Log.i(TAG, "mMovieType===> " + this.mMovieType);
        switch (this.mMovieType) {
            case 1:
                tag = "爱情";
                break;
            case 2:
                tag = "喜剧";
                break;
            case 3:
                tag = "动画";
                break;
            case 4:
                tag = "科幻";
                break;
            case 5:
                tag = "动作";
                break;
            case 6:
                tag = "经典";
                break;
        }
        Log.i(TAG, "tag==> " + tag);
        AsyncTask<String, Integer, List<MovieInfo>> task = new AsyncTask<String, Integer, List<MovieInfo>>() {
            @Override
            protected List<MovieInfo> doInBackground(String... strings) {
                return new FetchMovies().getMoviesByTag(tag, mCurrentStart);
            }

            @Override
            protected void onPostExecute(List<MovieInfo> movieInfos) {
                super.onPostExecute(movieInfos);
                mMovieInfos = movieInfos;
                adapter.notifyDataSetChanged();
                Log.i(TAG, "网络请求结束");
            }
        };
        task.execute();
        setRetainInstance(true);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_movie_types, container, false);
        mRecyclerView = view.findViewById(R.id.recyler_view);
        mRefreshLayout = view.findViewById(R.id.swipeRefresh);
        mRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,
                android.R.color.holo_orange_light, android.R.color.holo_green_light);
        mRefreshLayout.setOnRefreshListener(this);
        final GridLayoutManager lm = new GridLayoutManager(getActivity(), 3);
        lm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            //如果是最后一个item,则设置占据3列,否则占据1列
            @Override
            public int getSpanSize(int position) {
                boolean isFooter = position == adapter.getItemCount() - 1;
                return isFooter ? 3 : 1;
            }
        });
        mRecyclerView.setLayoutManager(lm);
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
               // Log.d(TAG, "current state==> " + newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    Log.d(TAG, "SCROLL_STATE_IDEL");
                    if (lastItemPosition + 1 == lm.getItemCount()) {
                        //Log.d(TAG, "我在加载更多");
                        mCurrentStart++;
                        loadMore();
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //Log.d(TAG, "onScrolled");
                lastItemPosition = lm.findLastVisibleItemPosition();
            }
        });
        return view;
    }

    @Override
    public void onRefresh() {
        mRefreshLayout.setRefreshing(true);
        AsyncTask<String, Integer, List<MovieInfo>> task = new AsyncTask<String, Integer, List<MovieInfo>>() {
            @Override
            protected List<MovieInfo> doInBackground(String... strings) {
                return new FetchMovies().getMoviesByTag(tag, 0);
            }

            @Override
            protected void onPostExecute(List<MovieInfo> movieInfos) {
                super.onPostExecute(movieInfos);
                mMovieInfos.clear();
                mMovieInfos = movieInfos;
                adapter.notifyDataSetChanged();
                mRefreshLayout.setRefreshing(false);
                Log.i(TAG, "网络请求结束");
            }
        };
        task.execute();
    }


    public class TypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            if (viewType == NormalView) {
                View v = inflater.inflate(R.layout.movie_item, parent, false);
                return new TypeHolder(v);
            } else {
                View v = inflater.inflate(R.layout.footview, parent, false);
                return new FootHolder(v);
            }
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            if (holder instanceof TypeHolder) {
                ((TypeHolder) holder).movieName.setText(mMovieInfos.get(position).getName());
                Picasso.with(getActivity()).load(mMovieInfos.get(position).getImgUrl()).into(((TypeHolder) holder).movieImg);
            } else {
                ((FootHolder)holder).mTip.setText("正在努力加载中...");
            }
        }

        @Override
        public int getItemCount() {
            if (mMovieInfos != null) {
                return mMovieInfos.size() + 1;
            } else {
                return 0;
            }
        }

        @Override
        public int getItemViewType(int position) {
            if (position + 1 == getItemCount()) {
                return FootView;
            } else {
                return NormalView;
            }
        }

        class TypeHolder extends ViewHolder {    //普通电影的holder
            public ImageView movieImg;
            public LinearLayout starContainer;
            public TextView movieName;

            public TypeHolder(View itemView) {
                super(itemView);
                movieImg = itemView.findViewById(R.id.movie_img);
                movieName = itemView.findViewById(R.id.movie_name);
                starContainer = itemView.findViewById(R.id.star_container);
            }
        }

        class FootHolder extends ViewHolder {  //提示加载的holder
            public TextView mTip;

            public FootHolder(View itemView) {
                super(itemView);
                mTip = itemView.findViewById(R.id.tv_tip);
            }
        }

    }

    private void loadMore() {
        final AsyncTask<String, Integer, List<MovieInfo>> task = new AsyncTask<String, Integer, List<MovieInfo>>() {
            @Override
            protected List<MovieInfo> doInBackground(String[] objects) {
                return new FetchMovies().getMoviesByTag(tag, mCurrentStart*20);
            }

            @Override
            protected void onPostExecute(List<MovieInfo> o) {
                super.onPostExecute(o);
                mMovieInfos.addAll(o);
                adapter.notifyDataSetChanged();
            }
        };
        task.execute();
    }
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值