本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
用RecyclerView实现纵向滚动、横向滚动和瀑布流布局
追忆似水年华 · 4898浏览 · 发布于2019-06-03 +关注

我们知道,ListView只能实现数据纵向滚动的效果,RecyclerView可以说是增强版的List View,不仅可以轻松实现和ListView同样的效果,还优化了ListView的不足之处,目前官方是更加推荐RecyclerView,首先来新建一个RecyclerViewTest项目


一、纵向滚动

首先我们需要在app/build.gradle文件中添加依赖,

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


添加完记得Sync Now,接着修改activity_main.xml,

       


在布局中加入RecyclerView控件是非常简单的,先为RecyclerView指定一个id,然后设置高度和宽度为match_parent,这样会占满整个布局的空间,要注意的是由于RecyclerView并不是内置在系统SDK中的,需要把完整的路径写出来


这里我做的是一个水果的展示,然后建立Fruit.java

package 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

            


接下来我们需要为RecycleView准备一个适配器,新建FruitAdapter.java,让这个适配器继承RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,然后在ViewHolder的构造参数中要传入一个View参数,这个参数通常就是RecyclerView子项的最外层布局,通过findViewById()方法来获取布局中的ImageView和TextView


package com.example.recyclerviewtest;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter {
    private List 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);
    }
}
   // 传入一个构造函数,把数据源传进来,并赋值给全局变量mFruitList
    public FruitAdapter(List fruitList){
        mFruitList = fruitList;
    
}
/**
   *由于FruitAdapter是继承于RecyclerView.Adapter,那么必须重写onCreateViewHolder()、
   *onBindViewHolder()、getItemCount()这3个方法,onCreateViewHolder()用来创建ViewHolder
   *实例,然后把fruit_item布局加载进来,创建一个VIewHolder实例,并把加载进来的布局传入到
   *构造函数中,最后将ViewHolder实例返回。onBindViewHolder()方法是用来对RecyclerView子
   *项中的数据进行赋值,会在每个子项被滚动到屏幕内的时候执行,这里通过positon参数得到当前项
   *的Fruit实例,再将数据设置到ViewHolder的ImageView和TextView当中,getItemCount()用来返回
   *数据源的长度
   **/
@Override
public 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;
}
@Override
public void onBindViewHolder(ViewHolder holder,int position) {
    Fruit fruit = mFruitList.get(position);
    holder.fruitImage.setImageResource(fruit.getImageId());
    holder.fruitName.setText(fruit.getName());
}
@Override
public int getItemCount(){
    return mFruitList.size();
}
}

最后修改MainActivity,在这里用了一个同样的initFruits()方法,用于初始化所有的水果数据,接着在onCreate()方法中获取到RecyclerView实例,然后创建一个LinearLayoutManager对象。LayoutManager用于指定RecyclerView的布局方式,LinearLayoutManager是线性布局的意思,接下来创建FruitAdapter的实例,并将水果数据传入到FruitAdapter的构造函数中,最后调用RecyclerView的setAdapter()方法来完成适配器设置。

package com.example.recyclerviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
    private List fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化水果数据
        initFruits();
        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);
    }
    private void initFruits(){
for (int i = 0; i < 2; i++){
        Fruit apple = new Fruit(
                ("Apple"),R.mipmap.ic_launcher);
        fruitList.add(apple);
        Fruit banner = new Fruit(
                ("Banner"),R.mipmap.ic_launcher);
        fruitList.add(banner);
        Fruit pear = new Fruit(
               ("Pear"),R.mipmap.ic_launcher);
        fruitList.add(pear);
        Fruit watermalon = new Fruit(
               ("Watermalon"),R.mipmap.ic_launcher);
        fruitList.add(watermalon);
        Fruit cherry = new Fruit(
               ("Cherry"),R.mipmap.ic_launcher);
        fruitList.add(cherry);
        }
    }
}


运行一下,可以看到和ListView一样的效果

01.png


二、横向滚动

首先对fruit_item布局进行修改,把元素改为垂直排列

        


这里要设定宽度,因为文字长度不一的话很难看,使用layout_marginTop属性让文字和图片之间保持距离。


接下来修改MainActivity中的代码,因为LinearLayoutManger.HORIZONTAL是默认纵向排列的,我们要设为横向滚动只需要设置为LinearLayoutManager.HORIZONTAL

