RecycleView的刷新,点击监听以及下划线设置

原创 2017年08月13日 13:28:33

前言

RecycleView功能已经非常强大了,可以说它已经是ListView的替代品,而它的刷新XRecycleView也刚好是XListView的替代品,下面就是实现在Xutils框架下的XRecycleView的刷新,监听和下划线设置。
(对于Xutils不了解的可以参考:http://blog.csdn.net/qiaoshi96_bk/article/details/74613542

依赖,权限

由于XRecycleView是v7的所以在使用该方法的时候我们必须导入依赖

compile 'com.jcodecraeer:xrecyclerview:1.3.2'

当然如果你需求里没有刷新的话,我们可以导入

 compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'

还有Xutils的依赖

 compile 'org.xutils:xutils:3.5.0'

因为是网络请求还得导入Gson解析的依赖

  compile 'com.google.code.gson:gson:2.8.1'

在清单文件配置网络请求的权限

 <uses-permission android:name="android.permission.INTERNET" />

到这里我们的准备工作就差不多完成了下面可以进行我们的功能操作了

XRecycleView的数据适配

注意点

由于我们是用Xutils框架的所以当创建App类时千万不要忘记在清单文件里加上引用如下:
在Application加上

 android:name=".App"

布局

activity_main.xml里面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.administrator.ggrecycle.MainActivity">
    <com.jcodecraeer.xrecyclerview.XRecyclerView
        android:id="@+id/x_recyc"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.jcodecraeer.xrecyclerview.XRecyclerView>
</LinearLayout>

子布局first_item 里

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/f_item"
        android:layout_width="match_parent"
        android:layout_height="160dp" />
<TextView
    android:id="@+id/f_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
</LinearLayout>

可见和ListView一样只是简单的布局。

代码

MainActivity中

@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    private String path="http://app.u17.com/v3/appV3_3/android/phone/list/commonComicList?argValue=23&argName=sort&argCon=0&page=1&android_id=4058040115108878&v=3330110&model=GT-P5210&come_from=Tg002";
    @ViewInject(R.id.x_recyc)
    XRecyclerView recyclerView;
    List<First_User.DataBean.ReturnDataBean.ComicsBean> list;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        x.view().inject(this);
        list=new ArrayList<>();
//        指定RecycleView的布局方式
        LinearLayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        adapter = new MyAdapter(list);
        recyclerView.setAdapter(adapter);
        getDate();
    }

    private void getDate() {
        RequestParams params = new RequestParams(path);
        x.http().get(params, new Callback.CacheCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Gson gson = new Gson();
                First_User user = gson.fromJson(result, First_User.class);
                list.addAll(user.getData().getReturnData().getComics());
                adapter.notifyDataSetChanged();
            }

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

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }

            @Override
            public boolean onCache(String result) {
                return false;
            }
        });

    }

}

可以看到这里面代码和ListView基本上一样唯一不同的是:

  LinearLayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);

多了上面这两行代码,其实这两行就是用来指定RecycleView的布局方式,是必须得写的,这里写LinearLayoutManager就是和普通的ListView相似

适配器: MyAdapter

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<First_User.DataBean.ReturnDataBean.ComicsBean> list;

    public MyAdapter(List<First_User.DataBean.ReturnDataBean.ComicsBean> list) {
        this.list = list;
    }
//初始化时
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//        加载我们的子布局
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.first_item,parent,false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }
//绑定成功
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof  MyViewHolder){
            MyViewHolder my= (MyViewHolder) holder;
           my.title.setText(list.get(position).getName());
            x.image().bind(my.imageView,list.get(position).getCover());
        }

    }
//返回集合里面的条目总数
    @Override
    public int getItemCount() {
        return list.size();
    }
//    创建自己的ViewHolder
    static class MyViewHolder extends RecyclerView.ViewHolder{
            @ViewInject(R.id.f_item)
            ImageView imageView;
            @ViewInject(R.id.f_title)
            TextView title;
        public MyViewHolder(View itemView) {
            super(itemView);
            x.view().inject(this,itemView);
        }
    }

}

