RecyclerView

Posted 环游世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
        }
    }
    
}

 

以上是关于RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Firebase 获取数据到 Recyclerview 中的片段?

从片段类中的对话框添加项目到recyclerview。

从其他片段添加新的 RecyclerView 项

为啥 recyclerview$adapter 在片段中为空

片段中的Android Studio RecyclerView [重复]

RecyclerView holder中的Android Google Maps动态片段