参考: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); //获取图片的宽高信息,然后得到宽高比 ,然后通过Fresco的SimpleDraweeView的setAspectRatio来设置 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); } }
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
//添加间隔,Decorator 的翻译就是装饰师,粉刷匠
MyItemDecorator myItemDecorator = new MyItemDecorator(10);
mRecyclerView.addItemDecoration(myItemDecorator);
mRecyclerView.setAdapter(adapter);