可以看到RecycleView的适配器和ListView有很大的变化,其实只是RecycleView是把优化封装好的,也是必须要优化,所以我们才必须继承 RecyclerView.Adapter 里的RecyclerView.ViewHolder
然后重写里面的三个方法

  • onCreateViewHolder(ViewGroup parent, int viewType)
    • onCreateViewHolder:创建ViewHolder实例,把我们自己的MyViewHolder放入里面
  • onBindViewHolder(RecyclerView.ViewHolder holder, int position)
    • onBindViewHolde:这个方法就是对RecycleView里面的子布局进行赋值操作
  • getItemCount()
    • getItemCount():这个好理解就是返回list集合里面的条目总数
      还有我们自定义的MyViewHolder
 static class MyViewHolder extends RecyclerView.ViewHolder{
            @ViewInject(R.id.f_item)
            ImageView imageView;
            @ViewInject(R.id.f_title)
            TextView title;
        public MyViewHolder(View itemView) {
            super(itemView);
            x.view().inject(this,itemView);
        }
    }

这里是我们自己创建的MyViewHolder ,我们的子布局获取id都是在里面操作的。
到这里简单的RecycleView展示数据就完成了,效果如下

这里写图片描述

下拉刷新上拉加载

对于刷新控件XRecycleView已经帮我封装好了,所以我们只需要实现 XRecyclerView.LoadingListener
并且重写onRefresh(),onLoadMore()两个方法,

//刷新
    @Override
    public void onRefresh() {
    //清空集合
        list.clear();
        page=1;
        getDate();
        adapter.notifyDataSetChanged();
    }
//加载更多
    @Override
    public void onLoadMore() {
        page++;
        getDate();
        adapter.notifyDataSetChanged();
    }

同时要在onCreate里面设置

//       对XRecycleView设置可以加载和刷新
         recyclerView.setLoadingListener(this);
         recyclerView.setPullRefreshEnabled(true);
//设置刷新风格
        recyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallPulseRise);

当然这里的刷新样式有很多种详情:
https://github.com/jianghejie/XRecyclerView
最后只需要在Xutils里的onfinish()里

   recyclerView.loadMoreComplete();
   recyclerView.refreshComplete();

到这里它的刷新和加载更多就基本实现了。

XrecycleView的监听

由于XUtils是没有事件的监听的,所以如果我们想要对我们的控件实现监听就必须得自己定义接口,并通过回调来实现。

所以在我们的MyAdapter里面需要写接口

    /**
     * 点击事件回掉接口
     */
    public interface OnItemClickListener {
        void onItemClick(View var2, int var3);

        void onImageClick(View view, int pos);

    }

然后在onBindViewHolder判断并调用接口

   if (holder instanceof  MyViewHolder){
            MyViewHolder my= (MyViewHolder) holder;
           my.title.setText(list.get(position).getName());
            x.image().bind(my.imageView,list.get(position).getCover());
//            设置整根条目的监听
            my.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (listener!=null){
                        listener.onItemClick(view,position);
                    }
                }
            });
//            设置单个监听
            my.imageView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    if (listener!=null){
                        listener.onImageClick(view,position);
                    }

                    return true;
                }
            });
        }

    }

最后千万不要忘记定义构造方法来设置监听:

   OnItemClickListener listener;//定义监听事件

    /**
     * 设置监听事件
     *
     * @param listener
     */
    public void setListener(OnItemClickListener listener) {
        this.listener = listener;
    }

在我们住方法里面

