主类
package com.zjw.chapter1androidnewcharacteristics; import android.content.DialogInterface; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View; import android.widget.Toast; import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; //1.1 p1 Android 5.0 新特性 /* Android 5.0 Lollipop 棒棒糖 API 21 */ //1.1.2 p3 替换ListView和GridView的RecyclerView /* RecyclerView 优点:高度解耦,灵活,效率更高 缺点:分割线需要自定义,列表点击事件要自己实现、 */ /* RecyclerView使用: 1.配置Gradle compile 'com.android.support:recyclerview-v7:25.3.1' 2.布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="#FFB900" android:dividerHeight="1dp" /> </LinearLayout> 3.找控件设置布局管理器、动画、设配器 其中LinearLayoutManager默认是垂直, 可用linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL)设为水平 4.设置分割线 addItemDecoration()来添加分割线,我们要继承RecyclerView.ItemDecoration来自定义分割线 setColorFilter()第二个参数:PorterDuff.Mode枚举值: 1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。 2.PorterDuff.Mode.SRC 显示上层绘制图片 3.PorterDuff.Mode.DST 显示下层绘制图片 4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。 5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。 6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。 7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。 8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。 9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。 10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分 11.PorterDuff.Mode.DST_ATOP 5.自定义点击事件 在adapter中设置接口回调,主类中进行监听 6.实现GridView */ public class MainActivity extends AppCompatActivity { @BindView(R.id.rv) RecyclerView mRv; List<String> mDataList = new ArrayList<>(); private RvAdapter mRvAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this);//绑定黄油刀 initData();//recyclerView数据 initView();//设置recyclerView的布局管理器、动画、分割线、设配器 initEvent();//设置recyclerView的点击监听 } //recyclerView数据 private void initData() { for (int i = 0; i < 500; i++) { mDataList.add("" + i); } } //设置布局管理器、动画、分割线、设配器 private void initView() { // //线性布局 // mRv.setLayoutManager(new LinearLayoutManager(this));//设置布局管理器 // mRv.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画 // mRv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST, Color.BLUE));//设置分割线 // //表格布局也可以用瀑布流管理器 // mRv.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL)); // mRv.addItemDecoration(new DividerGridItemDecoration(this, Color.YELLOW)); //瀑布流,在adapter里写一个随机高度来控制每个item的高度 mRv.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL)); mRv.addItemDecoration(new DividerGridItemDecoration(this, Color.YELLOW)); //设配器 mRvAdapter = new RvAdapter(this, mDataList); mRv.setAdapter(mRvAdapter);//设置设配器 } private void initEvent() { mRvAdapter.setOnItemClickListener(new RvAdapter.onItemClickListener() { @Override public void onItemClick(View view, int position) { showToast("点击第" + position + "条"); } @Override public void onItemLongClick(View view, final int position) { new AlertDialog.Builder(MainActivity.this) .setTitle("确认删除吗?") .setNegativeButton("取消", null) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mRvAdapter.removeData(position); } }).show(); } }); } //用来弹吐司 private static Toast mToast; public void showToast(String msg) { if (mToast == null) { mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT); } mToast.setText(msg); mToast.show(); } }
适配器
package com.zjw.chapter1androidnewcharacteristics; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; import java.util.List; /** * Created by hp on 2017/8/13. */ public class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvViewHolder> { Context mContext; List<String> mDataList; public onItemClickListener mOnItemClickListener; List<Integer> mHeights; public RvAdapter(Context context, List<String> dataList) { mContext = context; mDataList = dataList; } public void removeData(int position) { mDataList.remove(position); notifyDataSetChanged(); } //加载布局条目 @Override public RvViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RvViewHolder holder = new RvViewHolder(LayoutInflater.from(mContext).inflate(R.layout.rv_item, parent, false)); return holder; } //将视图与数据进行绑定 @Override public void onBindViewHolder(final RvViewHolder holder, int position) { holder.mTvRvItem.setText(mDataList.get(position)); if (mOnItemClickListener != null) { holder.mTvRvItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos = holder.getLayoutPosition(); mOnItemClickListener.onItemClick(holder.mTvRvItem, pos); } }); holder.mTvRvItem.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int pos = holder.getLayoutPosition(); mOnItemClickListener.onItemLongClick(holder.mTvRvItem, pos); return false; } }); } //设置高度 setHeight(); ViewGroup.LayoutParams layoutParams = holder.mTvRvItem.getLayoutParams(); layoutParams.height = mHeights.get(position); holder.mTvRvItem.setLayoutParams(layoutParams); } @Override public int getItemCount() { return mDataList.size(); } public class RvViewHolder extends RecyclerView.ViewHolder { TextView mTvRvItem; public RvViewHolder(View itemView) { super(itemView); mTvRvItem = (TextView) itemView.findViewById(R.id.tv_rv_item); } } //点击事件接口回调 public interface onItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } public void setOnItemClickListener(onItemClickListener onItemClickListener) { mOnItemClickListener = onItemClickListener; } public void setHeight() { mHeights = new ArrayList<>(); for (int i = 0; i < mDataList.size(); i++) { mHeights.add((int) (100 + Math.random() * 300)); } } }
分割线1
package com.zjw.chapter1androidnewcharacteristics; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Created by hp on 2017/8/13. */ public class DividerItemDecoration 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 Drawable mDrawable; private int mOrientation; private int mColor = -1; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDrawable = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public DividerItemDecoration(Context context, int orientation, int color) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDrawable = a.getDrawable(0); a.recycle(); setOrientation(orientation); setColor(color); } //设置分割线方向 public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } //设置分割线颜色 public void setColor(int color) { mColor = color; } @Override public void onDraw(Canvas c, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) {//画垂直方向上的分割线(横的) drawVertical(c, parent); } else { drawHorizontal(c, parent);//画水平方向上的分割线(竖的) } } //画垂直方向上的分割线(横的) 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; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + layoutParams.bottomMargin; int bottom = top + mDrawable.getIntrinsicHeight(); mDrawable.setBounds(left, top, right, bottom); if (mColor != -1) { mDrawable.setColorFilter(mColor, PorterDuff.Mode.DST_OVER); } mDrawable.draw(c); } } //画水平方向上的分割线(竖的) private void drawHorizontal(Canvas c, RecyclerView parent) { int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int left = child.getRight() + layoutParams.rightMargin; int right = left + mDrawable.getIntrinsicWidth(); mDrawable.setBounds(left, top, right, bottom); if (mColor != -1) { mDrawable.setColorFilter(mColor, PorterDuff.Mode.DST_OVER); } mDrawable.draw(c); } } //设置item分割线的size @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDrawable.getIntrinsicHeight()); } else { outRect.set(0, 0, mDrawable.getIntrinsicWidth(), 0); } } }
分割线2
package com.zjw.chapter1androidnewcharacteristics; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Created by hp on 2017/8/13. */ public class DividerGridItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; private Drawable mDrawable; private int mColor = -1; public DividerGridItemDecoration(Context context) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDrawable = a.getDrawable(0); a.recycle(); } public DividerGridItemDecoration(Context context,int color) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDrawable = a.getDrawable(0); a.recycle(); setColor(color); } //设置分割线颜色 public void setColor(int color) { mColor = color; } @Override public void onDraw(Canvas c, RecyclerView parent) { drawVertical(c, parent); drawHorizontal(c, parent);//画水平方向上的分割线(竖的) } //画垂直方向上的分割线(横的) 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; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + layoutParams.bottomMargin; int bottom = top + mDrawable.getIntrinsicHeight(); mDrawable.setBounds(left, top, right, bottom); if (mColor != -1) { mDrawable.setColorFilter(mColor, PorterDuff.Mode.DST_OVER); } mDrawable.draw(c); } } //画水平方向上的分割线(竖的) private void drawHorizontal(Canvas c, RecyclerView parent) { int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int left = child.getRight() + layoutParams.rightMargin; int right = left + mDrawable.getIntrinsicWidth(); mDrawable.setBounds(left, top, right, bottom); if (mColor != -1) { mDrawable.setColorFilter(mColor, PorterDuff.Mode.DST_OVER); } mDrawable.draw(c); } } //设置item分割线的size @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { outRect.set(0, 0,mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight()); } }
主布局一个recyclerView,item布局一个TextView