Fresco和 RecyclerView 實現瀑布流
阿新 • • 發佈:2019-01-30
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方法。來設定上下左右的距離
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" android2:建立item的佈局,這個佈局可以使用Fresco的SimpleDrawweView,記住要在Application裡面進行初始化。: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>
千萬記住了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); } }
7:通過程式碼設定佈局管理和adapter,以及一些模擬資料。
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
//新增間隔,Decorator 的翻譯就是裝飾師,粉刷匠
MyItemDecorator myItemDecorator = new MyItemDecorator(10);
mRecyclerView.addItemDecoration(myItemDecorator);
mRecyclerView.setAdapter(adapter);