Android控件RecyclerView实现横向滑动、瀑布流。

在开发的过程中,我们经常使用ListView控件,但是ListView也有它的缺点,就是它不能够左右滑动数据,运行效率不高;
所以我们可以使用更强大的控件RecyclerView,可以说它是一个增强版的ListView,Google推荐使用,那就简单的使用一下这个控件。

首先,我们先来实现一个跟ListView一样效果的界面。

这里写图片描述

因为RecyclerView是在support包中,所以我们要在build.gradle中添加该依赖。

compile 'com.android.support:recyclerview-v7:25.1.0'
第一步,在布局中创建出该控件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.dell.recyclerviewdemo.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyc"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
第二步,创建行布局item

这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:id="@+id/item_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="20dp"
        android:text="Hello World!" />
</LinearLayout>
第三步:创建实体类,来封装数据

/**
 * Created by Dell on 2017/1/9.
 */

public class ItemVO {
    private int mImg;
    private String mName;

    public ItemVO(int mImg, String mName) {
        this.mImg = mImg;
        this.mName = mName;
    }

    public void setmImg(int mImg) {
        this.mImg = mImg;
    }

    public void setmName(String mName) {
        this.mName = mName;
    }

    public int getmImg() {
        return mImg;
    }

    public String getmName() {
        return mName;
    }
}
第四步:创建适配器
package com.example.adapter;

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

import com.example.dell.recyclerviewdemo.R;
import com.example.vo.ItemVO;

import java.util.List;