既然是通过接口来实现监听如何我们想要自定义我们的监听事先当然得实现接口,所以首先我们得
实现MyAdapter.OnItemClickListener,我们自己写的接口,并重写里面的两个方法

   @Override
    public void onItemClick(View var2, int var3) {
        Toast.makeText(MainActivity.this,"点击了整个条目",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onImageClick(View view, int pos) {
        Toast.makeText(MainActivity.this,"长按了图片",Toast.LENGTH_SHORT).show();
    }

最后千万不要忘记在我们等Oncreate里面加上:

 adapter.setListener(this);

到这里我们的监听事件也就完全实现了。

设置下滑线

定义MyLine类

RecycleView为我们提供ItemDecoration方法,所以我们可以通过继承它来为我们的对我们RecycleView进行修饰:

public class MyLine extends RecyclerView.ItemDecoration {
    Drawable drawable;
    public MyLine(Context context, int resId) {
        drawable=context.getResources().getDrawable(resId);
    }
//设置item之间的边距
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.set(8,8,8,8);
    }
//重写方法来实现自定义布局
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }

//   绘制分割线

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        final int childCount = parent.getChildCount();
        for(int i=0;i<childCount;i++){
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            //以下计算主要用来确定绘制的位置
            final int top = child.getBottom() + params.bottomMargin;
            //注意这边drawable.getIntrinsicHeight()必须有高度
            final int bottom = top + drawable.getIntrinsicHeight();

            drawable.setBounds(left,top,right,bottom);
            drawable.draw(c);

            //        绘制虚线
//            Paint paint = new Paint();
//            paint.setStyle(Paint.Style.STROKE);
//            paint.setColor(Color.RED);
//            Path path = new Path();
//            path.moveTo(left, top);
//            path.lineTo(right,top);
//            PathEffect effects = new DashPathEffect(new float[]{15,15,15,15},5);//此处单位是像素不是dp  注意 请自行转化为dp
//            paint.setPathEffect(effects);
//            c.drawPath(path, paint);
//            drawable.setBounds(left,top,right,bottom);
//            drawable.draw(c);
        }


    }
}

MainActivity中

其实在我们的MainActivity中只需要一步就可以实现我们的分割线了:

//        设置条目之间的下划线
        recyclerView.addItemDecoration(new MyLine(this,R.drawable.item_line));

但是我们需要:R.drawable.item_line
很显然我们需要定义一个xml文件来写我们分割线的属性(颜色,宽度等):
所以我们在drawable下面定义item_line

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#66a92b"></solid>
    <size android:height="2dp"></size>
</shape>

到这里我们的所有功能都实现了
最终效果如下:
这里写图片描述

代码

这里贴上MainActivity和MyAdapter里面的代码
MainActivity

@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity implements XRecyclerView.LoadingListener,MyAdapter.OnItemClickListener{
    int page=1;
    private String path="http://app.u17.com/v3/appV3_3/android/phone/list/commonComicList?argValue=23&argName=sort&argCon=0&android_id=4058040115108878&v=3330110&model=GT-P5210&come_from=Tg002&page=";
    @ViewInject(R.id.x_recyc)
    XRecyclerView recyclerView;
    List<First_User.DataBean.ReturnDataBean.ComicsBean> list;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        x.view().inject(this);
        list=new ArrayList<>();

//        指定RecycleView的布局方式
        LinearLayoutManager manager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(manager);
        adapter = new MyAdapter(list);
        recyclerView.setAdapter(adapter);
        recyclerView.setLoadingListener(this);
        recyclerView.setLoadingMoreEnabled(true);
        //设置刷新风格
        recyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallPulseRise);
        //        设置条目之间的下划线
        recyclerView.addItemDecoration(new MyLine(this,R.drawable.item_line));
        adapter.setListener(this);
        getDate();
    }

    private void getDate() {
        RequestParams params = new RequestParams(path+page);
        x.http().get(params, new Callback.CacheCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Gson gson = new Gson();
                First_User user = gson.fromJson(result, First_User.class);
                list.addAll(user.getData().getReturnData().getComics());
                adapter.notifyDataSetChanged();
            }

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

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {
                recyclerView.loadMoreComplete();
                recyclerView.refreshComplete();
            }

            @Override
            public boolean onCache(String result) {
                return false;
            }
        });

    }
//刷新
    @Override
    public void onRefresh() {
        list.clear();
        page=1;
        getDate();
        adapter.notifyDataSetChanged();
    }
