转载 http://blog.csdn.net/yalinfendou/article/details/46636409【yalinfendou的博客】
Android RecyclerView 在去年的Google I/O大会上就推出来了,以前经常使用的ListView 继承的是AbsListView,而RecyclerView则直接继承 ViewGroup,并实现了ScrollingView 和 NestedScrollingChild接口,RecyclerView相比ListView,是一次彻底的改变,RecyclerView 比ListView更加强大灵活。
<android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:scrollbars="vertical" />如果想水平排列显示,把layoutManager.setOrientation(LinearLayoutManager.VERTICAL)替换成layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL)即可。
// 如果布局大小一致有利于优化 recyclerView.setHasFixedSize(true); // 创建一个线性布局管理器 LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); // 设置布局管理器 recyclerView.setLayoutManager(layoutManager); // 创建数据集 List<User> listData = new ArrayList<User>(); for (int i = 0; i < 20; ++i) { User uBean = new User(); uBean.setUsername("我是Item" + i); listData.add(uBean); } // 创建Adapter,并指定数据集 MyAdapter adapter = new MyAdapter(context, listData); // 设置Adapter recyclerView.setAdapter(adapter);
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> { private Context context; private List<User> listData; public MyAdapter(Context context, List<User> mList) { super(); this.context = context; this.listData = mList; } @Override public int getItemCount() { // TODO Auto-generated method stub return listData.size(); } @Override public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) { View view = View.inflate(viewGroup.getContext(), R.layout.item_user_friend_nod, null); // 创建一个ViewHolder MViewHolder holder = new MViewHolder(view); return holder; } @Override public void onBindViewHolder(MViewHolder mViewHolder, int arg1) { mViewHolder.mTextView.setText(listData.get(arg1).getUsername()); mViewHolder.image.setBackgroundResource(R.drawable.head); } public class MViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ImageView image; public MViewHolder(View view) { super(view); this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name); this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar); } } }
/** * item点击回调接口 * * @author wen_er * */ public interface ItemClickListener { /** * Item 普通点击 */ public void onItemClick(View view, int postion); /** * Item 长按 */ public void onItemLongClick(View view, int postion); /** * Item 内部View点击 */ public void onItemSubViewClick(View view, int postion); }
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MViewHolder> { private Context context; private List<User> listData; private ItemClickListener mItemClickListener; public MyAdapter(Context context, List<User> mList) { super(); this.context = context; this.listData = mList; } public void setItemClickListener(ItemClickListener mItemClickListener) { this.mItemClickListener = mItemClickListener; } @Override public int getItemCount() { // TODO Auto-generated method stub return listData.size(); } @Override public MViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) { View view = View.inflate(viewGroup.getContext(), R.layout.item_user_friend_nod, null); // 创建一个ViewHolder MViewHolder holder = new MViewHolder(view); return holder; } @Override public void onBindViewHolder(final MViewHolder mViewHolder, final int postion) { mViewHolder.mTextView.setText(listData.get(postion).getUsername()); mViewHolder.image.setBackgroundResource(R.drawable.head); // 为image添加监听回调 mViewHolder.image.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (null != mItemClickListener) { mItemClickListener.onItemSubViewClick(mViewHolder.image, postion); } } }); } public class MViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ImageView image; public MViewHolder(final View view) { super(view); this.mTextView = (TextView) view.findViewById(R.id.tv_friend_name); this.image = (ImageView) itemView.findViewById(R.id.img_friend_avatar); //为item添加普通点击回调 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (null != mItemClickListener) { mItemClickListener.onItemClick(view, getPosition()); } } }); //为item添加长按回调 view.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { if (null != mItemClickListener) { mItemClickListener.onItemLongClick(view, getPosition()); } return true; } }); } } }
//为Item具体实例点击3种事件 adapter.setItemClickListener(new ItemClickListener() { @Override public void onItemSubViewClick(View view, int postion) { T.showShort(context, "亲,你点击了Image"+postion); } @Override public void onItemLongClick(View view, int postion) { T.showShort(context, "亲,你长按了Item"+postion); } @Override public void onItemClick(View view, int postion) { T.showShort(context, "亲,你点击了Item"+postion); } });
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/selector_item_action" > <TextView android:id="@+id/tv_friend_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@+id/img_friend_avatar" android:text="test" android:textSize="18sp" /> <ImageView android:id="@+id/img_friend_avatar" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentLeft="true" android:layout_marginBottom="8dip" android:layout_marginLeft="8dip" android:layout_marginTop="8dip" android:background="@drawable/ic_launcher" /> </RelativeLayout> <!-- 可以添加以下代码为Item之间设置分隔线 --> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_alignParentBottom="true" android:background="@drawable/divider_horizontal_line" /> </RelativeLayout>
public class ItemDecorationDivider extends ItemDecoration { private Drawable mDivider; private int mOritation; public ItemDecorationDivider(Context context, int resId, int oritation) { mDivider = context.getResources().getDrawable(resId); this.mOritation = oritation; Log.i("ItemDecorationDivider", "mOritation=" + mOritation); } @Override public void onDrawOver(Canvas c, RecyclerView parent) { if (mOritation == LinearLayoutManager.VERTICAL) { 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); 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); } } else if (mOritation == LinearLayoutManager.HORIZONTAL) { final int top = parent.getPaddingTop(); // final int bottom = parent.getHeight() - // parent.getPaddingBottom(); 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 left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); final int bottom = child.getBottom(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } @Override public void getItemOffsets(Rect outRect, int position, RecyclerView parent) { if (mOritation == LinearLayoutManager.VERTICAL) { outRect.set(0, 0, 0, mDivider.getIntrinsicWidth()); // outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else if (mOritation == LinearLayoutManager.HORIZONTAL) { // outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } } }
recyclerView.addItemDecoration(new ItemDecorationDivider(context, R.drawable.item_divider, LinearLayoutManager.VERTICAL));
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" > <solid android:color="#CCCCCC" /> <size android:height="1dp" /> </shape>
notifyItemChanged(int position)
//通知位置position的Item的数据改变
notifyItemInserted(int)//通知位置position的Item的数据插入
notifyItemRemoved(int)//通知位置position的Item的数据移除
notifyItemRangeChanged(int positionStart, int itemCount) //通知从位置positionStart开始,有itemCount个Item的数据发生改变
notifyItemRangeInserted(int positionStart, int itemCount) //通知从位置positionStart开始,有itemCount个Item的数据插入
notifyItemRangeRemoved(int positionStart, int itemCount)//通知从位置positionStart开始,有itemCount个Item的数据移除
* TODO<添加数据,指定其位置> */ public void addData(User info, int position) { listData.add(position, info); notifyItemInserted(position); // notifyDataSetChanged(); //不会触发Item的动画效果,告知数据改变,刷新UI } /** * TODO<添加数据到最后面添加> */ public void addData(User info) { // listData.add(position, info); // notifyItemInserted(position); listData.add(info); notifyDataSetChanged(); } /** * TODO<删除数据,指定其位置> */ public void daleteData(int position) { listData.remove(position); notifyItemRemoved(position); } /** * TODO<某一位置开始,有itemCount个Item的数据删除> */ public void itemRangeRemoved(int positionStart, int itemCount) { for (int i = positionStart; i < itemCount; i++) { listData.remove(positionStart); } notifyItemRangeRemoved(positionStart, itemCount); // notifyDataSetChanged(); //不会触发Item的动画效果,告知数据改变,刷新UI } /** * TODO<某一位置开始,有itemCount个Item的数据插入> */ public void itemRangeInserted(User info, int positionStart, int itemCount) { for (int i = positionStart; i < itemCount; i++) { listData.add(i, info); } notifyItemRangeInserted(positionStart, itemCount); // notifyDataSetChanged(); }
case R.id.btn3: User uBean = new User(); uBean.setUsername("我是增加的Item"); adapter.addData(uBean, 0);// 添加到第一个 break; case R.id.btn4: adapter.daleteData(0); // 删除第一个 break; case R.id.btn5: User uBean1 = new User(); uBean1.setUsername("我是连续添加的Item"); adapter.itemRangeInserted(uBean1, 0, 5); break; case R.id.btn6: adapter.itemRangeRemoved(0, 5); break;
// 使用RecyclerView提供的默认的动画效果 recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int scrollState) { updateState(scrollState); } @Override public void onScrolled(RecyclerView recyclerView, int i, int i2) { String s = "可见Item数量:" + layoutManager.getChildCount()+"\n" + "可见Item第一个Position:" + layoutManager.findFirstVisibleItemPosition()+"\n" + "可见Item最后一个Position:" + layoutManager.findLastVisibleItemPosition(); tv.setText(s); } });
private void updateState(int scrollState) { String stateName = "Undefined"; switch (scrollState) { case SCROLL_STATE_IDLE: stateName = "Idle"; break; case SCROLL_STATE_DRAGGING: stateName = "Dragging"; break; case SCROLL_STATE_SETTLING: stateName = "Flinging"; break; } tv_state.setText("滑动状态:" + stateName); }
gridLayoutManager = new GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false); // 设置布局管理器 recyclerView.setLayoutManager(gridLayoutManager);
StaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); // 设置布局管理器 recyclerView.setLayoutManager(StaggeredGridLayoutManager);