自定义view-流式布局

总是觉得需求才是促进成长的一大动力哈哈

由于本人之前是做网页开发的,对于标签的流式布局只需要在flex布局内设置几个属性就能完成了。而转了android之后却没有那么好用的属性了,所以一直都想做一个android版的流式布局
(网上一搜一大堆,但还是想要自己实现一波)

公司有一个需求:添加一个奖励标签。效果图如下:


image.png

实现思路很简单:
1.在onMearsure中遍历list,计算出控件需要占据的总高度
2.在onDraw中同理计算出每一个item的左上角位置,调用drawItem方法绘制出item

下面是源代码

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class CustomFlexLayout extends View {

    private static final String TAG = "FlexLayout";

    private Paint mPaint;
    private Paint textPaint;
    private Path mPath;

    private List list = new ArrayList<>();

    private int marginV = 16;//绘制的item的纵向margin值
    private int marginH = 10;//绘制的item的横向margin值
    private int paddingV = 20;//绘制的item的纵向padding值
    private int paddingH = 28;//绘制的item的横向padding值
    private int radius = 4;//绘制的item四个角的半径
    private int backColor = Color.parseColor("#f3f9ff");//绘制的item的背景颜色
    private int textColor = Color.parseColor("#007aff");//绘制的item的背景颜色
    private float textSize = 32f;

    private int height;//控件高度,在onMeasure中计算得到
    private int width;//控件宽度,在xml中设置

    private int nowWidth;
    private int nowHeight;

    private int rectHeight; //矩形高度

    //暴露给外边设置item数据的方法
    public void setList(List list) {
        this.list = list;
        requestLayout();
    }

    public CustomFlexLayout(Context context) {
        this(context, null);
    }

    public CustomFlexLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomFlexLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(backColor);
        //设置抗锯齿
        mPaint.setAntiAlias(true);
        //设置防抖动
        mPaint.setDither(true);
        //设置填充方式
        mPaint.setStyle(Paint.Style.FILL);


        textPaint = new Paint();
        textPaint.setColor(textColor);
        //设置文本字体大小
        textPaint.setTextSize(textSize);
        //设置抗锯齿
        textPaint.setAntiAlias(true);
        //设置防抖动
        textPaint.setDither(true);
        //设置填充方式
        textPaint.setStyle(Paint.Style.FILL);

        mPath = new Path();

        rectHeight = marginV * 2 + paddingV * 2 + getFontHeight(textPaint);
        nowHeight = 0;
        nowWidth = 0;

    }

    private int getTextLength(String text) {
        return (int) textPaint.measureText(text);
    }

    private int getRectWidth(String text) {
        return marginH * 2 + paddingH * 2 + getTextLength(text);
    }

    private int getFontHeight(Paint paint) {
        Paint.FontMetrics fm = paint.getFontMetrics();
        //文字基准线的下部距离-文字基准线的上部距离 = 文字高度
        return (int) -(fm.bottom + fm.top);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        nowWidth = 0;
        nowHeight = rectHeight;
        width = getMeasuredWidth();

        int length;
        for (int i=0;i

你可能感兴趣的:(自定义view-流式布局)