美文网首页Android开发实战总结
RecycleView的简单使用,替代ListView、Grid

RecycleView的简单使用,替代ListView、Grid

作者: 破荒之恋 | 来源:发表于2017-07-17 09:45 被阅读536次

最近买了一本书《Android进阶之光》,希望能够让自己提高Android知识,走向进阶之路。

在看到RecycleView的讲解部分时,确实挺容易理解的,也自己敲了一遍代码,对RecycleView的使用理解更加深刻。RecycleView具有高度的解耦,异常灵活,RecycleView不但可以替代ListView、GridView等控件。还可以通过设置它提供的不同的LayoutManager、ItenDecoration、ItemAnimator可实现更加丰富多彩的效果。但是呢设置列表的分割线需要自己自定义,还有列表的点击事件需要自己去实现。

效果图:

image.png

那么如何使用RecycleView:

  • 配置build.gradle
 compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
  • 使用RecycleView
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private List<String> mListData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mListData=new ArrayList<>();
        for (int i = 0; i <30; i++) {
            mListData.add(i+"");
        }

          /*List<Integer> mHeights=new ArrayList<>();
            for (int i = 0; i < 30; i++) {

            mHeights.add((int) ((100+Math.random())+10*i));
        }*/
        mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        
        mRecyclerView.addItemDecoration(new     
        DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
       
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        //设置item增加和删除的动画
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        final RecycleViewMyAdapter adapter=new RecycleViewMyAdapter(mListData,MainActivity.this);

        /**
         * 实现RecycleView的item的点击效果
         */
        adapter.setOnItenClickListener(new RecycleViewMyAdapter.OnItenClickListener() {

            //单点击
            @Override
            public void onItenClick(View view, int position) {
                Toast.makeText(MainActivity.this, "点击了第"+position+"条"+"数据"+mListData.get(position), Toast.LENGTH_SHORT).show();
            }

            //长按点击
            @Override
            public void onItenLonfClick(View view, final int position) {
                //Toast.makeText(MainActivity.this, "长按了第"+position+"条"+"数据"+mListData.get(position), Toast.LENGTH_SHORT).show();
                new AlertDialog.Builder(MainActivity.this).setTitle("确定要删除吗?").
                        setNegativeButton("取消",null).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        //Toast.makeText(MainActivity.this, "---"+which, Toast.LENGTH_SHORT).show();
                        //Toast.makeText(MainActivity.this, "---------------------"+position, Toast.LENGTH_SHORT).show();
                        adapter.removeData(position);

                    }
                }).show();

            }
        });
        mRecyclerView.setAdapter(adapter);
    }
}

