Android开发——RecycleView控件(十三)

android开发 笔记(1.30)

  • 1.关于RecycleView的简易封装
  • 2.基本用法
  • 3.实现横向滚动和瀑布流布局.
    • (1)横向滚动
    • (2)瀑布流布局
    • 4.相关点击事件

1.关于RecycleView的简易封装

默认的Adapter :

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }
}

要写出一个RecyclerView.Adapter必须自己写一个ViewHolder且一定要继承RecyclerView.ViewHolder;然后重写onCreateViewHolder、onBindViewHolder、getItemCount这三个函数
而其他几个函数都基本上都是固定格式了,所以我们就可以将这些千篇一律的代码进行封装了。

Adapter中我们最终要的一个就是数据源了,所以我们需要先定义我们的数据源但是你会发现在不同的地方
我们的数据也是不一样的那我们怎么定义呢?这个时候我们就需要引入泛型了。

2.基本用法

1.RecycleVIew定义在support库中,所以要想使用这个控件,需要在build.grade中添加相应的依赖库。(记得Sync now同步)
Android开发——RecycleView控件(十三)_第1张图片
2.activity_main.xml中
Android开发——RecycleView控件(十三)_第2张图片
为RecyclerView指定一个id,宽高都为match_parent,这样就使RecycleView铺满整个布局空间。
(因为RecycleView不是内置系统Sdk当中的,所以需要把他的完整路径写下来)
3.同ListView的例子一样写一个Fruit类和fruit_item.xml,并将所需水果图复制过来。
Android开发——RecycleView控件(十三)_第3张图片
Android开发——RecycleView控件(十三)_第4张图片
4.为RecycleView准备一个适配器
(作用:把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作)

关于适配器的详细介绍博推荐:https://blog.csdn.net/carson_ho/article/details/54910430
(关于泛型的定义:https://blog.csdn.net/a_zhon/article/details/66971369)

默认的Adapter

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }
}

FruitAdapter.java
新建FruitAdapter类,让这个适配器继承自RecycleView.Adapter,并将泛型指定为FruitAdapter.Viewholder。其中,ViewHolder是在FruitAdapter定义的一个内部类。

代码如下:

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    private List<Fruit> myFruitList;

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(View view) {
            super(view);
            fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            fruitName = (TextView) view.findViewById(R.id.fruit_name);

        }

    }

    public FruitAdapter(List<Fruit> fruitList) {
        myFruitList = fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Fruit fruit = myFruitList.get(position);
        holder.fruitImage.setImageResource(fruit.getImageId());
        holder.fruitName.setText(fruit.getName());
    }

    @Override
    public int getItemCount() {
        return myFruitList.size();
    }
}

1.首先定义一个内部类ViewHolder,VIewHolder首先要继承RecycleView.ViewHolder。ViewHolder的构造函数要传入一个View参数,通常就是RecycleView子项的最外层布局
2.FruitAdapter中也存在一个构造函数,
public FruitAdapter(List< Fruit> fruitList) {
myFruitList = fruitList;
}
这个方法用于把要展示的数据源传进来,并赋值给全局变量mFruitList
3.重写三个方法
onCreateViewHolder()创建ViewHolder实例,把加载出来的布局传入到构造函数当中,最后将ViewHolder的实力返回
onBindViewHolder()用于对子项数据进行赋值,通过position得到当前Fruit实例,然后再将数据设置到ViewHolder的ImageView和TextView当中
getItemCount()告诉RecycleView一共有多少个子项,直接返回数据源长度就可以了。


5.MainActivity.java

public class MainActivity extends Activity {
    private List<Fruit> fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView=(RecyclerView) findViewById(R.id.recycler_view);
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        FruitAdapter adapter=new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);

    }
 private void initFruits() {
            Fruit apple = new Fruit("apple", R.drawable.apple);
            fruitList.add(apple);
            Fruit pear = new Fruit("apple", R.drawable.pear);
            fruitList.add(pear);
            Fruit pineapple = new Fruit("apple", R.drawable.pineapple);
            fruitList.add(pineapple);
            Fruit kiwi = new Fruit("apple", R.drawable.kiwi);
            fruitList.add(kiwi);
            Fruit grapes = new Fruit("apple", R.drawable.grapes);
            fruitList.add(apple);
            Fruit raspberry = new Fruit("apple", R.drawable.raspberry);
            fruitList.add(raspberry);
            Fruit straberry = new Fruit("apple", R.drawable.straberry);
            fruitList.add(straberry);
    }
}

