<declare-styleable name="LinearGradientBackgroundLayout"> <attr name="lgbBorderRadius" format="dimension" /> <attr name="lgbShadowWidth" format="dimension" /> </declare-styleable>
class LinearGradientBackgroundLayout : FrameLayout { companion object { private const val LEFT = 0 private const val TOP = 1 private const val RIGHT = 2 private const val BOTTOM = 3 } constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) { initAttrs(context, attrs, defStyleAttr) } private var borderRadius: Float = 0f private var shadowWidth: Float = 0f private val colors = intArrayOf( Color.argb(41, 255, 255, 255), Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT ) private val paint: Paint = Paint() private val path: Path = Path() private fun initAttrs(context: Context, attrs: AttributeSet?, defStyleAttr: Int) { val ta = context.obtainStyledAttributes(attrs, R.styleable.LinearGradientBackgroundLayout) borderRadius = ta.getDimension(R.styleable.LinearGradientBackgroundLayout_lgbBorderRadius, 0f) shadowWidth = ta.getDimension(R.styleable.LinearGradientBackgroundLayout_lgbShadowWidth, 0f) ta.recycle() setBackgroundColor(Color.TRANSPARENT) } override fun onDraw(canvas_: Canvas?) { super.onDraw(canvas_) val w = width.toFloat() val h = height.toFloat() canvas_?.apply { //clip path if (borderRadius > 0f) { path.apply { reset() moveTo(0f, borderRadius) quadTo(0f, 0f, borderRadius, 0f) lineTo(w - borderRadius, 0f) quadTo(w, 0f, w, borderRadius) lineTo(w, h - borderRadius) quadTo(w, h, w - borderRadius, h) lineTo(borderRadius, h) quadTo(0f, h, 0f, h - borderRadius) close() } clipPath(path) } drawColor(Color.BLACK) //left path.apply { reset() moveTo(0f, 0f) lineTo(shadowWidth, shadowWidth) lineTo(shadowWidth, h - shadowWidth) lineTo(0f, h) close() } paint.shader = createLinearGradient(LEFT) drawPath(path, paint) //top path.apply { reset() moveTo(0f, 0f) lineTo(shadowWidth, shadowWidth) lineTo(w - shadowWidth, shadowWidth) lineTo(w, 0f) close() } paint.shader = createLinearGradient(TOP) drawPath(path, paint) //right path.apply { reset() moveTo(w, 0f) lineTo(w - shadowWidth, shadowWidth) lineTo(w - shadowWidth, h - shadowWidth) lineTo(w, h) close() } paint.shader = createLinearGradient(RIGHT) drawPath(path, paint) //bottom path.apply { reset() moveTo(w, h) lineTo(w - shadowWidth, h - shadowWidth) lineTo(shadowWidth, h - shadowWidth) lineTo(0f, h) close() } paint.shader = createLinearGradient(BOTTOM) drawPath(path, paint) } } private fun createLinearGradient(direction: Int): LinearGradient { return when (direction) { LEFT -> LinearGradient(0f, 0f, shadowWidth, 0f, colors, null, Shader.TileMode.CLAMP) TOP -> LinearGradient(0f, 0f, 0f, shadowWidth, colors, null, Shader.TileMode.CLAMP) RIGHT -> LinearGradient( width.toFloat(), 0f, width.toFloat() - shadowWidth, 0f, colors, null, Shader.TileMode.CLAMP ) else -> LinearGradient( 0f, height.toFloat(), 0f, height - shadowWidth, colors, null, Shader.TileMode.CLAMP ) } } }