RecyclerView基本使用方式

1.RecyclerView 导入包的方式(可以避免build高版本调用低版本v7包编译不过问题)

compile ‘com.android.support:recyclerview-v7:+’

2.RecyclerView setAdapter前需要先设置LayoutManager,原因:明确其是水平展示还是纵向显示

3.RecyclerView 设置头部(尾部)View的方式

  • 原始方式:
        //复写getItemViewType方法,返回不同的iType值(与onCreateViewHolder保持一致)

        @Override 
        public int getItemViewType(int position) {
        int iType;
        if (position == 0) {
            iType = HEADVIEW;
        } else {
            iType = ORDINARYVIEW;
        }
            return iType;
        }
        @Override
    //复写onCreateViewHolder方法,根据不同的viewType产生不同的View

          @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          View view;

        if (viewType == HEADVIEW){
        view=LayoutInflater.from(parent.getContext()).
        inflate(R.layout.layout_item_head, null, false);
        } else {
            view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.layout_item, null, false);
        }

        return new MyHolder(view);
        }
    //复写onBindViewHolder方法,这里headView是一个固定的View,仅对普通布局进行bean类设定

        public void onBindViewHolder(MyHolder holder, int position) {
        //除头部外,其余项设置文字内同
        if (position != 0) {
            holder.txtContent.setText(lists.get(position));
            if (position % 2 == 0) {
                holder.txtContent.setBackgroundColor(Color.
                parseColor("#000000"));
                }
            }
        }

_ 大神造的轮子:

产考网址:http://www.open-open.com/lib/view/open1434422599926.html
关键代码:


    //在build.gradle(Module)文件中添加
    compile 'com.bartoszlipinski.recyclerviewheader:library:    1.2.0'
    //相应Activity中调用:
    RecyclerViewHeader header = RecyclerViewHeader.fromXml(
    MainActivity.this,R.layout.ayout_item_head);
    header.attachTo(recyclerView);

注意:

  RecyclerViewHeader必须在RecyclerView设置了LayoutManager之后调用。
目前该库适用于LinearLayoutManager,GridLayoutManager和
StaggeredGridLayoutManager布局的RecyclerViews。
只支持垂直布局LayoutManager

4.RecyclerView为子项添加监听事件

在MyAdapter中对ItemView设定点击事件的监听,通过getAdapterPosition可以获取到当前点击的position,再通过该position可以获取到ArrayList中的Bean对象。代码如下:
    public MyHolder(View itemView) {
        super(itemView);
        txtContent = (TextView) itemView. findViewById(
        R.id.txtContent);
        txtTit = (TextView) itemView.findViewById(R.id.txtTit);
        img = (ImageView) itemView.findViewById(R.id.img);
        //监控点击项
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                 Log.d("adapter","position: " + 
                 getAdapterPosition()); }
            });
        }
在如果想要将点击事件(点击位置position)暴露给外部的话,可以自定义一个接口,利用回调机制,在onClick中的调用接口中的相应方法即可.对Item添加监听的方式有很多种,修改源码,setOnItem-Touch方法等,在此使用一种最简单的方式去实现。

5.RecyclerView显示不同的布局方式,例如:

  • ①仅有content的Item
  • ②有content又有title的Item
  • ③有img,content,title的Item

Bean类设计如下:


    public class DataBean {

    public static final int DATA_TYPE_CONTENT = 1;
    public static final int DATA_TYPE_TIT = 2;
    public static final int DATA_TYPE_IMG = 3;

    int iType = DATA_TYPE_IMG;

    String strTit = "";
    String strContent = "";
    String strImgSource = "";

    public DataBean(String _strContext) {
        setType(DATA_TYPE_CONTENT);
        setContent(_strContext);
    }

    public DataBean(String _strTit, String _strContext) {
        this(_strContext);
        setType(DATA_TYPE_TIT);
        setTit(_strTit);
    }

    public DataBean(String strTit, String strContext, String _strImgSource) {
        this(strTit, strContext);
        setType(DATA_TYPE_IMG);
        setImgSource(_strImgSource);
    }

    public void setTit(String strTit) {
        this.strTit = strTit;
    }

    public String getTit() {
        return strTit;
    }

    public void setType(int iType) {
        this.iType = iType;
    }

    public int getType() {
        return iType;
    }

    public void setContent(String strContent) {
        this.strContent = strContent;
    }

    public String getContent() {
        return strContent;
    }

    public void setImgSource(String strImgSource) {
        this.strImgSource = strImgSource;
    }

    public String getImgSource() {
            return strImgSource;
        }
    }

MyAdapter中进行复写getItemViewType方法,根据Bean中的type来确定Item的type值:

    public int getItemViewType(int position) {
        DataBean data = datalists.get(position);
        return  data.getType();
    }

