新建项目RecyclerViewTest
RecyclerView是新增控件定义在support库中需要在app/build.gradle中添加相应的依赖库运行效率比ListView好很多ListView只能纵向滚动RecyclerView可以横向滚动
//build.gradledependencies {implementation fileTree(dir:\'libs\',includes: [\'*.jar\'])implementation \'com.android.support:appcompat-v7:30.2.1\'implementation \'com.android.support:recyclerview-v7:30.2.1\'testImplementation \'junit:junit:4.12\'}
//activity_main.xml//添加RecyclerView控件<?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=\"match_parent\"><androidx.recyclerview.widget.RecyclerViewandroid:id=\"@+id/recycler_view\"android:layout_width=\"match_parent\"android:layout_height=\"match_parent\"/></LinearLayout>
//新建类Fruit.java//name表示水果名//imageId表示水果对应图片的资源idpackage com.example.recyclerviewtest;public class Fruit {private String name;private int imageId;public Fruit(String name, int imageId){this.name = name;this.imageId = imageId;}public String getName(){return name;}public int getImageId(){return imageId;}}
//新建布局fruit_item.xml<?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\"><ImageViewandroid:id=\"@+id/fruit_image\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"/><TextViewandroid:id=\"@+id/fruit_name\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"android:layout_gravity=\"center_vertical\"android:layout_marginLeft=\"10dp\"/></LinearLayout>
//新建FruitAdapter类package com.example.recyclerview;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import java.util.List;import androidx.recyclerview.widget.RecyclerView;public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<Fruit> mFruitList;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){mFruitList = fruitList;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);ViewHolder holder = new ViewHolder(view);return holder;}@Overridepublic void onBindViewHolder(ViewHolder holder, int position){Fruit fruit = mFruitList.get(position);holder.fruitImage.setImageResource(fruit.getImageId());holder.fruitName.setText(fruit.getName());}@Overridepublic int getItemCount() {return mFruitList.size();}}
//MainActivitypackage com.example.recyclerview;import androidx.appcompat.app.AppCompatActivity;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;import android.os.Bundle;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {private List<Fruit> fruitList = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initFruits();RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);LinearLayoutManager layoutManager = new LinearLayoutManager(this);recyclerView.setLayoutManager(layoutManager);FruitAdapter adapter = new FruitAdapter(fruitList);recyclerView.setAdapter(adapter);}private void initFruits(){for(int i = 0 ; i < 2 ; i++){Fruit apple = new Fruit(\"Apple\",R.drawable.apple);fruitList.add(apple);Fruit banana = new Fruit(\"Babnana\",R.drawable.banana);fruitList.add(banana);Fruit orange = new Fruit(\"Orange\",R.drawable.orange);fruitList.add(orange);Fruit watermelon = new Fruit(\"Watermelon\",R.drawable.watermelon);fruitList.add(watermelon);Fruit pear = new Fruit(\"Pear\",R.drawable.pear);fruitList.add(pear);Fruit grape = new Fruit(\"Grape\",R.drawable.grape);fruitList.add(grape);Fruit pineapple = new Fruit(\"Pineapple\",R.drawable.pineapple);fruitList.add(pineapple);Fruit strawberry = new Fruit(\"Strawberry\",R.drawable.strawberry);fruitList.add(strawberry);Fruit cherry = new Fruit(\"Cherry\",R.drawable.cherry);fruitList.add(cherry);Fruit mango = new Fruit(\"Mango\",R.drawable.mango);fruitList.add(mango);}}}
横向滚动
//修改布局fruit_item.xml//改成垂直排列//控件位置改为水平居中//使用layout_marginTop让文图之间有距离<?xml version=\"1.0\" encoding=\"utf-8\"?><LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"android:orientation=\"vertical\"android:layout_width=\"100dp\"android:layout_height=\"wrap_content\"><ImageViewandroid:id=\"@+id/fruit_image\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"android:layout_gravity=\"center_horizontal\"/><TextViewandroid:id=\"@+id/fruit_name\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"android:layout_gravity=\"center_horizontal\"android:layout_marginTop=\"10dp\"/></LinearLayout>
//MainActivity@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initFruits();RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); //添加一行代码recyclerView.setLayoutManager(layoutManager);FruitAdapter adapter = new FruitAdapter(fruitList);recyclerView.setAdapter(adapter);}
ListView布局排列是由自身去管理的而RecyclerView将这个工作交给了LayoutManagerLayoutManager制定了一套可扩展的布局排列接口子类只要按照接口的规范来实现就能制定出不同的布局排列方式
RecyclerView还提供了网格布局GridLayoutManager和瀑布流布局StaggeredGridLayoutManager。
瀑布流布局StaggeredGridLayoutManager
//修改布局fruit_item.xml<?xml version=\"1.0\" encoding=\"utf-8\"?><LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"android:orientation=\"vertical\"android:layout_width=\"match_parent\"android:layout_height=\"wrap_content\"android:layout_margin=\"5dp\" ><ImageViewandroid:id=\"@+id/fruit_image\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"android:layout_gravity=\"center_horizontal\"/><TextViewandroid:id=\"@+id/fruit_name\"android:layout_width=\"wrap_content\"android:layout_height=\"wrap_content\"android:layout_gravity=\"left\"android:layout_marginTop=\"10dp\"/></LinearLayout>
//MainActivitypublic class MainActivity extends AppCompatActivity {private List<Fruit> fruitList = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initFruits();RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);//LinearLayoutManager layoutManager = new LinearLayoutManager(this);//layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//第一个参数指定布局的列数,第二个参数指定布局的排列方向StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);recyclerView.setLayoutManager(layoutManager);FruitAdapter adapter = new FruitAdapter(fruitList);recyclerView.setAdapter(adapter);}//创造一个1-20的随机数,然后将参数中传入的字符串重复随机遍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();}private void initFruits(){for(int i = 0 ; i < 2 ; i++){Fruit apple = new Fruit(getRandomLengthName(\"Apple\"),R.drawable.apple);fruitList.add(apple);Fruit banana = new Fruit(getRandomLengthName(\"Babnana\"),R.drawable.banana);fruitList.add(banana);Fruit orange = new Fruit(getRandomLengthName(\"Orange\"),R.drawable.orange);fruitList.add(orange);Fruit watermelon = new Fruit(getRandomLengthName(\"Watermelon\"),R.drawable.watermelon);fruitList.add(watermelon);Fruit pear = new Fruit(getRandomLengthName(\"Pear\"),R.drawable.pear);fruitList.add(pear);Fruit grape = new Fruit(getRandomLengthName(\"Grape\"),R.drawable.grape);fruitList.add(grape);Fruit pineapple = new Fruit(getRandomLengthName(\"Pineapple\"),R.drawable.pineapple);fruitList.add(pineapple);Fruit strawberry = new Fruit(getRandomLengthName(\"Strawberry\"),R.drawable.strawberry);fruitList.add(strawberry);Fruit cherry = new Fruit(getRandomLengthName(\"Cherry\"),R.drawable.cherry);fruitList.add(cherry);Fruit mango = new Fruit(getRandomLengthName(\"Mango\"),R.drawable.mango);fruitList.add(mango);}}}
点击事件
RecyclerView没有提供类似于setOnItemClickListener()这样的注册监听器方法而是需要我们自己给子项具体的View去注册点击事件,比ListView复杂但想点击子项中具体的某一个按钮,ListView就比较麻烦了
//FruitAdapterpublic class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<Fruit> mFruitList;static class ViewHolder extends RecyclerView.ViewHolder{View fruitView; //保存子项最外层布局的实例ImageView fruitImage;TextView fruitName;public ViewHolder(View view){super(view);fruitView = view; //fruitImage = (ImageView) view.findViewById(R.id.fruit_image);fruitName = (TextView) view.findViewById(R.id.fruit_name);}}public FruitAdapter(List<Fruit>fruitList){mFruitList = fruitList;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);//ViewHolder holder = new ViewHolder(view);final ViewHolder holder = new ViewHolder(view);holder.fruitView.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v){int position = holder.getAdapterPosition(); //用户点击的位置Fruit fruit = mFruitList.get(position); //Fruit实例Toast.makeText(v.getContext(),\"You clicked view\" + fruit.getName(),Toast.LENGTH_SHORT).show();}});holder.fruitImage.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v){int position = holder.getAdapterPosition();Fruit fruit = mFruitList.get(position);Toast.makeText(v.getContext(),\"You clicked image\" + fruit.getName(),Toast.LENGTH_SHORT).show();}});return holder;}@Overridepublic void onBindViewHolder(ViewHolder holder, int position){Fruit fruit = mFruitList.get(position);holder.fruitImage.setImageResource(fruit.getImageId());holder.fruitName.setText(fruit.getName());}@Overridepublic int getItemCount() {return mFruitList.size();}}
点击图片
点击文字