/**
 * Created by Dell on 2017/1/9.
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
    //动态数组
    private List<ItemVO> mList;

    //构造
    public MyAdapter(List<ItemVO> mList) {
        this.mList = mList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //绑定行布局
        View view = View.inflate(parent.getContext(),R.layout.item,null);
        //实例化ViewHolder
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    //设置数据
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //获取当前实体类对象
        ItemVO vo = mList.get(position);
        //设置
        holder.text.setText(vo.getmName());
        holder.img.setImageResource(vo.getmImg());
    }

    //数量
    @Override
    public int getItemCount() {
        return mList.size();
    }

    //内部类
    class ViewHolder extends RecyclerView.ViewHolder{
        //行布局中的控件
        ImageView img;
        TextView text;
        public ViewHolder(View itemView) {
            super(itemView);
            //绑定控件
            img = (ImageView) itemView.findViewById(R.id.item_img);
            text = (TextView) itemView.findViewById(R.id.item_text);
        }
    }
}
说明:

首先定义了一个内部类ViewHolder,继承RecyclerView.ViewHolder,然后定义两个两个全局变量,即行布局中的控件,然后再构造方法中绑定控件。
然后将适配器这个类继承RecyclerView.Adapter<内部类>,需要重写onCreateViewHolder()、onBindViewHolder()、getItemCount()这三个方法。
onCreateViewHolder():创建ViewHolder实例。
onBindViewHolder():对数据进行赋值。
getItemCount():返回有多少数据。

第五步:MainActivity
package com.example.dell.recyclerviewdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.example.adapter.MyAdapter;
import com.example.vo.ItemVO;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mView;
    private List<ItemVO> mList = new ArrayList<ItemVO>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定id
        bindID();
        //添加数据
        addData();
        //创建LinearLayoutManager
        LinearLayoutManager manager = new LinearLayoutManager(this);
        //设置
        mView.setLayoutManager(manager);
        //实例化适配器
        MyAdapter myAdapter = new MyAdapter(mList);
        //设置适配器
        mView.setAdapter(myAdapter);
    }

    private void addData() {
        for (int i = 0 ; i<50 ; i++){
            ItemVO itemVO = new ItemVO(R.mipmap.ic_launcher, i + ":Hello World!");
            //添加到数组
            mList.add(itemVO);
            itemVO = null;
        }
    }

    private void bindID() {
        mView = (RecyclerView) findViewById(R.id.recyc);
    }
}
说明:

这里跟ListView的使用方式是差不多的。
使用一个addData()方法添加数据到mList,接着在onCreate()方法中首先获取到RecyclerView实例,然后创建出一个LinearLayoutManager对象,将让设置到RecyclerView当中。LinearLayoutManager用于指定RecyclerView的布局方式;然后实例化MyAdapter;最后绑定适配器。

这样,效果跟ListView实现是一样的。

改变滑动方向:横向滑动

这里写图片描述

首先改变一下行布局item

因为是横向滑动,所以我们将行布局的宽度限定了。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    <--! 限定宽度-->
    android:layout_height="100dp"
    android:orientation="vertical"
    android:padding="10dp">

    <ImageView
        android:id="@+id/item_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Hello World!" />
</LinearLayout>
修改MainActivity

在onCreate()中给LinearLayoutManager设置属性


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定id
        bindID();
        //添加数据
        addData();
        //创建LinearLayoutManager
        LinearLayoutManager manager = new LinearLayoutManager(this);
        //设置为横向滑动
        manager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //设置
        mView.setLayoutManager(manager);
        //实例化适配器
        MyAdapter myAdapter = new MyAdapter(mList);
        //设置适配器
        mView.setAdapter(myAdapter);
    }

运行后,就会实现这个横向滑动了。
这样,RecyclerView的优势就显示出来了,完成了ListVIew不能完成的任务。

使用RecyclerView实现瀑布流

这里写图片描述

第一步:修改行布局Item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dp">

    <ImageView
        android:id="@+id/item_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Hello World!" />
</LinearLayout>

将行布局宽度更改为自定义。

修改MainActivity
package com.example.dell.recyclerviewdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

import com.example.adapter.MyAdapter;
import com.example.vo.ItemVO;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mView;
    private List<ItemVO> mList = new ArrayList<ItemVO>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //绑定id
        bindID();
        //添加数据
        addData();
//        //创建LinearLayoutManager
//        LinearLayoutManager manager = new LinearLayoutManager(this);
//        //设置为横向滑动
//        manager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //参数意思:分为几列;方向。
        StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);

        //设置
        mView.setLayoutManager(manager);
        //实例化适配器
        MyAdapter myAdapter = new MyAdapter(mList);
        //设置适配器
        mView.setAdapter(myAdapter);
    }

    private void addData() {
        for (int i = 0; i < 50; i++) {
            ItemVO itemVO = new ItemVO(R.mipmap.ic_launcher, getRandomStr(i + ":Hello World!"));
            //添加到数组
            mList.add(itemVO);
            itemVO = null;
        }
    }
    //将文本长度改变
    private String getRandomStr(String str){
        Random random = new Random();
        int num = random.nextInt(10)+1;
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i< num ;i++){
            builder.append(str+"");
        }
        return builder.toString();
    }

    private void bindID() {
        mView = (RecyclerView) findViewById(R.id.recyc);
    }
}
说明:

将关于LinearLayoutManager的都注释掉,使用StaggeredGridLayoutManager对象。
因为瀑布流在textView数据长度不同的时候才能看到,所以我们就随机更该文本的长度,让瀑布流效果显示出来。

RecyclerView实现点击事件的监听

这里写图片描述
在RecyclerView中,没有提供给我们点击事件的方法,需要我们自己给子项具体的View去注册点击事件,相比ListView,这的确是比较麻烦,但是不代表RecyclerView不好,而是RecyclerView是人性化设计,可以根据自己的需要去设计,我们可以给每一个item设置监听,也可以给每一个TextView或其他设置监听。

修改MyAdapter

给每个item 和 textView设置监听

package com.example.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.dell.recyclerviewdemo.R;
import com.example.vo.ItemVO;

import java.util.List;

/**
 * Created by Dell on 2017/1/9.
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
    //动态数组
    private List<ItemVO> mList;

    //构造
    public MyAdapter(List<ItemVO> mList) {
        this.mList = mList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //绑定行布局
        final View view = View.inflate(parent.getContext(),R.layout.item,null);
        //实例化ViewHolder
        final ViewHolder holder = new ViewHolder(view);
        //item设置监听
        holder.view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取到position
                int layoutPosition = holder.getLayoutPosition();
                //土司
                Toast.makeText(view.getContext(),"This is item :"+layoutPosition,Toast.LENGTH_SHORT).show();
            }
        });
        //textView设置监听
        holder.text.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取到position
                int layoutPosition = holder.getLayoutPosition();
                //土司
                Toast.makeText(view.getContext(),"This is textView :"+layoutPosition,Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }

    //设置数据
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        //获取当前实体类对象
        ItemVO vo = mList.get(position);
        //设置
        holder.text.setText(vo.getmName());
        holder.img.setImageResource(vo.getmImg());
    }

    //数量
    @Override
    public int getItemCount() {
        return mList.size();
    }

    //内部类
    class ViewHolder extends RecyclerView.ViewHolder{
        //行布局中的控件
        ImageView img;
        TextView text;
        //视图
        View view;
        public ViewHolder(View itemView) {
            super(itemView);
            view = itemView;
            //绑定控件
            img = (ImageView) itemView.findViewById(R.id.item_img);
            text = (TextView) itemView.findViewById(R.id.item_text);
        }
    }
}

先修改了ViewHolder,在ViewHolder中添加了view变量来保存子项最外层布局实例,然后再onCreateViewHolder()中注册监听就好了。
这也是RecyclerView的强大之处,可以轻松的对子项中的任意控件设置点击事件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值