diff --git a/library/build.gradle b/library/build.gradle index dc2f9ee..2266363 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -12,8 +12,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 28 - versionCode 224 - versionName "2.2.4" + versionCode 230 + versionName "2.3.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/library/src/main/java/com/allen/library/helper/AttributeSetHelper.kt b/library/src/main/java/com/allen/library/helper/AttributeSetHelper.kt new file mode 100644 index 0000000..5648ea6 --- /dev/null +++ b/library/src/main/java/com/allen/library/helper/AttributeSetHelper.kt @@ -0,0 +1,108 @@ +package com.allen.library.helper + +import android.content.Context +import android.graphics.drawable.GradientDrawable +import android.util.AttributeSet +import com.allen.library.R + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class AttributeSetHelper { + + private val defaultColor = 0x20000000 + private val defaultSelectorColor = 0x20000000 + + fun initShapeBuilderFromAttributeSet(context: Context, attrs: AttributeSet?): ShapeBuilder { + if (attrs == null) return ShapeBuilder() + val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShapeView) + + val shapeType = typedArray.getInt(R.styleable.ShapeView_shapeType, GradientDrawable.RECTANGLE) + + val solidColor = typedArray.getColor(R.styleable.ShapeView_shapeSolidColor, defaultColor) + + val selectorPressedColor = typedArray.getColor(R.styleable.ShapeView_shapeSelectorPressedColor, defaultSelectorColor) + val selectorDisableColor = typedArray.getColor(R.styleable.ShapeView_shapeSelectorDisableColor, defaultSelectorColor) + val selectorNormalColor = typedArray.getColor(R.styleable.ShapeView_shapeSelectorNormalColor, defaultSelectorColor) + + val cornersRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeCornersRadius, 0).toFloat() + val cornersTopLeftRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeCornersTopLeftRadius, 0).toFloat() + val cornersTopRightRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeCornersTopRightRadius, 0).toFloat() + val cornersBottomLeftRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeCornersBottomLeftRadius, 0).toFloat() + val cornersBottomRightRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeCornersBottomRightRadius, 0).toFloat() + + val strokeWidth = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeStrokeWidth, 0) + val strokeDashWidth = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeStrokeDashWidth, 0).toFloat() + val strokeDashGap = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeStrokeDashGap, 0).toFloat() + + val strokeColor = typedArray.getColor(R.styleable.ShapeView_shapeStrokeColor, defaultColor) + + val sizeWidth = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeSizeWidth, 0) + val sizeHeight = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeSizeHeight, dip2px(context, 48f)) + + val gradientAngle = typedArray.getFloat(R.styleable.ShapeView_shapeGradientAngle, -1f).toInt() + val gradientCenterX = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeGradientCenterX, 0) + val gradientCenterY = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeGradientCenterY, 0) + val gradientGradientRadius = typedArray.getDimensionPixelSize(R.styleable.ShapeView_shapeGradientGradientRadius, 0) + + val gradientStartColor = typedArray.getColor(R.styleable.ShapeView_shapeGradientStartColor, -1) + val gradientCenterColor = typedArray.getColor(R.styleable.ShapeView_shapeGradientCenterColor, -1) + val gradientEndColor = typedArray.getColor(R.styleable.ShapeView_shapeGradientEndColor, -1) + + val gradientType = typedArray.getInt(R.styleable.ShapeView_shapeGradientType, 0) + val gradientUseLevel = typedArray.getBoolean(R.styleable.ShapeView_shapeGradientUseLevel, false) + + val useSelector = typedArray.getBoolean(R.styleable.ShapeView_shapeUseSelector, false) + + typedArray.recycle() + + val shapeBuilder = ShapeBuilder() + shapeBuilder + .setShapeType(shapeType) + .setShapeCornersRadius(cornersRadius) + .setShapeCornersTopLeftRadius(cornersTopLeftRadius) + .setShapeCornersTopRightRadius(cornersTopRightRadius) + .setShapeCornersBottomRightRadius(cornersBottomRightRadius) + .setShapeCornersBottomLeftRadius(cornersBottomLeftRadius) + .setShapeSolidColor(solidColor) + .setShapeStrokeColor(strokeColor) + .setShapeStrokeWidth(strokeWidth) + .setShapeStrokeDashWidth(strokeDashWidth) + .setShapeStrokeDashGap(strokeDashGap) + .setShapeUseSelector(useSelector) + .setShapeSelectorNormalColor(selectorNormalColor) + .setShapeSelectorPressedColor(selectorPressedColor) + .setShapeSelectorDisableColor(selectorDisableColor) + .setShapeSizeWidth(sizeWidth) + .setShapeSizeHeight(sizeHeight) + .setShapeGradientType(gradientType) + .setShapeGradientAngle(gradientAngle) + .setShapeGradientGradientRadius(gradientGradientRadius) + .setShapeGradientUseLevel(gradientUseLevel) + .setShapeGradientCenterX(gradientCenterX) + .setShapeGradientCenterY(gradientCenterY) + .setShapeGradientStartColor(gradientStartColor) + .setShapeGradientCenterColor(gradientCenterColor) + .setShapeGradientEndColor(gradientEndColor) + + return shapeBuilder + } + + + /** + * 单位转换工具类 + * + * @param context 上下文对象 + * @param dipValue 值 + * @return 返回值 + */ + private fun dip2px(context: Context, dipValue: Float): Int { + val scale = context.resources.displayMetrics.density + return (dipValue * scale + 0.5f).toInt() + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/helper/ShapeBuilder.kt b/library/src/main/java/com/allen/library/helper/ShapeBuilder.kt new file mode 100644 index 0000000..d3c72b6 --- /dev/null +++ b/library/src/main/java/com/allen/library/helper/ShapeBuilder.kt @@ -0,0 +1,413 @@ +package com.allen.library.helper + +import android.content.Context +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.StateListDrawable +import android.os.Build +import android.support.v4.view.ViewCompat +import android.view.View + +/** + *
+ * @author : Allen
+ * e-mail  : lygttpod@163.com
+ * date    : 2019/05/27
+ * desc    : shape构造器
+
* + */ +class ShapeBuilder { + + companion object { + + /** + * shape的样式 + */ + const val RECTANGLE = 0 + const val OVAL = 1 + const val LINE = 2 + const val RING = 3 + + /** + * "radial" | "sweep"] + * android:useLevel=["true" | "false"] /> + * 参数对应关系 + */ + + //渐变色的显示方式 + const val TOP_BOTTOM = 0 + const val TR_BL = 1 + const val RIGHT_LEFT = 2 + const val BR_TL = 3 + const val BOTTOM_TOP = 4 + const val BL_TR = 5 + const val LEFT_RIGHT = 6 + const val TL_BR = 7 + + const val LINEAR = 0 + const val RADIAL = 1 + const val SWEEP = 2 + } + + /** + * android:shape=["rectangle" | "oval" | "line" | "ring"] + */ + private var shapeType = -1 + + /** + * + */ + private var solidColor = -1 + + /** + * + */ + private var strokeWidth = -1 + private var strokeColor = -1 + private var strokeDashWidth = 0.0f + private var strokeDashGap = 0.0f + + /** + * + */ + private var cornersRadius = 0.0f + private var cornersTopLeftRadius = 0.0f + private var cornersTopRightRadius = 0.0f + private var cornersBottomLeftRadius = 0.0f + private var cornersBottomRightRadius = 0.0f + + private var gradientAngle = -1 + private var gradientCenterX: Int = 0 + private var gradientCenterY: Int = 0 + private var gradientGradientRadius: Int = 0 + + private var gradientStartColor = -1 + private var gradientCenterColor = -1 + private var gradientEndColor = -1 + + private var gradientType: Int = 0 + + private var gradientUseLevel: Boolean = false + + /** + * + */ + private var sizeWidth = -1 + private var sizeHeight = -1 + + /** + * "false"] + * android:dither=["true" | "false"] + * android:variablePadding=["true" | "false"] > + * "false"] + * android:state_focused=["true" | "false"] + * android:state_hovered=["true" | "false"] + * android:state_selected=["true" | "false"] + * android:state_checkable=["true" | "false"] + * android:state_checked=["true" | "false"] + * android:state_enabled=["true" | "false"] + * android:state_activated=["true" | "false"] + * android:state_window_focused=["true" | "false"] /> + * + */ + private var selectorPressedColor: Int = 0 + private var selectorDisableColor: Int = 0 + private var selectorNormalColor: Int = 0 + + private var useSelector: Boolean = false + + fun setShapeType(shapeType: Int): ShapeBuilder { + this.shapeType = shapeType + return this + } + + fun setShapeSolidColor(color: Int): ShapeBuilder { + this.solidColor = color + return this + } + + fun setShapeCornersRadius(radius: Float): ShapeBuilder { + this.cornersRadius = radius + return this + } + + fun setShapeCornersTopLeftRadius(radius: Float): ShapeBuilder { + this.cornersTopLeftRadius = radius + return this + } + + fun setShapeCornersTopRightRadius(radius: Float): ShapeBuilder { + this.cornersTopRightRadius = radius + return this + } + + fun setShapeCornersBottomRightRadius(radius: Float): ShapeBuilder { + this.cornersBottomRightRadius = radius + return this + } + + fun setShapeCornersBottomLeftRadius(radius: Float): ShapeBuilder { + this.cornersBottomLeftRadius = radius + return this + } + + fun setShapeStrokeWidth(strokeWidth: Int): ShapeBuilder { + this.strokeWidth = strokeWidth + return this + } + + fun setShapeStrokeColor(strokeColor: Int): ShapeBuilder { + this.strokeColor = strokeColor + return this + } + + fun setShapeStrokeDashWidth(strokeDashWidth: Float): ShapeBuilder { + this.strokeDashWidth = strokeDashWidth + return this + } + + fun setShapeStrokeDashGap(strokeDashGap: Float): ShapeBuilder { + this.strokeDashGap = strokeDashGap + return this + } + + fun setShapeUseSelector(useSelector: Boolean): ShapeBuilder { + this.useSelector = useSelector + return this + } + + fun setShapeSelectorPressedColor(color: Int): ShapeBuilder { + this.selectorPressedColor = color + return this + } + + fun setShapeSelectorNormalColor(color: Int): ShapeBuilder { + this.selectorNormalColor = color + return this + } + + fun setShapeSelectorDisableColor(color: Int): ShapeBuilder { + this.selectorDisableColor = color + return this + } + + fun setShapeSizeWidth(sizeWidth: Int): ShapeBuilder { + this.sizeWidth = sizeWidth + return this + } + + fun setShapeSizeHeight(sizeHeight: Int): ShapeBuilder { + this.sizeHeight = sizeHeight + return this + } + + fun setShapeGradientAngle(gradientAngle: Int): ShapeBuilder { + this.gradientAngle = gradientAngle + return this + } + + fun setShapeGradientCenterX(gradientCenterX: Int): ShapeBuilder { + this.gradientCenterX = gradientCenterX + return this + } + + fun setShapeGradientCenterY(gradientCenterY: Int): ShapeBuilder { + this.gradientCenterY = gradientCenterY + return this + } + + fun setShapeGradientGradientRadius(gradientGradientRadius: Int): ShapeBuilder { + this.gradientGradientRadius = gradientGradientRadius + return this + } + + fun setShapeGradientStartColor(gradientStartColor: Int): ShapeBuilder { + this.gradientStartColor = gradientStartColor + return this + } + + fun setShapeGradientCenterColor(gradientCenterColor: Int): ShapeBuilder { + this.gradientCenterColor = gradientCenterColor + return this + } + + fun setShapeGradientEndColor(gradientEndColor: Int): ShapeBuilder { + this.gradientEndColor = gradientEndColor + return this + } + + fun setShapeGradientType(gradientType: Int): ShapeBuilder { + this.gradientType = gradientType + return this + } + + fun setShapeGradientUseLevel(gradientUseLevel: Boolean): ShapeBuilder { + this.gradientUseLevel = gradientUseLevel + return this + } + + + private fun setShapeType(gradientDrawable: GradientDrawable) { + if (shapeType != -1) { + when (shapeType) { + RECTANGLE -> gradientDrawable.shape = GradientDrawable.RECTANGLE + OVAL -> gradientDrawable.shape = GradientDrawable.OVAL + LINE -> gradientDrawable.shape = GradientDrawable.LINE + RING -> gradientDrawable.shape = GradientDrawable.RING + } + } + } + + + private fun setSize(gradientDrawable: GradientDrawable) { + if (sizeWidth > 0 || sizeHeight > 0) { + gradientDrawable.setSize(sizeWidth, sizeHeight) + } + } + + /** + * 设置边框 宽度 颜色 虚线 间隙 + */ + private fun setBorder(gradientDrawable: GradientDrawable) { + if (strokeWidth >= 0) { + gradientDrawable.setStroke(strokeWidth, strokeColor, strokeDashWidth, strokeDashGap) + } + } + + /** + * 只有类型是矩形的时候设置圆角半径才有效 + */ + private fun setRadius(gradientDrawable: GradientDrawable) { + if (shapeType == RECTANGLE) { + if (cornersRadius != 0f) { + gradientDrawable.cornerRadius = cornersRadius + } else { + if (cornersTopLeftRadius != 0f || cornersTopRightRadius != 0f || cornersBottomRightRadius != 0f || cornersBottomLeftRadius != 0f) { + //1、2两个参数表示左上角,3、4表示右上角,5、6表示右下角,7、8表示左下角 + gradientDrawable.cornerRadii = floatArrayOf(cornersTopLeftRadius, cornersTopLeftRadius, cornersTopRightRadius, cornersTopRightRadius, cornersBottomRightRadius, cornersBottomRightRadius, cornersBottomLeftRadius, cornersBottomLeftRadius) + } + } + } + } + + + private fun setSolidColor(gradientDrawable: GradientDrawable) { + if (solidColor != -1 && gradientStartColor == -1 && gradientEndColor == -1) { + gradientDrawable.setColor(solidColor) + } + } + + + /** + * 设置Selector的不同状态的颜色 + * + * @param state 按钮状态 + */ + private fun setSelectorColor(gradientDrawable: GradientDrawable, state: Int) { + if (useSelector && state != 0) { + when (state) { + android.R.attr.state_pressed -> gradientDrawable.setColor(selectorPressedColor) + -android.R.attr.state_enabled -> gradientDrawable.setColor(selectorDisableColor) + android.R.attr.state_enabled -> gradientDrawable.setColor(selectorNormalColor) + } + } + } + + + /** + * 设置背景颜色 + * 如果设定的有Orientation 就默认为是渐变色的Button,否则就是纯色的Button + */ + private fun setGradient(gradientDrawable: GradientDrawable) { + if (gradientStartColor != -1 || gradientEndColor != -1) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + if (gradientCenterColor == -1) { + gradientDrawable.colors = intArrayOf(gradientStartColor, gradientEndColor) + } else { + gradientDrawable.colors = intArrayOf(gradientStartColor, gradientCenterColor, gradientEndColor) + } + when (gradientType) { + LINEAR -> { + gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT + if (gradientAngle != -1) { + gradientDrawable.orientation = getGradientOrientationByAngle(gradientAngle) + } + } + RADIAL -> { + gradientDrawable.gradientType = GradientDrawable.RADIAL_GRADIENT + gradientDrawable.gradientRadius = gradientGradientRadius.toFloat() + } + SWEEP -> gradientDrawable.gradientType = GradientDrawable.SWEEP_GRADIENT + } + if (gradientCenterX != 0 || gradientCenterY != 0) { + gradientDrawable.setGradientCenter(gradientCenterX.toFloat(), gradientCenterY.toFloat()) + } + gradientDrawable.useLevel = gradientUseLevel + } + } + } + + + /** + * 设置颜色渐变类型 + * + * @param gradientAngle gradientAngle + * @return Orientation + */ + private fun getGradientOrientationByAngle(gradientAngle: Int): GradientDrawable.Orientation? { + var orientation: GradientDrawable.Orientation? = null + when (gradientAngle) { + 0 -> orientation = GradientDrawable.Orientation.LEFT_RIGHT + 45 -> orientation = GradientDrawable.Orientation.BL_TR + 90 -> orientation = GradientDrawable.Orientation.BOTTOM_TOP + 135 -> orientation = GradientDrawable.Orientation.BR_TL + 180 -> orientation = GradientDrawable.Orientation.RIGHT_LEFT + 225 -> orientation = GradientDrawable.Orientation.TR_BL + 270 -> orientation = GradientDrawable.Orientation.TOP_BOTTOM + 315 -> orientation = GradientDrawable.Orientation.TL_BR + } + return orientation + } + + /** + * 获取设置之后的Selector + * 注意该处的顺序,只要有一个状态与之相配,背景就会被换掉 所以不要把大范围放在前面了, + * 如果sd.addState(new[]{},normal)放在第一个的话,就没有什么效果了 + * @return stateListDrawable + */ + private val selectorDrawable: StateListDrawable + get() { + val stateListDrawable = StateListDrawable() + stateListDrawable.addState(intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled), getDrawable(android.R.attr.state_pressed)) + stateListDrawable.addState(intArrayOf(-android.R.attr.state_enabled), getDrawable(-android.R.attr.state_enabled)) + stateListDrawable.addState(intArrayOf(), getDrawable(android.R.attr.state_enabled)) + return stateListDrawable + } + + private fun getDrawable(state: Int): GradientDrawable { + val gradientDrawable = GradientDrawable() + setShapeType(gradientDrawable) + setGradient(gradientDrawable) + setSolidColor(gradientDrawable) + setBorder(gradientDrawable) + setRadius(gradientDrawable) + setSize(gradientDrawable) + setSelectorColor(gradientDrawable, state) + return gradientDrawable + } + + fun into(view: View) { + ViewCompat.setBackground(view, if (useSelector) selectorDrawable else getDrawable(0)) + } + + /** + * 单位转换工具类 + * + * @param context 上下文对象 + * @param dipValue 值 + * @return 返回值 + */ + private fun dip2px(context: Context, dipValue: Float): Int { + val scale = context.resources.displayMetrics.density + return (dipValue * scale + 0.5f).toInt() + } +} diff --git a/library/src/main/java/com/allen/library/shape/ShapeButton.kt b/library/src/main/java/com/allen/library/shape/ShapeButton.kt new file mode 100644 index 0000000..36ae7f5 --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeButton.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.support.v7.widget.AppCompatButton +import android.util.AttributeSet +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatButton(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeCardView.kt b/library/src/main/java/com/allen/library/shape/ShapeCardView.kt new file mode 100644 index 0000000..f8d8dbf --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeCardView.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.support.v7.widget.CardView +import android.util.AttributeSet +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeCardView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : CardView(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeConstraintLayout.kt b/library/src/main/java/com/allen/library/shape/ShapeConstraintLayout.kt new file mode 100644 index 0000000..881f40c --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeConstraintLayout.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.support.constraint.ConstraintLayout +import android.util.AttributeSet +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeConstraintLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ConstraintLayout(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeFrameLayout.kt b/library/src/main/java/com/allen/library/shape/ShapeFrameLayout.kt new file mode 100644 index 0000000..0be81ff --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeFrameLayout.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeFrameLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeLinearLayout.kt b/library/src/main/java/com/allen/library/shape/ShapeLinearLayout.kt new file mode 100644 index 0000000..e911aea --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeLinearLayout.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.util.AttributeSet +import android.widget.LinearLayout +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeLinearLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeRelativeLayout.kt b/library/src/main/java/com/allen/library/shape/ShapeRelativeLayout.kt new file mode 100644 index 0000000..ed2f06c --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeRelativeLayout.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.util.AttributeSet +import android.widget.RelativeLayout +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : RelativeLayout(context, attrs, defStyleAttr) { + private var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/shape/ShapeTextView.kt b/library/src/main/java/com/allen/library/shape/ShapeTextView.kt new file mode 100644 index 0000000..804786e --- /dev/null +++ b/library/src/main/java/com/allen/library/shape/ShapeTextView.kt @@ -0,0 +1,24 @@ +package com.allen.library.shape + +import android.content.Context +import android.support.v7.widget.AppCompatTextView +import android.util.AttributeSet +import com.allen.library.helper.AttributeSetHelper +import com.allen.library.helper.ShapeBuilder + +/** + *
+ *      @author : Allen
+ *      e-mail  : lygttpod@163.com
+ *      date    : 2019/09/09
+ *      desc    :
+ * 
+ */ +class ShapeTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatTextView(context, attrs, defStyleAttr) { + var shapeBuilder: ShapeBuilder = ShapeBuilder() + + init { + shapeBuilder = AttributeSetHelper().initShapeBuilderFromAttributeSet(context, attrs) + shapeBuilder.into(this) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/allen/library/utils/ShapeBuilder.java b/library/src/main/java/com/allen/library/utils/ShapeBuilder.java deleted file mode 100644 index 4688fc4..0000000 --- a/library/src/main/java/com/allen/library/utils/ShapeBuilder.java +++ /dev/null @@ -1,486 +0,0 @@ -package com.allen.library.utils; - -import android.content.Context; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.StateListDrawable; -import android.os.Build; -import android.view.View; - -/** - *
- *      @author : Allen
- *      e-mail  : lygttpod@163.com
- *      date    : 2019/05/27
- *      desc    : shape构造器
- * 
- */ -public class ShapeBuilder { - - /** - * shape的样式 - */ - public static final int RECTANGLE = 0; - public static final int OVAL = 1; - public static final int LINE = 2; - public static final int RING = 3; - - /** - * android:shape=["rectangle" | "oval" | "line" | "ring"] - */ - private int shapeType = -1; - - /** - * - */ - private int solidColor = -1; - - /** - * - */ - private int strokeWidth = -1; - private int strokeColor = -1; - private float strokeDashWidth = 0.0f; - private float strokeDashGap = 0.0f; - - /** - * - */ - private float cornersRadius = 0.0f; - private float cornersTopLeftRadius = 0.0f; - private float cornersTopRightRadius = 0.0f; - private float cornersBottomLeftRadius = 0.0f; - private float cornersBottomRightRadius = 0.0f; - - /** - * - * 参数对应关系 - */ - - //渐变色的显示方式 - public static final int TOP_BOTTOM = 0; - public static final int TR_BL = 1; - public static final int RIGHT_LEFT = 2; - public static final int BR_TL = 3; - public static final int BOTTOM_TOP = 4; - public static final int BL_TR = 5; - public static final int LEFT_RIGHT = 6; - public static final int TL_BR = 7; - - private int gradientAngle = -1; - private int gradientCenterX; - private int gradientCenterY; - private int gradientGradientRadius; - - private int gradientStartColor; - private int gradientCenterColor; - private int gradientEndColor; - - private int gradientType; - - public static final int LINEAR = 0; - public static final int RADIAL = 1; - public static final int SWEEP = 2; - - private boolean gradientUseLevel; - - /** - * - */ - private int sizeWidth = -1; - private int sizeHeight = -1; - - /** - * - * - * - */ - private int selectorPressedColor; - private int selectorDisableColor; - private int selectorNormalColor; - - private boolean useSelector; - - public ShapeBuilder() { - } - - public ShapeBuilder setShapeType(int shapeType) { - this.shapeType = shapeType; - return this; - } - - public ShapeBuilder setShapeSolidColor(int color) { - this.solidColor = color; - return this; - } - - public ShapeBuilder setShapeCornersRadius(float radius) { - this.cornersRadius = radius; - return this; - } - - public ShapeBuilder setShapeCornersTopLeftRadius(float radius) { - this.cornersTopLeftRadius = radius; - return this; - } - - public ShapeBuilder setShapeCornersTopRightRadius(float radius) { - this.cornersTopRightRadius = radius; - return this; - } - - public ShapeBuilder setShapeCornersBottomRightRadius(float radius) { - this.cornersBottomRightRadius = radius; - return this; - } - - public ShapeBuilder setShapeCornersBottomLeftRadius(float radius) { - this.cornersBottomLeftRadius = radius; - return this; - } - - public ShapeBuilder setShapeStrokeWidth(int strokeWidth) { - this.strokeWidth = strokeWidth; - return this; - } - - public ShapeBuilder setShapeStrokeColor(int strokeColor) { - this.strokeColor = strokeColor; - return this; - } - - public ShapeBuilder setShapeStrokeDashWidth(float strokeDashWidth) { - this.strokeDashWidth = strokeDashWidth; - return this; - } - - public ShapeBuilder setShapeStrokeDashGap(float strokeDashGap) { - this.strokeDashGap = strokeDashGap; - return this; - } - - public ShapeBuilder setShapeUseSelector(boolean useSelector) { - this.useSelector = useSelector; - return this; - } - - public ShapeBuilder setShapeSelectorPressedColor(int color) { - this.selectorPressedColor = color; - return this; - } - - public ShapeBuilder setShapeSelectorNormalColor(int color) { - this.selectorNormalColor = color; - return this; - } - - public ShapeBuilder setShapeSelectorDisableColor(int color) { - this.selectorDisableColor = color; - return this; - } - - public ShapeBuilder setShapeSizeWidth(int sizeWidth) { - this.sizeWidth = sizeWidth; - return this; - } - - public ShapeBuilder setShapeSizeHeight(int sizeHeight) { - this.sizeHeight = sizeHeight; - return this; - } - - public ShapeBuilder setShapeGradientAngle(int gradientAngle) { - this.gradientAngle = gradientAngle; - return this; - } - - public ShapeBuilder setShapeGradientCenterX(int gradientCenterX) { - this.gradientCenterX = gradientCenterX; - return this; - } - - public ShapeBuilder setShapeGradientCenterY(int gradientCenterY) { - this.gradientCenterY = gradientCenterY; - return this; - } - - public ShapeBuilder setShapeGradientGradientRadius(int gradientGradientRadius) { - this.gradientGradientRadius = gradientGradientRadius; - return this; - } - - public ShapeBuilder setShapeGradientStartColor(int gradientStartColor) { - this.gradientStartColor = gradientStartColor; - return this; - } - - public ShapeBuilder setShapeGradientCenterColor(int gradientCenterColor) { - this.gradientCenterColor = gradientCenterColor; - return this; - } - - public ShapeBuilder setShapeGradientEndColor(int gradientEndColor) { - this.gradientEndColor = gradientEndColor; - return this; - } - - public ShapeBuilder setShapeGradientType(int gradientType) { - this.gradientType = gradientType; - return this; - } - - public ShapeBuilder setShapeGradientUseLevel(boolean gradientUseLevel) { - this.gradientUseLevel = gradientUseLevel; - return this; - } - - - private void setShapeType(GradientDrawable gradientDrawable) { - if (shapeType != -1) { - switch (shapeType) { - case RECTANGLE: - gradientDrawable.setShape(GradientDrawable.RECTANGLE); - break; - case OVAL: - gradientDrawable.setShape(GradientDrawable.OVAL); - break; - case LINE: - gradientDrawable.setShape(GradientDrawable.LINE); - break; - case RING: - gradientDrawable.setShape(GradientDrawable.RING); - break; - } - } - } - - - private void setSize(GradientDrawable gradientDrawable) { - if (sizeWidth > 0 || sizeHeight > 0) { - gradientDrawable.setSize(sizeWidth, sizeHeight); - } - } - - /** - * 设置边框 宽度 颜色 虚线 间隙 - */ - private void setBorder(GradientDrawable gradientDrawable) { - if (strokeWidth >= 0) { - gradientDrawable.setStroke(strokeWidth, strokeColor, strokeDashWidth, strokeDashGap); - } - } - - /** - * 只有类型是矩形的时候设置圆角半径才有效 - */ - private void setRadius(GradientDrawable gradientDrawable) { - if (shapeType == RECTANGLE) { - if (cornersRadius != 0) { - gradientDrawable.setCornerRadius(cornersRadius); - } else { - if (cornersTopLeftRadius != 0 || cornersTopRightRadius != 0 || cornersBottomRightRadius != 0 || cornersBottomLeftRadius != 0) { - //1、2两个参数表示左上角,3、4表示右上角,5、6表示右下角,7、8表示左下角 - gradientDrawable.setCornerRadii( - new float[] - { - cornersTopLeftRadius, cornersTopLeftRadius, - cornersTopRightRadius, cornersTopRightRadius, - cornersBottomRightRadius, cornersBottomRightRadius, - cornersBottomLeftRadius, cornersBottomLeftRadius - } - ); - } - - } - } - } - - - private void setSolidColor(GradientDrawable gradientDrawable) { - if (solidColor != -1) { - gradientDrawable.setColor(solidColor); - } - } - - - /** - * 设置Selector的不同状态的颜色 - * - * @param state 按钮状态 - */ - private void setSelectorColor(GradientDrawable gradientDrawable, int state) { - if (useSelector && state != 0) { - switch (state) { - case android.R.attr.state_pressed: - gradientDrawable.setColor(selectorPressedColor); - break; - case -android.R.attr.state_enabled: - gradientDrawable.setColor(selectorDisableColor); - break; - case android.R.attr.state_enabled: - gradientDrawable.setColor(selectorNormalColor); - break; - } - } - } - - - /** - * 设置背景颜色 - * 如果设定的有Orientation 就默认为是渐变色的Button,否则就是纯色的Button - */ - private void setGradient(GradientDrawable gradientDrawable) { - if (gradientAngle != -1) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - gradientDrawable.setOrientation(getGradientOrientationByAngle(gradientAngle)); - - if (gradientCenterColor == -1) { - gradientDrawable.setColors(new int[]{gradientStartColor, gradientEndColor}); - } else { - gradientDrawable.setColors(new int[]{gradientStartColor, gradientCenterColor, gradientEndColor}); - } - - switch (gradientType) { - case LINEAR: - gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT); - break; - case RADIAL: - gradientDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT); - gradientDrawable.setGradientRadius(gradientGradientRadius); - break; - case SWEEP: - gradientDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT); - break; - } - - - gradientDrawable.setUseLevel(gradientUseLevel); - - if (gradientCenterX != 0 && gradientCenterY != 0) { - gradientDrawable.setGradientCenter(gradientCenterX, gradientCenterY); - } - } - } else { - setSolidColor(gradientDrawable); - } - } - - - /** - * 设置颜色渐变类型 - * - * @param gradientAngle gradientAngle - * @return Orientation - */ - private GradientDrawable.Orientation getGradientOrientationByAngle(int gradientAngle) { - GradientDrawable.Orientation orientation = null; - switch (gradientAngle) { - case 0: - orientation = GradientDrawable.Orientation.LEFT_RIGHT; - break; - case 45: - orientation = GradientDrawable.Orientation.BL_TR; - break; - case 90: - orientation = GradientDrawable.Orientation.BOTTOM_TOP; - break; - case 135: - orientation = GradientDrawable.Orientation.BR_TL; - break; - case 180: - orientation = GradientDrawable.Orientation.RIGHT_LEFT; - break; - case 225: - orientation = GradientDrawable.Orientation.TR_BL; - break; - case 270: - orientation = GradientDrawable.Orientation.TOP_BOTTOM; - break; - case 315: - orientation = GradientDrawable.Orientation.TL_BR; - break; - } - return orientation; - } - - - /** - * 获取设置之后的Selector - * - * @return stateListDrawable - */ - private StateListDrawable getSelectorDrawable() { - StateListDrawable stateListDrawable = new StateListDrawable(); - //注意该处的顺序,只要有一个状态与之相配,背景就会被换掉 - //所以不要把大范围放在前面了,如果sd.addState(new[]{},normal)放在第一个的话,就没有什么效果了 - stateListDrawable.addState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}, getDrawable(android.R.attr.state_pressed)); - stateListDrawable.addState(new int[]{-android.R.attr.state_enabled}, getDrawable(-android.R.attr.state_enabled)); - stateListDrawable.addState(new int[]{}, getDrawable(android.R.attr.state_enabled)); - return stateListDrawable; - } - - private GradientDrawable getDrawable(int state) { - GradientDrawable gradientDrawable = new GradientDrawable(); - setShapeType(gradientDrawable); - setGradient(gradientDrawable); - setBorder(gradientDrawable); - setRadius(gradientDrawable); - setSize(gradientDrawable); - setSelectorColor(gradientDrawable, state); - return gradientDrawable; - } - - - public void into(View view) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.setBackground(useSelector ? getSelectorDrawable() : getDrawable(0)); - } else { - view.setBackgroundDrawable(useSelector ? getSelectorDrawable() : getDrawable(0)); - } - } - - /** - * 单位转换工具类 - * - * @param context 上下文对象 - * @param dipValue 值 - * @return 返回值 - */ - private int dip2px(Context context, float dipValue) { - final float scale = context.getResources().getDisplayMetrics().density; - return (int) (dipValue * scale + 0.5f); - } -} diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index b578a89..a38d57e 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -425,4 +425,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file