Fresco和 RecyclerView 实现瀑布流 <图片是用本地图片来模拟网络图片的>

本文介绍了如何利用RecyclerView结合Fresco库实现瀑布流布局。主要步骤包括:导入相关库,设置RecyclerView的StaggeredGridLayoutManager,创建带有Fresco SimpleDraweeView的item布局,定义Product实体类存储图片信息,以及自定义ItemDecorator来设置item间的间距。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:http://blog.youkuaiyun.com/Rodulf/article/details/50768220

RecyclerView 实现瀑布流非常的简单,只需要设置布局管理为 StaggeredGridLayoutManager。然后还需要设置ItemDecorator

代码:瀑布流代码模拟网络图片

图片:瀑布流的图片


1:大概的步骤如下.具体的步骤在下面的下面.

0:导入RecyclerView,Fresco

1:布局里面添加RecyclerView,

2:创建item的布局,这个布局可以使用Fresco的SimpleDrawweView,记住要在Application里面进行初始化。

3:创建Product的实体类,这个里面包含了四个变量,图片地址,图片名称,图片的宽度,图片的高度。

4:创建 Adatper, PicRecyclerViewAdapter,在这个PicRecyclerViewAdapter里面首先要创建PicViewHolder继承RecyclerView.ViewHolder,这个ViewHolder必须要先创建,因为下面继承RecyclerView.Adapter里面要用到
5:让我们的adpter,PicRecyclerViewAdapter继承RecyclerView.Adatper, extends RecyclerView.Adapter<PicRecyclerViewAdapter.PicViewHolder>
继承里面的方法,包括onCreateViewHolder,和onBindViewHolder。

public PicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View ret = LayoutInflater.from(context).inflate(R.layout.item_recyclerview,parent,false);
        return new PicViewHolder(ret);
    }

//瀑布流里面,我们会从服务器得到宽度和高度,然后通过这个设置宽高比。
    @Override
    public void onBindViewHolder(PicViewHolder holder, int position) {
        Product product = list.get(position);
        holder.pic.setImageURI(Uri.parse(product.getLocalPosition()));
        holder.textView.setText(product.getProductName());
    }

6:创建每一个Item之间的间隔 通过创建一个继承了ItemDecorator的类来做,里面有getItemOffSet方法。来设置上下左右的距离

7:通过代码设置布局管理和adapter,以及一些模拟数据。
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //添加间隔,Decorator 的翻译就是装饰师,粉刷匠
        MyItemDecorator myItemDecorator = new MyItemDecorator(10);
        mRecyclerView.addItemDecoration(myItemDecorator);
        mRecyclerView.setAdapter(adapter);


2:具体的步骤:

0:导入RecyclerView,Fresco

1:布局里面添加RecyclerView,

<?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:layout_width="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerview"></android.support.v7.widget.RecyclerView>
</RelativeLayout>

2:创建item的布局,这个布局可以使用Fresco的SimpleDrawweView,记住要在Application里面进行初始化。

千万记住了SimpleDraweeView不能是全部的wrap_content

<?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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent">
<com.facebook.drawee.view.SimpleDraweeView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/item_simpleDraweeView"
    app:placeholderImage="@mipmap/ic_launcher"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/item_name"/>
</LinearLayout>
创建MyApplication
package tech.androidstudio.recyclerviewdemo;

import android.app.Application;

import com.facebook.drawee.backends.pipeline.Fresco;

/**
 * Created by Kodulf on 2016/3/15.
 */
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this);
    }
}

在清单文件中修改:
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:name=".MyApplication">

 

3:创建Product的实体类,这个里面包含了四个变量,图片地址,图片名称,图片的宽度,图片的高度。

package tech.androidstudio.recyclerviewdemo;

/**
 * Created by Kodulf on 2016/3/15.
 */
public class Product {
    private String localPosition;
    private String productName;
    private int width;
    private int height;

    public Product(String localPosition, String productName, int width, int height) {
        this.localPosition = localPosition;
        this.productName = productName;
        this.width = width;
        this.height = height;
    }

    public int getWidth() {

        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public Product(String localPosition, String productName) {
        this.localPosition = localPosition;
        this.productName = productName;
    }

    public Product() {
    }

    public String getLocalPosition() {

        return localPosition;
    }

    public void setLocalPosition(String localPosition) {
        this.localPosition = localPosition;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }
}

4:创建 Adatper, PicRecyclerViewAdapter,在这个PicRecyclerViewAdapter里面首先要创建PicViewHolder继承RecyclerView.ViewHolder,这个ViewHolder必须要先创建,因为下面继承RecyclerView.Adapter里面要用到

//必须 首先写这个 ViewHolder,因为只有这样才能写里面的参数,
    // 然后才是写继承的 extends RecyclerView.Adapter<PicViewHolder>
    public class PicViewHolder extends RecyclerView.ViewHolder{

