RecyclerView 已經出現有一年多了,看過的和沒看過的都需要了解一下。
據官方的介紹,該控件用于在有限的視窗中展示大量資料集,其實這樣功能的控件我們并不陌生,例如:ListView、GridView。
使用RecyclerView取代以往使用的ListView、GridView,使用SwipeRefreshLayout取代pull-to-refresh第三方庫,打造更符合Material Design風格的APP。
開始之前,我們需要先導入這個。
Android Studio 在build 中加入
compile 'com.android.support:recyclerview-v7:+'
Eclipse 直接導入support-v7就可以了。
為了簡單直接上Demo 代碼:
首先上layout 布局檔案:
由于需要用到下拉重新整理,為了簡單還是使用官方的元件:
android.support.v4.widget.SwipeRefreshLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.recyclerview.demo.MainActivity">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swiperefresh_layout"
>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"
>
那麼接下來就需要編寫ITEM了
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:id="@+id/photo_item_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
android:id="@+id/photo_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
OK,既然做瀑布流,最流行的的那就是圖檔瀑布了。 我們先從Windows 中拷貝幾張圖檔到項目中去。
完成這步,那就可以着手編寫代碼了。
和ListView 一樣,既然使用相對複雜的東西,那麼就需要重寫擴充卡。 這裡先不考慮他的點選事件。後面教程将會說到點選事件
public class MyAdapter extends RecyclerView.Adapter {
//定義資料模型
private List products;
private MyItemClickListener mItemClickListener;
//構造方法
public MyAdapter(List list) {
products=list;
}
public void setOnItemClickListener(MyItemClickListener listener){
this.mItemClickListener = listener;
}
//建立每一條小牧
@Override
public PhotoView onCreateViewHolder(ViewGroup viewGroup, int i) {
//加載布局
View view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.photo_item, viewGroup, false);
return new PhotoView(view,mItemClickListener);
}
//banding資料的資料模型
@Override
public void onBindViewHolder(final PhotoView photoView, int position) {
photoView.imageView.setImageResource(products.get(position).getImage());
photoView.titleView.setText(products.get(position).getTitle());
}
//擷取資料的大小
@Override
public int getItemCount() {
return products.size();
}
//增加一項
public void addData(int position,Photo photo) {
products.add(position,photo);
notifyItemInserted(position);
}
//删除一項
public void removeData(int position) {
products.remove(position);
notifyItemRemoved(position);
}
}
哔哔
再繼續将實體類型添加進去,讓擴充卡與實體進行判定。由于是模拟資料,那麼我們就用本地的圖檔代替。是以實體為int 的圖檔ID
public class Photo {
private int image;
private String title;
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Photo(int image, String title) {
this.image = image;
this.title = title;
}
}
OK,編寫到這裡,那麼我們需要思考的是如何去實作這個瀑布的效果。
Recyclerview 提供了三個布局管理器。
LinearLayoutManager 水準或者垂直的Item視圖。
GridLayoutManager 網格Item視圖。
StaggeredGridLayoutManager 交錯的網格Item視圖。
這三個布局管理可以根據業務需求的不同設定不同的管理器,這裡我們将使用
StaggeredGridLayoutManager 來實作 瀑布流的效果 。
public class MainActivity extends AppCompatActivity {
private final int[] imageRes = new int []{
R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4,R.drawable.p5,R.drawable.p6,R.drawable.p7,R.drawable.p8
};
private MyAdapter myAdapter;
private SwipeRefreshLayout mSwipeRefreshLayout;
private RecyclerView recyclerView;
private StaggeredGridLayoutManager mStaggerdGridLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler_view);
mStaggerdGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//設定layoutManager
recyclerView.setLayoutManager(mStaggerdGridLayoutManager);
myAdapter = new MyAdapter(new ArrayList());
recyclerView.setAdapter(myAdapter);
//設定item之間的間隔
SpacesItemDecoration decoration=new SpacesItemDecoration(2);
recyclerView.addItemDecoration(decoration);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh_layout);
mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.BLUE);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// new MoreArticleTask().execute(mAdapter.getTopArticleId());
Toast.makeText(getApplicationContext(),"重新整理",Toast.LENGTH_SHORT).show();
for(int i = 0 ; i < myAdapter.getItemCount() ;i ++) {
myAdapter.removeData(i);
}
refreshing();
mSwipeRefreshLayout.setRefreshing(false);
}
});
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
refreshing();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
//用于重新整理的方法 主要使用擴充卡中addData 方法
private void refreshing(){
for(int i = 0 ; i < imageRes.length; i++){
Photo photo = new Photo(imageRes[(int)(Math.random()*imageRes.length)],"這是第"+(int)(Math.random()*imageRes.length)+":"+i+"張圖檔");
myAdapter.addData(i,photo);
}
}
private void loadMore(){
}
}
其中我們為了實作 瀑布流的需要設定下劃線 也就是空隙:
//設定item之間的間隔
SpacesItemDecoration decoration=new SpacesItemDecoration(2);
recyclerView.addItemDecoration(decoration);
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space=space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.left=space;
outRect.right=space;
outRect.bottom=space;
if(parent.getChildAdapterPosition(view)==0){
outRect.top=space;
}
}
}
OK ,那麼實作線性布局 可以直接這樣寫
//設定layoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Demo :下載下傳位址
最後效果圖
