RecyclerView
一、概述
RecyclerView可以看成是ListView的升级版。RecyclerView比ListView更加灵活,但是使用起来也更加麻烦。
二、使用
1、RecyclerView.setLayoutManager,设置整个RecyclerView的显示样式。Android提供了几个已经实现好的样式,LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。可以直接使用。
2、RecyclerView.setItemAnimator,设置增加、删除Item时候的动画效果。不设置的话,使用DefaultItemAnimator。
3、RecyclerView.setItemDecoration,通常用于设置Item之间的间隔符。
4、RecyclerView.setAdapter,设置RecyclerView对应的数据,及每条数据的展现。这个与ListView类似。但是RecyclerView对应点Adapter需要继承RecyclerView.Adapter<VH extends ViewHolder>,也就是说RecyclerView强制用户使用ViewHolder,这样效率更高。
5、RecyclerView设置Item被点击时的事件。在Adapter中写一个事件相关的接口,在外面添加处理的方法。在Adapter中添加删除、修改、添加的方法,并在方法中调用notifyItem*,我这里只添加了add的方法。
三、代码
1、总体代码
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); LayoutParams params = new LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1); recyclerView = new RecyclerView(this); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.addItemDecoration(new RecyclerItemDecoration()); recyclerView.setLayoutParams(params); final RecyclerAdapter adapter = new RecyclerAdapter(infos , this); adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(View view) { if (view instanceof TextView) { Toast.makeText(RecyclerViewActivity.this, ((TextView)view).getText().toString() , Toast.LENGTH_SHORT).show(); } } }); recyclerView.setAdapter(adapter); layout.addView(recyclerView); Button btnAdd = new Button(this); btnAdd.setText("Add"); layout.addView(btnAdd); btnAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { adapter.addItem("" + count, count); count++; } }); }
2、ItemDecorator,重写getItemOffsets,onDraw,onDrawOver方法。
public class RecyclerItemDecoration extends ItemDecoration { private int orientation; private ShapeDrawable shapeDrawable; private int shapeWidth = 5; private int shapeHeight = 5; public RecyclerItemDecoration() { this.orientation = RecyclerView.VERTICAL; initShape(); } public RecyclerItemDecoration(int orientation) { if (orientation == RecyclerView.HORIZONTAL) { this.orientation = RecyclerView.HORIZONTAL; } else { this.orientation = RecyclerView.VERTICAL; } initShape(); } private void initShape() { shapeDrawable = new ShapeDrawable(); shapeDrawable.getPaint().setColor(Color.RED); } @Override public void onDraw(Canvas c, RecyclerView parent, State state) { if (orientation == RecyclerView.HORIZONTAL) { drawHorizontal(c, parent, state); } else { drawVertical(c, parent, state); } } private void drawVertical(Canvas c, RecyclerView parent, State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int count = parent.getChildCount(); for(int index = 0; index < count; index++) { View child = parent.getChildAt(index); RecyclerView.LayoutParams params = (LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + shapeHeight; shapeDrawable.setBounds(left, top, right, bottom); shapeDrawable.draw(c); } } private void drawHorizontal(Canvas c, RecyclerView parent, State state) { // TODO Auto-generated method stub } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { if (orientation == RecyclerView.HORIZONTAL) { outRect.set(0, 0, shapeWidth, 0); } else { outRect.set(0, 0, 0, shapeHeight); } } }
其中,onDraw和onDrawOver的区别,onDraw绘制在最底层、Item绘制在中间层、onDrawOver绘制在最上层。
3、Adapter
public class RecyclerAdapter extends Adapter<RecyclerViewHolder> { public interface OnItemClickListener { void onItemClick(View view); } private OnItemClickListener itemClickListener = null; private static final String RecyclerViewTag = "RecyclerViewTag"; private String[] infos = null; private Context context = null; public RecyclerAdapter(String[] infos, Context context) { this.infos = infos; this.context = context; } @Override public int getItemCount() { return infos.length; } @Override public void onBindViewHolder(final RecyclerViewHolder holder, final int i) { holder.bindView(infos[i]); Log.i(RecyclerViewTag, ">>>>>>>>>>onBindViewHolder:>>>" + i); } @Override public RecyclerViewHolder onCreateViewHolder(ViewGroup viewgroup, int i) { LinearLayout view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.recycler_item, null); final RecyclerViewHolder holder = new RecyclerViewHolder(view); holder.textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.i(RecyclerViewTag, "Clicked"); if (itemClickListener != null) { itemClickListener.onItemClick(holder.textView); } } }); return holder; } public void addItem(String info, int position) { String[] newInfos = new String[infos.length + 1]; for (int i = 0; i < position; i++) { newInfos[i] = infos[i]; } newInfos[position] = info; for (int i = position; i < infos.length; i++) { newInfos[i + 1] = infos[i]; } infos = newInfos; notifyItemInserted(position); } public void setOnItemClickListener(OnItemClickListener listener) { itemClickListener = listener; } static class RecyclerViewHolder extends ViewHolder { public LinearLayout layout; public TextView textView; public RecyclerViewHolder(View arg0) { super(arg0); layout = (LinearLayout) arg0; textView = (TextView) layout.findViewById(R.id.tv_recycler_item); textView.setHeight(100); textView.setWidth(300); } public void bindView(String info) { textView.setText(info); } } }