RecyclerView的簡單使用以及實現瀑布流效果
阿新 • • 發佈:2019-01-01
RecyclerView
簡介
RecyclerView是support.v7包中的控制元件,可以認為是ListView和GridView的增強版,RecyclerView提供了一個耦合度更低的方式來複用ViewHolder,可以更輕鬆的實現瀑布流的效果,為增加和刪除條目提供了預設的動畫效果.
目前SDK中提供了三種自帶的LayoutManager:(LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager)
簡單使用
1:新增依賴
在AS的build.gradle
中新增依賴,然後同步一下就可以引入依賴包:
compile 'com.android.support:recyclerview-v7:23.1.0'
2:編寫程式碼
先寫好佈局檔案
在其對應Activity中獲取RecycleView,宣告好佈局管理器,Adapter,初始化資料,以及設定分割線等...<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_recycle_view" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycleView" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </RelativeLayout>
接下來設定Adapterpackage com.goblin.esx.gridlist.activity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.OrientationHelper; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Toast; import com.goblin.esx.gridlist.MyItemDecoration; import com.goblin.esx.gridlist.R; import com.goblin.esx.gridlist.adapter.MyRecyclerViewAdapter; import java.util.ArrayList; import java.util.List; public class RecyclerViewActivity extends AppCompatActivity { private RecyclerView recyclerView; //標題的集合 private List<String> title = new ArrayList<>(); //內容的集合 private List<String> content = new ArrayList<>(); private int NUMBER = 40; private MyRecyclerViewAdapter myRecyclerViewAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recycle_view); recyclerView = (RecyclerView) findViewById(R.id.recycleView); //初始化資料 initData(); // LinearLayoutManager layoutManager = new LinearLayoutManager(this); //實現網格效果的佈局管理器 GridLayoutManager layoutManager=new GridLayoutManager(this,3); //設定佈局管理器 recyclerView.setLayoutManager(layoutManager); //設定為垂直佈局,這是預設的 layoutManager.setOrientation(OrientationHelper.VERTICAL); // layoutManager.setOrientation(OrientationHelper.HORIZONTAL); myRecyclerViewAdapter = new MyRecyclerViewAdapter(RecyclerViewActivity.this, title, content); //設定點選事件 myRecyclerViewAdapter.setOnMyItemClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { Toast.makeText(RecyclerViewActivity.this, "您點選咯---->"+v.getTag(), Toast.LENGTH_SHORT).show(); } }); recyclerView.setAdapter(myRecyclerViewAdapter); //設定分隔線 recyclerView.addItemDecoration(new MyItemDecoration(this)); } private void initData() { for (int i = 0; i < NUMBER; i++) { title.add("標題" + i); content.add("內容" + i); } } }
package com.goblin.esx.gridlist.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.goblin.esx.gridlist.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017-3-20.
*/
public class MyRecyclerViewAdapter extends RecyclerView.Adapter {
//標題的集合
private List<String> title = new ArrayList<>();
//內容的集合
private List<String> content = new ArrayList<>();
private Context context;
public MyRecyclerViewAdapter(Context context, List<String> title, List<String> content) {
this.title = title;
this.content = content;
this.context = context;
}
//建立ChildView
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.item_list_adapter, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//將資料繫結到每一個childView中
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder myHolder = (ViewHolder) holder;
myHolder.ivLeft.setImageResource(R.drawable.goblin);
myHolder.tvTitle.setText(title.get(position));
myHolder.tvContent.setText(content.get(position));
//設定標記
myHolder.itemView.setTag(title.get(position));
myHolder.itemView.setOnClickListener(listener);
}
private View.OnClickListener listener;
public void setOnMyItemClickListener(View.OnClickListener listener) {
this.listener = listener;
}
//得到child的數量
@Override
public int getItemCount() {
return title.size();
}
// 通過holder的方式來初始化每一個ChildView的內容
static class ViewHolder extends RecyclerView.ViewHolder {
private ImageView ivLeft;
private TextView tvTitle;
private TextView tvContent;
public ViewHolder(View itemView) {
super(itemView);
ivLeft = (ImageView) itemView.findViewById(R.id.iv_left);
tvTitle = (TextView) itemView.findViewById(R.id.tv_title);
tvContent = (TextView) itemView.findViewById(R.id.tv_content);
}
}
}
最後設定分割線,這樣簡單的RecyclerView就實現咯
package com.goblin.esx.gridlist;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by Administrator on 2017-3-20.
*/
public class MyItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDividerDarwable;
private int mDividerHight = 1;
private Paint mColorPaint;
public final int[] ATRRS = new int[]{android.R.attr.listDivider};
public MyItemDecoration(Context context) {
final TypedArray ta = context.obtainStyledAttributes(ATRRS);
this.mDividerDarwable = ta.getDrawable(0);
ta.recycle();
}
/*
int dividerHight 分割線的線寬
int dividerColor 分割線的顏色
*/
public MyItemDecoration(Context context, int dividerHight, int dividerColor) {
this(context);
mDividerHight = dividerHight;
mColorPaint = new Paint();
mColorPaint.setColor(dividerColor);
}
/*
int dividerHight 分割線的線寬
Drawable dividerDrawable 圖片分割線
*/
public MyItemDecoration(Context context, int dividerHight, Drawable dividerDrawable) {
this(context);
mDividerHight = dividerHight;
mDividerDarwable = dividerDrawable;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
//畫水平和垂直分割線
drawHorizontalDivider(c, parent);
drawVerticalDivider(c, parent);
}
public void drawVerticalDivider(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getTop() - params.topMargin;
final int bottom = child.getBottom() + params.bottomMargin;
int left = 0;
int right = 0;
//左邊第一列
if ((i % 3) == 0) {
//item左邊分割線
left = child.getLeft();
right = left + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
//item右邊分割線
left = child.getRight() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
} else {
//非左邊第一列
left = child.getRight() + params.rightMargin - mDividerHight;
right = left + mDividerHight;
}
//畫分割線
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
}
}
public void drawHorizontalDivider(Canvas c, RecyclerView parent) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - params.leftMargin - mDividerHight;
final int right = child.getRight() + params.rightMargin;
int top = 0;
int bottom = 0;
// 最上面一行
if ((i / 3) == 0) {
//當前item最上面的分割線
top = child.getTop();
//當前item下面的分割線
bottom = top + mDividerHight;
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
top = child.getBottom() + params.bottomMargin;
bottom = top + mDividerHight;
} else {
top = child.getBottom() + params.bottomMargin;
bottom = top + mDividerHight;
}
//畫分割線
mDividerDarwable.setBounds(left, top, right, bottom);
mDividerDarwable.draw(c);
if (mColorPaint != null) {
c.drawRect(left, top, right, bottom, mColorPaint);
}
}
}
}
高階使用
RecyclerView實現瀑布流,以及RecyclerView增加和刪除條目
設定佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle_view" android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<ImageView
android:id="@+id/iv_add" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_margin="10dp"
android:background="@drawable/selector_iv_add"/>
</RelativeLayout>
設定Adapter
package com.goblin.esx.gridlist.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.goblin.esx.gridlist.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017-3-20.
*/
public class MyRecycleSaultAdapter extends RecyclerView.Adapter {
private Context context;
private List<Integer> list = new ArrayList<>();
private List<Integer> mHeights;
public MyRecycleSaultAdapter(Context context, List<Integer> list) {
this.context = context;
this.list = list;
mHeights = new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.item_recycle_adapter, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ViewHolder myHolder = (ViewHolder) holder;
// 隨機高度, 模擬瀑布效果.
if (mHeights.size() <= position) {
mHeights.add((int) (300 + Math.random() * 100));
}
ViewGroup.LayoutParams lp = myHolder.ivImage.getLayoutParams();
lp.height = mHeights.get(position);
myHolder.ivImage.setLayoutParams(lp);
Integer ivId = list.get(position);
myHolder.ivImage.setImageResource(ivId);
//設定標記
myHolder.itemView.setTag(position);
myHolder.itemView.setOnClickListener(listener);
myHolder.itemView.setOnLongClickListener(longListener);
}
//點選事件
private View.OnClickListener listener;
public void setOnMyItemClickListener(View.OnClickListener listener) {
this.listener = listener;
}
//長按事件
private View.OnLongClickListener longListener;
public void setOnMyItemLongClickListener(View.OnLongClickListener longListener) {
this.longListener = longListener;
}
@Override
public int getItemCount() {
return list.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView ivImage;
public ViewHolder(View itemView) {
super(itemView);
ivImage = (ImageView) itemView.findViewById(R.id.iv_image);
}
}
//向集合中新增資料
public void addList(int position) {
list.add(position, R.drawable.x);
notifyItemInserted(position);
}
//移除集合中的資料
public void removeList(int position) {
list.remove(position);
notifyItemRemoved(position);
}
}
Activity裡面設定點選事件,長按刪除事件等......
package com.goblin.esx.gridlist.activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import com.goblin.esx.gridlist.MyItemDecoration;
import com.goblin.esx.gridlist.R;
import com.goblin.esx.gridlist.adapter.MyRecycleSaultAdapter;
import java.util.ArrayList;
import java.util.List;
public class RecyclerSaultActivity extends AppCompatActivity {
private RecyclerView recycleView;
private MyRecycleSaultAdapter myRecycleAdapter;
private List<Integer> list = new ArrayList<>();
private int NUMBER = 20;
private ImageView ivAdd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
ivAdd = (ImageView) findViewById(R.id.iv_add);
//初始化資料
initData();
recycleView = (RecyclerView) findViewById(R.id.recycle_view);
myRecycleAdapter = new MyRecycleSaultAdapter(this, list);
// 錯列網格佈局
recycleView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager
.VERTICAL));
//設定間距
recycleView.addItemDecoration(new SpacesItemDecoration(8));
recycleView.setItemAnimator(new DefaultItemAnimator());
recycleView.setAdapter(myRecycleAdapter);
//設定分隔線
recycleView.addItemDecoration(new MyItemDecoration(this));
//新增的點選事件
ivAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(RecyclerSaultActivity.this, "您新增咯一張圖片", Toast.LENGTH_SHORT).show();
myRecycleAdapter.addList(1);
}
});
//點選事件
myRecycleAdapter.setOnMyItemClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(RecyclerSaultActivity.this, "您點選咯"+v.getTag(), Toast.LENGTH_SHORT).show();
}
});
//長按事件(刪除)
myRecycleAdapter.setOnMyItemLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
myRecycleAdapter.removeList(1);
Toast.makeText(RecyclerSaultActivity.this, "您刪除咯一張圖片"+v.getTag(), Toast.LENGTH_SHORT).show();
//不返回true,鬆手還會去執行單擊事件
return true;
}
});
}
private void initData() {
for (int i = 0; i < NUMBER; i++) {
list.add(R.drawable.a);
list.add(R.drawable.b);
list.add(R.drawable.c);
list.add(R.drawable.d);
list.add(R.drawable.e);
list.add(R.drawable.f);
list.add(R.drawable.g);
}
}
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;
} else if (parent.getChildAdapterPosition(view) == 5) {
outRect.top = space * 2;
}
}
}
}
圖片的佈局檔案
<?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"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:background="@drawable/a"
android:gravity="center" />
</LinearLayout>
給新增的圖片按鈕設定狀態選擇器
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/add"/>
<item android:drawable="@drawable/add_pressed"/>
</selector>