package com.example.recyclerviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
    private List fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化水果数据
        initFruits();
        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);
    }
    private void initFruits(){
        for (int i = 0; i < 2; i++){
            Fruit apple = new Fruit(
                    ("Apple"),R.mipmap.ic_launcher);
            fruitList.add(apple);
            Fruit banner = new Fruit(
                    ("Banner"),R.mipmap.ic_launcher);
            fruitList.add(banner);
            Fruit pear = new Fruit(
                   ("Pear"),R.mipmap.ic_launcher);
            fruitList.add(pear);
            Fruit watermalon = new Fruit(
                   ("Watermalon"),R.mipmap.ic_launcher);
            fruitList.add(watermalon);
            Fruit cherry = new Fruit(
                   ("Cherry"),R.mipmap.ic_launcher);
            fruitList.add(cherry);
        }
    }
}

02.png

最后运行一下就可以看到横向布局了

当然,GiridLayoutManager可以用于实现网格布局,StaggeredGirdLayoutManager可以实现瀑布流布局


三、瀑布流布局

最后来看看瀑布流布局,首先修改一下fruit_item.xml中的代码


这里我们为了好看把TextView的对齐属性改为居左对齐,因为待会文字会变长

         


接着来修改MainActivity中的代码

package com.example.recyclerviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private List fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //初始化水果数据
    initFruits();
    RecyclerView recyclerView = findViewById(R.id.recycler_view);
/**
*创建StaggeredGridLayoutManager实例,StaggeredGridLayoutManager
*构造函数接收两个参数,第一个参数用于指定布局的列数,表示把布局分为3列,
*第二个参数表示指定布局的排列方向
**/
    StaggeredGridLayoutManager layoutManager = new
            StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
    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(
                getRandomLengthName("Apple"),R.mipmap.ic_launcher);
        fruitList.add(apple);
        Fruit banner = new Fruit
                getRandomLengthName("Banner"),R.mipmap.ic_launcher);
        fruitList.add(banner);
        Fruit pear = new Fruit(
                getRandomLengthName("Pear"),R.mipmap.ic_launcher);
        fruitList.add(pear);
        Fruit watermalon = new Fruit(
               getRandomLengthName("Watermalon"),R.mipmap.ic_launcher);
        fruitList.add(watermalon);
        Fruit cherry = new Fruit(
               getRandomLengthName("Cherry"),R.mipmap.ic_launcher);
        fruitList.add(cherry);
    }
}
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();
}


因为瀑布流布局需要各个子项高度不一致才能看出明显效果,这里使用getRandLengthName()方法把名字随机重复几遍,这样保证各水果的名字长短不一样


最后运行,可以看到效果

03.png



四、设置监听器

当然,我们还可以加上点击事件,不过要注意的是,RecyclerView并没有提供类似于setOnItemClickListener()这样的注册监听器方法,需要我们自己给子项具体的View去注册点击事件


修改FruitAdapter.java

package com.example.recyclerviewtest;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class FruitAdapter extends RecyclerView.Adapter {
    private List 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 fruitList){
    mFruitList = fruitList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    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 = mFruitList.get(position);
            Toast.makeText(v.getContext(),"你点击了文字"+fruit.getName(),
                    Toast.LENGTH_LONG).show();
        }
    });
    holder.fruitImage.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            int position = holder.getAdapterPosition();
            Fruit fruit = mFruitList.get(position);
            Toast.makeText(v.getContext(),"你点击了图片" + fruit.getName(),
                    Toast.LENGTH_LONG).show();
        }
    });
   // ViewHolder holder = new ViewHolder(view);
    return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder,int position) {
    Fruit fruit = mFruitList.get(position);
    holder.fruitImage.setImageResource(fruit.getImageId());
    holder.fruitName.setText(fruit.getName());
}
@Override
public int getItemCount(){
    return mFruitList.size();
}
}


我们在ViewHolder中加入了fruitView变量来保存子项最外层布局的实例,然后在onCreateViewHolder()方法中注册点击事件就可以了


我们会看到,点击文字和点击图片是弹出不同的内容的

04.png


相关推荐

android下vulkan与opengles纹理互通

talkchan · 1158浏览 · 2020-11-23 10:37:39
Android 使用RecyclerView实现轮播图

奔跑的男人 · 2166浏览 · 2019-05-09 17:11:13
微软发布新命令行工具 Windows Terminal

吴振华 · 860浏览 · 2019-05-09 17:15:04
Facebook 停止屏蔽部分区块链广告

· 746浏览 · 2019-05-09 17:20:08
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页