注:1.为什么是List list = new ArrayList(),而不直接用ArrayList
(1) List list = new ArrayList();
这样你就只能调用List接口里面定义好的方法,而不能使用你自己在ArrayList扩展的方法。

(2) ArrayList list = new ArrayList();
这样你可以使用自己在ArrayList类上扩展的方法

接口就是定义了一些行为,它要求你应该做什么。 假如你采用了面向接口编程方式,也就是第一种方式:
List list = new ArrayList(); 就能通过接口很大限度上规范开发人员的实现规则,因为你现在只能调用接口的方法。

1.initFruits() 用于初始化所有水果数据
2.onCreate()方法中休闲获取RecycleView的实例
3.创建一个LinearLayoutManager对象,并将它设置到RecycleView当中。
4.创建FruitAdapter的实例并将水果数据传入到构造函数之中
5.调用RecycleView的setAdapter()方法来完成适配器设置

3.实现横向滚动和瀑布流布局.

(1)横向滚动

以上面的例子修改:

fruit_item.xml
Android开发——RecycleView控件(十三)_第5张图片

MainActivity.java 中只加入
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
调用LinearLayoutManager的setOrientation()方法来设置布局的排列方向,默认是纵向排列的,我们把它修改为LinearLayoutManager.HORIZONTAL
Android开发——RecycleView控件(十三)_第6张图片
Android开发——RecycleView控件(十三)_第7张图片

RecycleView将工作交给LayoutManager,LayoutManager中制定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现,就可以制定出各种不同的布局了。

(2)瀑布流布局

fruit_item.xml的修改细节
Android开发——RecycleView控件(十三)_第8张图片

StaggeredGridLayoutManager layoutManager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);

在onCreate()方法中创建一个StaggeredGridLayoutManager的实例,StaggeredGridLayoutManager的构造函数接收两个参数,第一个参数用于指定布局的列数,第二个参数用于指定布局的排列方向。

这里在写入一个getRandomLengthName()方法,实现更好的瀑布效果

 private String getRandomLengthName(String name){
        Random random=new Random();
        int length=random.nextInt(20)+1;
        StringBuilder builder=new StringBuilder();
        for(int i=0;i<length;i++){
            builder.append(name);
        }
        return builder.toString();
    }

注:
(1)nextInt(int n) 方法用于获取一个伪随机,在0(包括)和指定值(不包括),从此随机数生成器的序列中取出均匀分布的int值。
(2)StringBuffer 方法:
以下是 StringBuffer 类支持的主要方法:
1 public StringBuffer append(String s)
将指定的字符串追加到此字符序列。
2 public StringBuffer reverse()
将此字符序列用其反转形式取代。
3 public delete(int start, int end)
移除此序列的子字符串中的字符。
4 public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。
5 replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。

效果图:
Android开发——RecycleView控件(十三)_第9张图片

4.相关点击事件

修改ViewHolder,在ViewHolder中添加fruitView变量来保存子项最外层实例,然后在onCreateViewHolder()方法中注册点击事件。这里分别在最外层布局和ImageView都注册点击事件。
在两个事件中先获取用户的点击的position,然后通过position拿到相应的Fruit实例,再分别使用Toast分别弹出两种不同内容以示区别。

相关代码:
Android开发——RecycleView控件(十三)_第10张图片

    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        final View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
        final ViewHolder holder=new ViewHolder(view);
        holder.fruitView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position=holder.getAdapterPosition();
                Fruit fruit=myFruitList.get(position);
                Toast.makeText(v.getContext(),"you clicked view"+fruit.getName(),Toast.LENGTH_SHORT).show();
            }
        });
        holder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position=holder.getAdapterPosition();
                Fruit fruit=myFruitList.get(position);
                Toast.makeText(v.getContext(),"you clicked image"+fruit.getImageId(),Toast.LENGTH_SHORT).show();
            }
        });

        return  holder;
    }


你可能感兴趣的:(android开发)