//加载更多
    @Override
    public void onLoadMore() {
        page++;
        getDate();
        adapter.notifyDataSetChanged();
    }

    @Override
    public void onItemClick(View var2, int var3) {
        Toast.makeText(MainActivity.this,"点击了整个条目",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onImageClick(View view, int pos) {
        Toast.makeText(MainActivity.this,"长按了图片",Toast.LENGTH_SHORT).show();
    }
}

MyAdapter

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<First_User.DataBean.ReturnDataBean.ComicsBean> list;

    public MyAdapter(List<First_User.DataBean.ReturnDataBean.ComicsBean> list) {
        this.list = list;
    }
    OnItemClickListener listener;//定义监听事件

    /**
     * 设置监听事件
     *
     * @param listener
     */
    public void setListener(OnItemClickListener listener) {
        this.listener = listener;
    }

//初始化时
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//        加载我们的子布局
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.first_item,parent,false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }
//绑定成功
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        if (holder instanceof  MyViewHolder){
            MyViewHolder my= (MyViewHolder) holder;
           my.title.setText(list.get(position).getName());
            x.image().bind(my.imageView,list.get(position).getCover());
//            设置整根条目的监听
            my.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (listener!=null){
                        listener.onItemClick(view,position);
                    }
                }
            });
//            设置单个监听
            my.imageView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    if (listener!=null){
                        listener.onImageClick(view,position);
                    }

                    return true;
                }
            });
        }

    }
//返回集合里面的条目总数
    @Override
    public int getItemCount() {
        return list.size();
    }

    //    创建自己的ViewHolder
    static class MyViewHolder extends RecyclerView.ViewHolder{
            @ViewInject(R.id.f_item)
            ImageView imageView;
            @ViewInject(R.id.f_title)
            TextView title;
        public MyViewHolder(View itemView) {
            super(itemView);
            x.view().inject(this,itemView);
        }
    }

    /**
     * 点击事件回掉接口
     */
    public interface OnItemClickListener {
        void onItemClick(View var2, int var3);

        void onImageClick(View view, int pos);

    }

}

完整dome下载:https://github.com/Qiaoshi96/GGRecycle.git

版权声明:个人学习总结。

TextView使用SpannableString设置某部分文本的各种属性(点击、颜色、下划线...)

public void setSpan(Object what, int start, int end, int flags) { super.setSpan(what, start, end...

RecycleView 分割线设置及监听滚动状态

一、RecycleView 分割线ListView中的分割线可以通过属性divider和dividerHeight分别设置颜色值/图片及分割线高度。而RecycleView并没有提供这两个属性设置分割...

(十九)TableView的点击监听和数据刷新(Alert的多种样式) -tag传值的技巧

要实现监听,要使用代理,控制器要成为TableView的代理。 注意下面的方式是代理方法: - (void)tableView:(UITableView *)tableView didSelectRo...

RecyclerView系列(二)下拉刷新、上拉加载、Item点击监听

RecyclerView下拉刷新、上拉加载、Item点击监听
  • nsacer
  • nsacer
  • 2017年05月23日 22:51
  • 174

RecyclerView原生的上拉加载与下拉刷新及点击监听事件

刷新和加载//刷新 srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Overrid...

iOS—TableView的点击监听和数据刷新(Alert的多种样式) -tag传值的技巧

要实现监听,要使用代理,控制器要成为TableView的代理。 注意下面的方式是代理方法:   - (void)tableView:(UITableView *)tableView didSel...

有关ios UITableViewCell自定义下划线在点击时先消失再出现的问题

最近在开发公司app时发现一个问题,在公司自定义的UITableViewCell上的下划线,在点击Cell之后,下划线会先消失再出现.由于是菜鸟ioser,对这个问题很疑惑,一度找不到原因.由于公司的...
  • loiszxy
  • loiszxy
  • 2017年01月08日 17:41
  • 380

Android RecycleView 里面有按钮点击 复用错位的问题解决

今天做了商城收货地址选择的部分,地址信息又RecycleVeiw展示。里面有一个自己写的TextView 选择那个 那个背景图就是一个对号。而且是单选。之前定义一个int 常量num,每次点击text...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RecycleView的刷新,点击监听以及下划线设置
举报原因:
原因补充:

(最多只允许输入30个字)