1、分割线:
实现分割线的代码写在一个Activity类中,其中两个内部类重写了ItemDecoration实现分割线效果;
GridDividerItemDecoration:
LinearDividerItemDecoration:
这个类实现类似ListView的分割线效果,支持水平和垂直方向;
package com.longshun.recycleviewdemo;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 自定义RecycleView的ItemDecoration
*/
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.ItemDecoration itemDecoration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.rv);
itemDecoration = new LinearDividerItemDecoration(this, LinearLayoutManager.VERTICAL);
recyclerView.addItemDecoration(itemDecoration);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
final List listStr = new ArrayList<>();
for (int i = 0; i < 29; i++) {
listStr.add("item" + i);
}
final MyAdapter adapter = new MyAdapter(this, listStr);
recyclerView.setAdapter(adapter);
//交互动画
MyItemTouchHelperCallback callback = new MyItemTouchHelperCallback(new MyItemTouchHelperCallback.ItemSwipeListener() {
@Override
public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction) {
//删除数据 更新列表
int position = viewHolder.getAdapterPosition();
listStr.remove(position);
adapter.notifyItemRemoved(position);
}
@Override
public void onItemDrag(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//交换数据 更新列表
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(listStr, fromPosition, toPosition);
adapter.notifyItemMoved(fromPosition, toPosition);
}
});
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
}
public void showLinear(View view) {
recyclerView.removeItemDecoration(itemDecoration);
itemDecoration = new LinearDividerItemDecoration(this, LinearLayoutManager.VERTICAL);
recyclerView.addItemDecoration(itemDecoration);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
}
public void showGrid(View view) {
recyclerView.removeItemDecoration(itemDecoration);
itemDecoration = new GridDividerItemDecoration(this);
recyclerView.addItemDecoration(itemDecoration);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false));
}
/*适用于 RecycleView的GridLayoutManager和StaggerGridLayoutManager*/
class GridDividerItemDecoration extends RecyclerView.ItemDecoration {
private int[] attrs = {android.R.attr.listDivider};
private Drawable mDividerDrawable;
public GridDividerItemDecoration(Context context) {
TypedArray typedArray = context.obtainStyledAttributes(attrs);
this.mDividerDrawable = typedArray.getDrawable(0);
typedArray.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
drawVertical(c, parent);
drawHorizontal(c, parent);
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getLeft() - params.leftMargin;
int top = child.getBottom() + params.bottomMargin;
int right = child.getRight() + params.rightMargin;
int bottom = top + mDividerDrawable.getIntrinsicHeight();
//画下面的线
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
//如果是第一行 那么画上面的线
if (isFirstRow(parent, i)) {
top = child.getTop() - params.topMargin;
bottom = top + mDividerDrawable.getIntrinsicHeight();
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
}
}
}
private void drawVertical(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getRight() + params.rightMargin;
int top = child.getTop() - params.topMargin;
int right = left + mDividerDrawable.getIntrinsicWidth();
int bottom = child.getBottom() + params.bottomMargin;
//画右边的线
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
//如果是第一列 画左边的线
if (isFirstColumn(parent, i)) {
left = child.getLeft() - params.leftMargin;
right = left + mDividerDrawable.getIntrinsicWidth();
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
}
}
}
private boolean isFirstColumn(RecyclerView parent, int position) {
int spanCount = getSpanCount(parent);
return position % spanCount == 0;
}
/*是否是第一行*/
private boolean isFirstRow(RecyclerView parent, int i) {
int spanCount = getSpanCount(parent);
return i <= spanCount - 1;
}
private int getSpanCount(RecyclerView parent) {
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof StaggeredGridLayoutManager) {
return ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof GridLayoutManager) {
return ((GridLayoutManager) layoutManager).getSpanCount();
}
return 0;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(mDividerDrawable.getIntrinsicWidth(), mDividerDrawable.getIntrinsicHeight(), mDividerDrawable.getIntrinsicWidth(), mDividerDrawable.getIntrinsicHeight());
}
}
/*适用于 RecycleView的LineaLayoutManager*/
class LinearDividerItemDecoration extends RecyclerView.ItemDecoration {
private int[] attrs = {android.R.attr.listDivider};
private Drawable mDividerDrawable;
private int mOri;
public LinearDividerItemDecoration(Context context, int ori) {
TypedArray typedArray = context.obtainStyledAttributes(attrs);
mDividerDrawable = typedArray.getDrawable(0);
this.mOri = ori;
typedArray.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOri == LinearLayoutManager.VERTICAL) {
//画水平线 上下左右的每条分割线都看成一个小矩形,绘制每个item的矩形分割线
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getLeft() - params.leftMargin;
int top = child.getBottom() + params.bottomMargin;
int right = child.getRight() + params.rightMargin;
int bottom = top + mDividerDrawable.getIntrinsicHeight();
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
}
} else if (mOri == LinearLayoutManager.HORIZONTAL) {
//画垂直线
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getRight() + params.rightMargin;
int right = left + mDividerDrawable.getIntrinsicWidth();
int top = child.getTop() - params.topMargin;
int bottom = child.getBottom() + params.bottomMargin;
mDividerDrawable.setBounds(left, top, right, bottom);
mDividerDrawable.draw(c);
}
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//获取每个item上下左右四边向外的偏移量 上下左右的每条分割线都看成一个小矩形
if (mOri == LinearLayoutManager.HORIZONTAL) {
outRect.set(0, 0, mDividerDrawable.getIntrinsicWidth(), 0);
} else if (mOri == LinearLayoutManager.VERTICAL) {
outRect.set(0, 0, 0, mDividerDrawable.getIntrinsicHeight());
}
}
}
class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List listStr;
public MyAdapter(Context context, List listStr) {
this.context = context;
this.listStr = listStr;
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
holder.tvStr.setText(listStr.get(position));
}
@Override
public int getItemCount() {
return listStr == null ? 0 : listStr.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvStr;
public MyViewHolder(View itemView) {
super(itemView);
tvStr = (TextView) itemView.findViewById(android.R.id.text1);
}
}
}
}
2、交互动画效果
关键类:ItemTouchHelper,ItemTouchHelper.Callback
//交互动画
MyItemTouchHelperCallback callback = new MyItemTouchHelperCallback(new MyItemTouchHelperCallback.ItemSwipeListener() {
@Override
public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction) {
//删除数据 更新列表
int position = viewHolder.getAdapterPosition();
listStr.remove(position);
adapter.notifyItemRemoved(position);
}
@Override
public void onItemDrag(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//交换数据 更新列表
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(listStr, fromPosition, toPosition);
adapter.notifyItemMoved(fromPosition, toPosition);
}
});
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
package com.longshun.recycleviewdemo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
/**
* Created by longShun on 2017/4/22.
*/
public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
private ItemSwipeListener itemSwipeListener;
public MyItemTouchHelperCallback(ItemSwipeListener itemSwipeListener) {
this.itemSwipeListener = itemSwipeListener;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//设置拖动方向和滑动方向
//上下拖动
int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
//左右滑动
int swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlag, swipeFlag);
}
/*拖拽移动*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if (itemSwipeListener != null) {
itemSwipeListener.onItemDrag(viewHolder, target);
}
return false;
}
/*开启长按拖拽*/
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//滑动事件交给外部处理
if (itemSwipeListener != null) {
itemSwipeListener.onItemSwipe(viewHolder, direction);
}
}
/*在这里做一些动画效果*/
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
//dX 0-> +(-)viewHolder.itemView.getWidth
float alpha= 1 - Math.abs(dX) / viewHolder.itemView.getWidth();
viewHolder.itemView.setAlpha(alpha);
//产生的布局复用问题 可以在这里处理
//item滑出删除,那么透明度变化的item的布局可能会被复用
if(alpha== 0){
//还原布局之前的状态
viewHolder.itemView.setAlpha(1);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
//判断选中状态,拖动和滑动的时候 设置item的背景
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundColor(Color.GRAY);
}
super.onSelectedChanged(viewHolder, actionState);
}
//*这个方法中恢复 item的状态*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
viewHolder.itemView.setBackgroundColor(Color.WHITE);
super.clearView(recyclerView, viewHolder);
}
public interface ItemSwipeListener {
void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction);
void onItemDrag(RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target);
}
}