RecyclerView+SwipeRefreshLayout两个控件同时使用

RecyclerView+SwipeRefreshLayout


Google给我提供了一个很好的控件来取代listview。今天特意去弄了一下,因为这段时间忙,上次遗留下一个问题还没有解决,这些天是寝食不安啊。所以趁着今天有点空,所以就抽空重新看了下那个问题,终于解决了。(我这里遇到的问题是,RecyclerView数据错乱的问题)


这里喔顺便也把Google提供的自动刷新的控件也讲了,这个控件不难,但是很实用。我们在很多的app里面已经用上这个控件了。所以我们要跟上时代的步伐。


先上效果图:

RecyclerView 



SwipeRefreshLayout




具体的说明已经在代码中进行说明了,请认真查看代码注释



布局文件是这样的:


<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<!--这里用到的是v4包,里面包含了SwipeRefreshLayout,直接引用就OK了-->
<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/refreshLayout"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.kuyu.recycleview.MainActivity"
    tools:showIn="@layout/app_bar_main">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_refreshing"
            android:layout_width="match_parent"
            android:gravity="center"
            android:textColor="#f3d468"
            android:textSize="20sp"
            android:visibility="invisible"
            android:layout_height="wrap_content"
            android:text="正在刷新中,请稍等..." />

        <!--这里用到的是v7包,里面包含了RecyclerView,直接引用就OK了-->
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycleView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/tv_refreshing" />
    </RelativeLayout>

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


 
 
RecycleView:
   适配器
 
 
package com.kuyu.recycleview.adapter;

import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.kuyu.recycleview.R;

import java.util.List;

/**
 * Created by tanksu.yaojt on 16/4/30.
 * <p/>
 * 这里要着重说明一下
 * <p/>
 * 我的问题就是在这里:原先是利用自己生成的ViewHolder 在onBindViewHolder()方法里面进行设置数据
 * 然后的话,那个ViewHolder是一直没有按照正常对应的位置进行显示,就造成错误
 * <p/>
 * 然后解决问题的方法是:我们要继承RecyclerView.Adapter<RecycleViewAdapter.MyViewHolder>
 * 然后把我们自定义的ViewHolder 放到里面去,然后RecyclerView 就会用你传入的类来作为参数进行传递
 * 然后我们可以看到在public void onBindViewHolder(MyViewHolder holder, int position)
 * 回调里面,传的参数就是我们自定义的ViewHolder了。然后我们就可以对回传回来的 holder 进行数据设置了
 * 问题解决。
 */
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyViewHolder> {

    private Activity mActivity;
    private List<String> mList;
    private MyViewHolder myViewHolder;

    /**
     * 构造函数,传入一个数据源
     *
     * @param activity activity
     * @param list     list
     */
    public RecycleViewAdapter(Activity activity, List<String> list) {
        this.mActivity = activity;
        this.mList = list;
    }

    /**
     * 这里是创建一个ViewHolder
     *
     * @param parent   parent
     * @param viewType viewType
     * @return myViewHolder
     */
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mActivity.getLayoutInflater().inflate(R.layout.recycleview_item, parent, false);
        myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    /**
     * 这里进行数据绑定,就是将数据放入到对应的item布局中。
     * 我在这里进行了打印,发现滚动的时候,这里一直会调用
     * 但是onCreateViewHolder 就不再调用了
     * 据我的理解就是onCreateViewHolder在创建好了当前屏幕可以显示的item条数 + 1 之后,
     * 再上下滚动,就是利用回收的view了,所以不用在创建ViewHolder了
     *
     * @param holder   holder
     * @param position position
     */
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        //这是我一开始设置数据的方法,直接调用的是onCreateViewHolder()方法创建好的那个vh
        //事实证明是不可以的,造成数据错乱
//        myViewHolder.tv_itemShow.setText(mList.get(position));
        holder.tv_itemShow.setText(mList.get(position));
    }

    /**
     * 得到数据源的总条数
     *
     * @return size()
     */
    @Override
    public int getItemCount() {
        return mList.size();
    }

    /**
     * 自定义的MyViewHolder 继承自RecyclerView.ViewHolder
     * 记住一定要继承自RecyclerView.ViewHolder
     */
    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tv_itemShow;//这里我只是弄了一个tv用来展示数据

        public MyViewHolder(View view) {
            super(view);
            tv_itemShow = (TextView) view.findViewById(R.id.tv_itemShow);
        }
    }
}

在MainActivity里头,我只截取重要的代码块,其他的都不是最重要的
 产生数据源 
List<String> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add("------------>>" + i);
        }


找到句炳和设置适配器
recyclerView = (RecyclerView) findViewById(R.id.recycleView);
        recyclerView.setHasFixedSize(true);//item固定高度
        recyclerView.setLayoutManager(new LinearLayoutManager(this));//设置默认的管理器
        RecycleViewAdapter recycleViewAdapter = new RecycleViewAdapter(this, list);
        recyclerView.setAdapter(recycleViewAdapter);

至此, RecycleView的工作就做好了。


下面是SwipeRefreshLayout的用法

同样在java文件中找到句炳,并设置监听
//        1、setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置手势滑动监听器。
//        2、setProgressBackgroundColor(int colorRes):设置进度圈的背景色。
//        3、setColorSchemeResources(int… colorResIds):设置进度动画的颜色。
//        4、setRefreshing(Boolean refreshing):设置组件的刷洗状态。
//        5、setSize(int size):设置进度圈的大小,只有两个值:DEFAULT、LARGE
        //其余的属性自己去寻找就OK了
        //这里要说明一点的是:我以为在SwipeRefreshLayout + RecyclerView两个一起,然后手势上下滚动
        //系统会傻傻分不清,然后造成无法滑动RecyclerView,或者无法进行SwipeRefreshLayout刷新
        //但是,今天我特意弄了两个同样有滑动手势的控件,看会不会产生冲突
        //事实证明,系统帮我们作了区分,只有在RecyclerView到达了第一条数据顶部是,SwipeRefreshLayout才会起作用
        refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshLayout);
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                tv_refreshing.setVisibility(View.VISIBLE);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Message msg = mHandler.obtainMessage();
                        msg.arg1 = 101;
                        mHandler.sendMessage(msg);
                    }
                }, 2000);
            }
        });

我这里用了一个handler来操作,本来想用监听者的,但是太麻烦了,就没弄。

Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.arg1 == 101) {
                refreshLayout.setRefreshing(false);
                tv_refreshing.setVisibility(View.INVISIBLE);
            }
        }
    };

这里说明一下,refreshLayout.setRefreshing(false) 就是结束刷新的方法。
至此,刷新控件也算完成了。

以上纯属个人见解,各位看官如果有任何疑问,请与我联系。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值