以前一直使用ListView,普通需求使用算是简单,现在使用RecyckerView能够更强大的简化使用,来满足更多需求。
- 纵向滑动 横向滑动(线性、格子、瀑布流)
// ListView形式上下滑动:
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
// 左右滑动:
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.HORIZONTAL);
// Grid形式上下滑动:
GridLayoutManager manager = new GridLayoutManager(this,4);
// Grid形式左右滑动:
GridLayoutManager manager = new GridLayoutManager(this, 4);
manager.setOrientation(GridLayoutManager.HORIZONTAL);
// 瀑布流形式上下滑动:
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL);
// 瀑布流形式左右滑动:
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL);
2、Adapter 适配器(触发响应事件)(RecyclerView动画展示)
public class RecyclerView1Adapter extends RecyclerView.Adapter<RecyclerView1Adapter.MyViewHolder> {
private List<String> mData;
private Context mContext;
private boolean flag;
private int mLastPosition;
public RecyclerView1Adapter(List<String> mData, Context mContext) {
this.mData = mData;
this.mContext = mContext;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recy_view_item_tv,parent,false);
final MyViewHolder holder = new MyViewHolder(view);
Log.e("chenxh","onCreateViewHolder");
holder.addBtn.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
new AlertDialog.Builder(v.getContext())
.setTitle("确认删除吗")
.setNegativeButton("取消",null)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (flag == true){
removeData(holder.getAdapterPosition());
flag=false;
}else{
addData(holder.getAdapterPosition());
flag=true;
}
}
}).show();
return false;
}
});
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tv1.setText(mData.get(position));
Log.e("chenxh","onBindViewHolder"+position);
holder.tv1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext, mData.get(position), Toast.LENGTH_SHORT).show();
}
});
//动画核心
if (holder.getAdapterPosition() > mLastPosition) {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(holder.itemView, "scaleX", 0.5f, 1f);
scaleX.start();
mLastPosition = holder.getLayoutPosition();
}
}
/**
* getItemViewType()
* 多布局 核心方法 getItemViewType
* 1、onCreateViewHolder中判断 == viewType 进行viewHolder的填充
* 2、onBindViewHolder中判断 instanceof viewHolder
* @param position
* @return viewType(){Integer}
*/
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getItemCount() {
return mData.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
Button addBtn,removeBtn;
TextView tv1;
public MyViewHolder(View itemView) {
super(itemView);
tv1 = (TextView) itemView.findViewById(R.id.recy_view_item_tv1);
addBtn = (Button) itemView.findViewById(R.id.recy_view_item_btn1);
}
}
// 添加数据
public void addData(int position) {
mData.add(position,"addData"+position);
notifyItemInserted(position);
}
// 删除数据
public void removeData(int position) {
mData.remove(position);
notifyItemRemoved(position);
}
}
//添加默认的动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
3、刷新数据
runOnUiThread(new Runnable() {
@Override
public void run() {
//数据更新
initmData();
//Adapter更新RecyclerView
adapter.notifyDataSetChanged();
}
});
4、添加线性的分割线
mRecyclerView.addItemDecoration(new MyDividerItemDecoration(this, MyDividerItemDecoration.VERTICAL_LIST));
分割线类:
public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private int mOrientation;
private Drawable mDivider;
private int mDividerHeight = 2; //默认是2px
private Paint mPaint;
//绘制默认分割线
public MyDividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
//系统属性中获取
a.recycle();
setOrientation(orientation);
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public MyDividerItemDecoration(Context context, int orientation, int drawableId) {
this(context, orientation);
mDivider = ContextCompat.getDrawable(context, drawableId);
mDividerHeight = mDivider.getIntrinsicHeight();
}
/**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public MyDividerItemDecoration(Context context, int orientation, int dividerHeight, int dividerColor) {
this(context, orientation);
mDividerHeight = dividerHeight;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
}
private void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientaion");
}
mOrientation = orientation;
}
@Override
//在RecyclerView的onDraw中执行
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount-1; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount-1; i++) {
final View child = parent.getChildAt(i);
RecyclerView v = new RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDividerHeight);
} else {
outRect.set(0, 0, mDividerHeight, 0);
}
}
}
5、多布局三步走
①:Adapter中重写getItemViewType方法
@Override
public int getItemViewType(int position) {
if (mNewsBeanList.get(position).getThumbnail_pic_s03() == null) {
return IMAGE_ONLY_ONE;
} else {
return IMAGE_TWOORTHREE;
}
}
②:在onCreateViewHolder方法中第二个参数对应的就是上面方法返回的值,我们根据值的不同,填充不同的布局
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == IMAGE_TWOORTHREE) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_imagethree_item, viewGroup, false);
ImageThreeViewHolder viewHolder = new ImageThreeViewHolder(view);
return viewHolder;
} else {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_imageonly_item, viewGroup, false);
ImageOnlyOneViewHolder viewHolder = new ImageOnlyOneViewHolder(view);
return viewHolder;
}
}
③: 不同的布局需要不同的ViewHolder,在onBindViewHolder方法中的第一个参数对应不同的viewholder,我们通过判断,来进行每个元素的写入
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof ImageThreeViewHolder) {
((ImageThreeViewHolder) viewHolder).mTv_title.setText(mNewsBeanList.get(position).getTitle());
}
}
6、添加Grid的分割线
mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration{
private static final int[] ATTRS = new int[] { android.R.attr.listDivider };
private Drawable mDivider;
public DividerGridItemDecoration(Context context){
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
{
drawHorizontal(c, parent);
drawVertical(c, parent);
}
private int getSpanCount(RecyclerView parent)
{
// 列数
int spanCount = -1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
spanCount = ((StaggeredGridLayoutManager) layoutManager)
.getSpanCount();
}
return spanCount;
}
public void drawHorizontal(Canvas c, RecyclerView parent)
{
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 left = child.getLeft() - params.leftMargin;
final int right = child.getRight() + params.rightMargin
+ mDivider.getIntrinsicWidth();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawVertical(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;
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
if (orientation == StaggeredGridLayoutManager.VERTICAL)
{
if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边
{
return true;
}
} else
{
childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一列,则不需要绘制右边
return true;
}
}
return false;
}
private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount)
{
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager)
{
childCount = childCount - childCount % spanCount;
if (pos >= childCount)// 如果是最后一行,则不需要绘制底部
return true;
} else if (layoutManager instanceof StaggeredGridLayoutManager)
{
int orientation = ((StaggeredGridLayoutManager) layoutManager)
.getOrientation();
// StaggeredGridLayoutManager 且纵向滚动
if (orientation == StaggeredGridLayoutManager.VERTICAL)
{
childCount = childCount - childCount % spanCount;
// 如果是最后一行,则不需要绘制底部
if (pos >= childCount)
return true;
} else
// StaggeredGridLayoutManager 且横向滚动
{
// 如果是最后一行,则不需要绘制底部
if ((pos + 1) % spanCount == 0)
{
return true;
}
}
}
return false;
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition,
RecyclerView parent)
{
int spanCount = getSpanCount(parent);
int childCount = parent.getAdapter().getItemCount();
if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边
{
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else
{
outRect.set(0, 0, mDivider.getIntrinsicWidth(),
mDivider.getIntrinsicHeight());
}
}
}