            SimpleDraweeView pic;
            TextView textView;

        public PicViewHolder(View itemView) {
            super(itemView);
            pic=(SimpleDraweeView)itemView.findViewById(R.id.item_simpleDraweeView);
//            pic.setAspectRatio(0.9f);
            pic.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
            textView=(TextView)itemView.findViewById(R.id.item_name);
        }

    }
5:让我们的adpter,PicRecyclerViewAdapter继承RecyclerView.Adatper, extends RecyclerView.Adapter<PicRecyclerViewAdapter.PicViewHolder>
继承里面的方法,包括onCreateViewHolder,和onBindViewHolder。

public PicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View ret = LayoutInflater.from(context).inflate(R.layout.item_recyclerview,parent,false);
        return new PicViewHolder(ret);
    }

//瀑布流里面,我们会从服务器得到宽度和高度,然后通过这个设置宽高比。
    @Override
    public void onBindViewHolder(PicViewHolder holder, int position) {
        Product product = list.get(position);
        holder.pic.setImageURI(Uri.parse(product.getLocalPosition()));
        holder.textView.setText(product.getProductName());
    }



package tech.androidstudio.recyclerviewdemo.adapter;
import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.view.SimpleDraweeView;

import java.util.Collection;
import java.util.List;

import tech.androidstudio.recyclerviewdemo.Product;
import tech.androidstudio.recyclerviewdemo.R;

/**
 * Created by Kodulf on 2016/3/15.
 */

//注意 这里 集成的 RecyclerView.Adapter
public class PicRecyclerViewAdapter extends RecyclerView.Adapter<PicRecyclerViewAdapter.PicViewHolder> {
    List<Product> list;
    Context context;
    public PicRecyclerViewAdapter(List<Product> list,Context context) {
        this.list = list;
        this.context=context;
    }

    @Override
    public PicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View ret = LayoutInflater.from(context).inflate(R.layout.item_recyclerview,parent,false);
        return new PicViewHolder(ret);

        //TODO 下面的 返回方法是错误的,如果这样做的话,会报错
        //TODO java.lang.NullPointerException: Attempt to invoke virtual method 'void com.facebook.drawee.view.SimpleDraweeView.setImageURI(android.net.Uri)' on a null object reference

        //PicViewHolder picViewHolder = new PicViewHolder(parent);
        //return picViewHolder;
        //return null;
    }

    @Override
    public void onBindViewHolder(PicViewHolder holder, int position) {
        Log.d("Kodulf", "position" + position + " Uri:");
        Product product = list.get(position);
        //获取图片的宽高信息,然后得到宽高比 ,然后通过FrescoSimpleDraweeViewsetAspectRatio来设置
        float ratio = (float)product.getWidth() / (float)product.getHeight();
        holder.pic.setAspectRatio(ratio);
        holder.pic.setImageURI(Uri.parse(product.getLocalPosition()));

        Log.d("Kodulf", "Width=" + product.getWidth());
        Log.d("Kodulf", "Height=" +product.getHeight());
        Log.d("Kodulf","Ratio="+ratio);
        holder.textView.setText(product.getProductName());
    }

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

    //以后添加更新数据的时候会用到addAll的方法
    public void addAll(Collection<? extends Product> collection){

        int size = list.size();
        list.addAll(collection);
        notifyItemRangeChanged(size, collection.size());
    }


    //必须 首先写这个 ViewHolder,因为只有这样才能写里面的参数,
    // 然后才是写继承的 extends RecyclerView.Adapter<PicViewHolder>
    public class PicViewHolder extends RecyclerView.ViewHolder{

            SimpleDraweeView pic;
            TextView textView;

        public PicViewHolder(View itemView) {
            super(itemView);
            pic=(SimpleDraweeView)itemView.findViewById(R.id.item_simpleDraweeView);
//            pic.setAspectRatio(0.9f);
            pic.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY);
            textView=(TextView)itemView.findViewById(R.id.item_name);
        }

    }
}





6:创建每一个Item之间的间隔 通过创建一个继承了ItemDecorator的类来做,里面有getItemOffSet方法。来设置上下左右的距离
package tech.androidstudio.recyclerviewdemo;

import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by Kodulf on 2016/3/15.
 */
//Decorator 的翻译就是装饰师,粉刷匠
public class MyItemDecorator extends RecyclerView.ItemDecoration {
    private int space;

    public MyItemDecorator(int space) {
        this.space = space;
    }