同时需要对onCreateViewHolder方法进行修改(根据viewType的值来加载不同的布局文件),核心代码如下:

            switch (viewType){
            case DataBean.DATA_TYPE_CONTENT:
                iItemView = R.layout.layout_item_content;
                break;
            case DataBean.DATA_TYPE_TIT:
                iItemView = R.layout.layout_item_title;
                break;
            case DataBean.DATA_TYPE_IMG:
                iItemView = R.layout.layout_item_img;
                break;
            default:
                break;
        }
        view = LayoutInflater.from(parent.getContext()).inflate(
                iItemView, null, false);

        return new MyHolder(view);

更改绑定数据的方法onBindViewHolder,注意在onBindViewHolder方法中没有onCreateViewHolder方法中的viewType参数,所以需要根据position在ArrayList中获取相应的元素,再通过Bean类中的getType来确定需要绑定数据的种类。核心代码如下:


        DataBean _data = datalists.get(position);

        switch (_data.getType()){
            case DataBean.DATA_TYPE_CONTENT:
                if (holder.txtContent != null) {
                    holder.txtContent.setText(_data.getContent());
                }
                break;
            case DataBean.DATA_TYPE_TIT:
                if(holder.txtContent != null){
                    holder.txtContent.setText(_data.getContent());
                }
                if(holder.txtTit != null){
                    holder.txtTit.setText(_data.getTit());
                }
                break;
            case DataBean.DATA_TYPE_IMG:
                if(holder.txtContent != null){
                    holder.txtContent.setText(_data.getContent());
                }
                                if(holder.txtTit != null){
                    holder.txtTit.setText(_data.getTit());
                }
                if(holder.img != null){
                    holder.img.setBackgroundColor(Color.GREEN);
                }
                break;
        }

方便期间,在这里没有实际为ImageView加载真实的图片,仅仅设定了控件的背景色代表设置图片的操作。

6.RecyclerrView设定分割线

官方没有提供设置分割线的方法recyclerView.addItemDecoration()
遗憾的是分割线是一个虚拟类,需要我们自行继承并去实现分割线的显示样式

参考万能的分割线:http://blog.csdn.net/pengkv/article/details/50538121

完整RecycleViewDivider代码如下:


    public class RecycleViewDivider extends RecyclerView.ItemDecoration {

    private Paint mPaint;
    private Drawable mDivider;
    private int mDividerHeight = 2;//分割线高度,默认为1px
    private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

    /**
     * 默认分割线:高度为2px,颜色为灰色
     *
     * @param context
     * @param orientation 列表方向
     */
    public RecycleViewDivider(Context context, int orientation) {
        if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
            throw new IllegalArgumentException("请输入正确的参数!");
        }
        mOrientation = orientation;

        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    /**
     * 自定义分割线
     *
     * @param context
     * @param orientation 列表方向
     * @param drawableId  分割线图片
     */
    public RecycleViewDivider(Context context, int orientation, int drawableId) {
        this(context, orientation);
        mDivider = ContextCompat.getDrawable(context, drawableId);
        mDividerHeight = mDivider.getIntrinsicHeight();
    }

    /**
     * 自定义分割线
     *
     * @param context
     * @param orientation   列表方向
     * @param dividerHeight 分割线高度
     * @param dividerColor  分割线颜色
     */
    public RecycleViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) {
        this(context, orientation);
        mDividerHeight = dividerHeight;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(dividerColor);
        mPaint.setStyle(Paint.Style.FILL);
    }


    //获取分割线尺寸
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.set(0, 0, 0, mDividerHeight);
    }

    //绘制分割线
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    //绘制横向 item 分割线
    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + layoutParams.bottomMargin;
            final int bottom = top + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
            }
        }
    }

    //绘制纵向 item 分割线
    private void drawVertical(Canvas canvas, RecyclerView parent)   {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + layoutParams.rightMargin;
            final int right = left + mDividerHeight;
            if (mDivider != null) {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
                }
            if (mPaint != null) {
                canvas.drawRect(left, top, right, bottom, mPaint);
                }
            }
        }  
    }

3种使用方式:

    //自定义分割线高,指定分割线颜色
        /*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
                LinearLayoutManager.HORIZONTAL,10, Color.BLUE));
        */

        //指定样式(在shape中进行颜色,线高的设置)的分割线
        /*recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,
                LinearLayoutManager.HORIZONTAL, R.drawable.shape_item_line));*/

        //默认样式实现分割线
        recyclerView.addItemDecoration(new RecycleViewDivider(MainActivity.this,LinearLayoutManager.HORIZONTAL));

drawable/shape_item_line.xml代码如下:

<gradient
    android:centerColor="#ff00ff00"
    android:endColor="#ff0000ff"
    android:startColor="#ffff0000"
    android:type="linear" />
<size android:height="4dp"/>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值