我正在构建一个MultiStateToggle按钮。
要突出显示所选状态,我需要绘制一个矩形,该矩形恰好是按钮的大小。此矩形滑动到当前状态。因此,我需要进行绘制,但是无论我做什么,即使调用了onDraw,我也看不到任何变化。
超类ToggleButton仅包含一些常量。它扩展了LinearLayout
!
有人知道,为什么在这个LinearLayout子类中无法绘制图形?
class MultiStateToggleButton : ToggleButton {
//region Variables
private val mHighlightPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
@DrawableRes
private val iSelectableItemBackgroundDrawableResId: Int
private val mButtons = mutableListOf<Button>()
//endregion
constructor(context: Context) : this(context, Any() as AttributeSet)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
val mTypedValue = TypedValue()
context.theme.resolveAttribute(R.attr.colorPrimary, mTypedValue, true)
val iPrimaryColor = mTypedValue.data
context.theme.resolveAttribute(R.attr.colorPrimary, mTypedValue, true)
val iPrimaryDarkColor = mTypedValue.data
setBackgroundColor(iPrimaryDarkColor)
context.theme.resolveAttribute(R.attr.colorAccent, mTypedValue, true)
val iAccentColor = mTypedValue.data
val mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.MultiStateToggleButton)
foregroundColor = mTypedArray.getColor(R.styleable.MultiStateToggleButton_foregroundColor, iPrimaryColor)
highlightColor = mTypedArray.getColor(R.styleable.MultiStateToggleButton_highlightColor, iAccentColor)
val mTexts = mTypedArray.getTextArray(R.styleable.MultiStateToggleButton_elements)
if (mTexts != null) {
val iSelectedElement = mTypedArray.getInt(R.styleable.MultiStateToggleButton_selectedElement, 0)
setElements(Array(mTexts.size) { i ->
mTexts[i].toString()
}, iSelectedElement)
}
mTypedArray.recycle()
}
init {
val mTypedValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, mTypedValue, true)
iSelectableItemBackgroundDrawableResId = mTypedValue.resourceId
mHighlightPaint.apply {
color = highlightColor
style = Paint.Style.FILL
}
}
//region Public Variables
override var selectedElement: Int = 0
set(value) {
selectButton(value)
field = value
super.selectedElement = value
}
//endregion
//region Methods
fun setElements(texts: Array<String>) {
removeAllViews()
mButtons.clear()
texts.forEachIndexed { i, text ->
val mButton = Button(context).apply {
layoutParams = LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, LAYOUT_WEIGHT_EQUAL)
setBackgroundResource(iSelectableItemBackgroundDrawableResId)
setText(text)
setTextColor(textColor)
setOnClickListener { selectedElement = i }
}
mButtons.add(mButton)
addView(mButton)
}
}
fun setElements(texts: Array<String>, selectedItem: Int) {
setElements(texts)
selectButton(selectedItem)
}
override fun setEnabled(enabled: Boolean) {
for (i in 0 until childCount) {
getChildAt(i).isEnabled = enabled
}
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.drawRect(0f, 0f, 30f, 30f, mHighlightPaint)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
super.onLayout(changed, l, t, r, b)
setWillNotDraw(false)
}
override fun onSaveInstanceState(): Parcelable {
return Bundle().apply {
putParcelable(KEY_INSTANCE_STATE, super.onSaveInstanceState())
putInt(KEY_SELECTED_BUTTON, selectedElement)
}
}
override fun onRestoreInstanceState(state: Parcelable?) {
var mRestoredState: Parcelable? = state
if (state is Bundle) {
selectButton(state.getInt(KEY_SELECTED_BUTTON))
mRestoredState = state.getParcelable(KEY_INSTANCE_STATE)
}
super.onRestoreInstanceState(mRestoredState)
}
private fun selectButton(position: Int) {
if (mButtons.isNotEmpty()) {
if (position >= mButtons.size) {
throw IndexOutOfBoundsException("Position was $position but there are only ${mButtons.size} Buttons.")
}
getChildAt(selectedElement).isEnabled = true
getChildAt(position).isEnabled = false
invalidate()
}
}
//endregion
companion object {
private const val KEY_SELECTED_BUTTON = "mtb_selected_button"
private const val KEY_INSTANCE_STATE = "mtb_instance_state"
}
}
答案 0 :(得分:0)
当在主要构造函数调用中调用Kotlins的init
块时,我的Paint尚未初始化。