    //自定义item之间的距离,如果是第一个的话就没有距离,
    //设置上下左右的距离
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//        super.getItemOffsets(outRect, view, parent, state);
        outRect.bottom=space;
        outRect.right=space;
        outRect.left=space;
        if(parent.getChildPosition(view)!=0){
            outRect.top=space;
        }
    }
}



7:通过代码设置布局管理和adapter,以及一些模拟数据。
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //添加间隔,Decorator 的翻译就是装饰师,粉刷匠
        MyItemDecorator myItemDecorator = new MyItemDecorator(10);
        mRecyclerView.addItemDecoration(myItemDecorator);
        mRecyclerView.setAdapter(adapter);


package tech.androidstudio.recyclerviewdemo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;

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

import tech.androidstudio.recyclerviewdemo.adapter.PicRecyclerViewAdapter;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

/**
        List<String> listUrl = new ArrayList<String>();
        listUrl.add("http://fdfs.xmcdn.com/group16/M08/F1/13/wKgDbFal40bR7Uc6AAH3JpWhLiQ015_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group10/M07/F0/14/wKgDaVal9ZLTP5q1AAFIJeYaktQ092_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group12/M07/E8/35/wKgDXFacqEfReClFAAFvbZHe_mU331_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group9/M05/EE/15/wKgDZlagtF_yH9YXAAEyq6YSxDo657_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group11/M07/FC/B4/wKgDbValyzzy0fBpAAMdsEAuI-Q295_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group9/M01/EF/02/wKgDZlaiCqbTzvIzAAH_l7MCT-k503_android_large.jpg");
        listUrl.add("http://fdfs.xmcdn.com/group9/M01/EF/02/wKgDZlaiCqbTzvIzAAH_l7MCT-k503_android_large.jpg");
        List<Product> mList = new ArrayList<Product>();
        for(int i=0;i<7;i++){
            Product product = new Product();
//            product.setLocalPosition("res://mipmap/"+i+".png");
            product.setLocalPosition(listUrl.get(i));
            product.setProductName("Picture "+i);
            mList.add(product);
        }

*/

        //模拟数据,这里需要获取图片的宽高 ,一般的在我们从服务器请求数据的 时候 它会返回图片的 宽高信息
        Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.p1);
        Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.mipmap.p2);
        Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.mipmap.p3);
        Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.mipmap.p4);
        Bitmap bitmap5 = BitmapFactory.decodeResource(getResources(), R.mipmap.p5);
        Bitmap bitmap6 = BitmapFactory.decodeResource(getResources(), R.mipmap.p6);
        Bitmap bitmap7 = BitmapFactory.decodeResource(getResources(), R.mipmap.p7);

        List<Product> mList = new ArrayList<Product>();
        Product product1 = new Product("res://mipmap/"+R.mipmap.p1,"Picture 1",bitmap1.getWidth(),bitmap1.getHeight());
        Product product2 = new Product("res://mipmap/"+R.mipmap.p2,"Picture 2",bitmap2.getWidth(),bitmap2.getHeight());
        Product product3 = new Product("res://mipmap/"+R.mipmap.p3,"Picture 3",bitmap3.getWidth(),bitmap3.getHeight());
        Product product4 = new Product("res://mipmap/"+R.mipmap.p4,"Picture 4",bitmap4.getWidth(),bitmap4.getHeight());
        Product product5 = new Product("res://mipmap/"+R.mipmap.p5,"Picture 5",bitmap5.getWidth(),bitmap5.getHeight());
        Product product6 = new Product("res://mipmap/"+R.mipmap.p6,"Picture 6",bitmap6.getWidth(),bitmap6.getHeight());
        Product product7 = new Product("res://mipmap/"+R.mipmap.p7,"Picture 7",bitmap7.getWidth(),bitmap7.getHeight());
        mList.add(product1);
        mList.add(product2);
        mList.add(product3);
        mList.add(product4);
        mList.add(product5);
        mList.add(product6);
        mList.add(product7);


        mRecyclerView = (RecyclerView)findViewById(R.id.recyclerview);
        PicRecyclerViewAdapter adapter = new PicRecyclerViewAdapter(mList,this);
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //添加间隔,Decorator 的翻译就是装饰师,粉刷匠
        MyItemDecorator myItemDecorator = new MyItemDecorator(10);
        mRecyclerView.addItemDecoration(myItemDecorator);

        mRecyclerView.setAdapter(adapter);
    }
}




7:通过代码设置布局管理和adapter,以及一些模拟数据。
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        //添加间隔,Decorator 的翻译就是装饰师,粉刷匠
        MyItemDecorator myItemDecorator = new MyItemDecorator(10);
        mRecyclerView.addItemDecoration(myItemDecorator);
        mRecyclerView.setAdapter(adapter);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值