ShapeDrawable DSL

29 阅读1分钟
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.GradientDrawable.*
import kotlin.math.roundToInt

enum class Shape {
    Rectangle,
    Oval,
    Line
    //Ring
}

class ShapeDrawableBuilder : DrawableBuilder {

    //形状,默认矩形
    var mShape = Shape.Rectangle

    //填充颜色
    private var mSolidColor = 0

    //描边颜色
    private var mStrokeColor = 0

    //描边宽度
    private var mStrokeWidth = 0

    //虚线宽度
    private var mDashWidth = 0f

    //虚线间隔
    private var mDashGap = 0f

    //渐变颜色
    private var mGradientColors: IntArray? = null

    //渐变角度
    var mAngle = 0

    //渐变方式
    private var mGradientType = LINEAR_GRADIENT

    //分别设置圆角
    private var leftTopRadius = 0f
    private var leftBottomRadius = 0f
    private var rightTopRadius = 0f
    private var rightBottomRadius = 0f

    //分别设置圆角的集合
    private var mRadii: FloatArray? = null

    //统一的圆角
    var mCornerRadius = 0f

    //大小
    private var mWidth = 0f
    private var mHeight = 0f

    fun stroke(strokeWidth: Int, strokeColor: Int) {
        this.mStrokeWidth = strokeWidth
        this.mStrokeColor = strokeColor
    }

    fun stroke(strokeWidth: Int, strokeColor: Int, dashWidth: Float, dashGap: Float) {
        this.mStrokeWidth = strokeWidth
        this.mStrokeColor = strokeColor
        this.mDashWidth = dashWidth
        this.mDashGap = dashGap
    }

    fun solidColor(color: Int) {
        this.mSolidColor = color
    }

    fun solidColor(color: String) {
        try {
            this.mSolidColor = Color.parseColor(color)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun cornerRadius(leftTopRadius: Float, leftBottomRadius: Float, rightTopRadius: Float, rightBottomRadius: Float) {
        this.leftTopRadius = leftTopRadius
        this.leftBottomRadius = leftBottomRadius
        this.rightTopRadius = rightTopRadius
        this.rightBottomRadius = rightBottomRadius
    }

    fun gradientColors(colors: IntArray) {
        this.mGradientColors = colors
    }

    fun setSize(width: Float, height: Float) {
        mWidth = width
        mHeight = height
    }

    override fun build(): Drawable {
        val drawable = mGradientColors?.let {
            buildGradientDrawable()
        } ?: buildNormalShapeDrawable()

        return drawable.apply {
            if (mStrokeWidth != 0) {
                if (mDashWidth != 0f && mDashGap != 0f) {
                    setStroke(mStrokeWidth, mStrokeColor, mDashWidth, mDashGap)
                } else {
                    setStroke(mStrokeWidth, mStrokeColor)
                }
            }
            if (mCornerRadius != 0f) {
                cornerRadius = mCornerRadius
            } else {
                mRadii = floatArrayOf(leftTopRadius,
                    leftTopRadius,
                    rightTopRadius,
                    rightTopRadius,
                    rightBottomRadius,
                    rightBottomRadius,
                    leftBottomRadius,
                    leftBottomRadius)
                cornerRadii = mRadii
            }
            shape = when (mShape) {
                Shape.Rectangle -> RECTANGLE
                Shape.Line -> LINE
                Shape.Oval -> OVAL
                //Shape.Ring -> RING
            }

            if (mWidth != 0f && mHeight != 0f) {
                setSize(mWidth.roundToInt(), mHeight.roundToInt())
            }
        }
    }

    private fun buildNormalShapeDrawable(): GradientDrawable {
        return GradientDrawable().apply {
            setColor(mSolidColor)
        }
    }

    private fun buildGradientDrawable(): GradientDrawable {
        val orientation = when (mAngle) {
            0 -> Orientation.LEFT_RIGHT
            45 -> Orientation.BL_TR
            90 -> Orientation.BOTTOM_TOP
            135 -> Orientation.BR_TL
            180 -> Orientation.RIGHT_LEFT
            225 -> Orientation.TR_BL
            270 -> Orientation.TOP_BOTTOM
            315 -> Orientation.TL_BR
            else -> Orientation.LEFT_RIGHT
        }
        return GradientDrawable(orientation, mGradientColors).apply {
            gradientType = mGradientType
        }
    }
}
/**
 * 建造者模式生成Drawable,普通的Drawable
 */
inline fun shapeDrawable(block: ShapeDrawableBuilder.() -> Unit): Drawable {
    return ShapeDrawableBuilder().also(block).build()
}

/**
 * 建造者模式生成Drawable,具有状态变化的Drawable
 */
inline fun selectorDrawable(block: SelectorDrawableBuilder.() -> Unit): Drawable {
    return SelectorDrawableBuilder().also(block).build()
}