和ListView不同,需要设置布局管理器用于设置条目的排列样式,可以是水平或垂直。

   mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
    LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
    linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    mRecyclerView.setLayoutManager(linearLayoutManager);
  • Adapter的设置
    Adapter最大的改进就是对ViewHolder进行了封装,我们只需要定义一个ViewHolder继承RecycleView.ViewHolder就可以了。另外,Adapter继承RecycleView.adapter,在onCreateViewHolder中加载条目布局,在onBindViewHolder中将视图与数据进行绑定。

     *适配器RecycleView的Adapter
    * Created by an on 2017/7/11.
       public class RecycleViewMyAdapter extends RecyclerView.Adapter<RecycleViewMyAdapter.ViewHolder> {
    private List<String> mListDatas;
    private Context mContext;
    private static final String TAG = "RecycleViewMyAdapter";
    /**
     * 通过接口来实现点击、长按等事件
     */
     private OnItenClickListener mOnItenClickListener;
    private List<Integer> mHeights;
    public interface OnItenClickListener {
      void  onItenClick(View view,int position);
       void onItenLonfClick(View view,int position);
    }
    public void setOnItenClickListener(OnItenClickListener mOnItenClickListener){
        this.mOnItenClickListener=mOnItenClickListener;
    }

    public RecycleViewMyAdapter(List<String> mListData, MainActivity mainActivity) {

        this.mContext=mainActivity;
        this.mListDatas=mListData;

    }

    public void removeData(int position){
        mListDatas.remove(position);
        notifyItemRemoved(position);

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(mContext).inflate(R.layout.item_recycle, parent,false);
        ViewHolder holder=new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {

      holder.tv.setText(mListDatas.get(position));
         /* ViewGroup.LayoutParams lp=  holder.lin.getLayoutParams();
        lp.height=mHeights.get(position);
        holder.lin.setLayoutParams(lp);*/

       if (mOnItenClickListener!=null){
           holder.tv.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   int pos=holder.getLayoutPosition();
                   Toast.makeText(mContext, ""+pos, Toast.LENGTH_SHORT).show();
                   Log.d(TAG, "onClick: "+pos);

                   mOnItenClickListener.onItenClick(holder.tv,pos);

               }
           });


           holder.tv.setOnLongClickListener(new View.OnLongClickListener() {
               @Override
               public boolean onLongClick(View v) {
                   int pos=holder.getLayoutPosition();
                   Toast.makeText(mContext, ""+pos, Toast.LENGTH_SHORT).show();
                   mOnItenClickListener.onItenLonfClick(holder.tv,pos);
                   return false;
               }
           });


       }
    }

    @Override
    public int getItemCount() {
        return mListDatas.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        private TextView tv;
       // private ImageView lin;
        public ViewHolder(View itemView) {
            super(itemView);

            tv= (TextView) itemView.findViewById(R.id.item_tv);
            //lin= (ImageView) itemView.findViewById(R.id.img);

        }
    }
}

  • 设置分割线
    可以使用RecycleView.addItemDecoration()来加入分割线。

    Created by an on 2017/7/11.
    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 mDivider;
    private int mOrientation;
    private int orientation;
    public DividerItemDecoration(Context mContext, int mOrientation) {
        final TypedArray a = mContext.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(mOrientation);
    }



    public void setOrientation(int orientation) {
        if (orientation!=HORIZONTAL_LIST&&orientation!=VERTICAL_LIST){
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation=orientation;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent) {

        if (mOrientation==VERTICAL_LIST){
            drawVertical(c,parent);
        }else{
            drawHorizontal(c,parent);
        }

    }

    /**
     * 画水平方向的分割线
     * @param c
     * @param 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; 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);

        }
    }

    /**
     *画 随之方向
     * @param c
     * @param 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 v=new RecyclerView(parent.getContext());
            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,mDivider.getIntrinsicHeight());
        }else{
            outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
        }

    }
}

当然,也可以替代GridView的作用:
修改LinearLayoutManager

 mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));

效果图:

image.png
  • 自定义点击事件
    列表中的点击事件需要自己定义的。在Adapter中定义接口并提供回调。
   /**
 * 通过接口来实现点击、长按等事件
 */
   private OnItenClickListener mOnItenClickListener;
   public interface OnItenClickListener {
   void  onItenClick(View view,int position);
   void onItenLonfClick(View view,int position);
    }
   public void setOnItenClickListener(OnItenClickListener mOnItenClickListener){
    this.mOnItenClickListener=mOnItenClickListener;
   }
  • 实现瀑布流
    只要在Adapter中写一个随机的高度来控制每一个item的高度就可以了,通常高度是有服务器这边来控制的,现在我们随意来一个高度:
   List<Integer> mHeights=new ArrayList<>();
    for (int i = 0; i < 30; i++) {
        mHeights.add((int) ((100+Math.random())+10*i));
    }

效果图:

image.png

在onCreateViewHolder中设置控件高度

    holder.tv.setText(mListDatas.get(position));
    ViewGroup.LayoutParams lp=  holder.tv.getLayoutParams();
    lp.height=mHeights.get(position);
    holder.tv.setLayoutParams(lp);

自此,RecycleView替代ListView、GridView并且实现瀑布的功能都已实现。

相关文章

网友评论

    本文标题:RecycleView的简单使用,替代ListView、Grid

    本文链接:https://www.haomeiwen.com/subject/jirmhxtx.html