美文网首页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