Я хочу динамически выбрать Drawable на основе выбранного состояния для представления . Я использовал логические состояния вместо строки, потому что строка не поддерживается согласно этой записи. Вот детали кода:
attrs. xml
<declare-styleable name="StateView">
<attr name="state_not_available" format="boolean" />
<attr name="state_idle" format="boolean" />
<attr name="state_busy" format="boolean" />
</declare-styleable>
selector_driver_state. xml
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto">
<item custom:state_not_available="true"
android:drawable="@drawable/drawable_icon_not_available"/>
<item custom:state_idle="true"
android:drawable="@drawable/drawable_icon_idle"/>
<item custom:state_busy="true"
android:drawable="@drawable/drawable_icon_busy"/>
<item android:drawable="@drawable/drawable_icon_busy" />
</selector>
StateView.kt
class StateView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private var STATE_NOT_AVAILABLE = intArrayOf(R.attr.state_not_available)
private var STATE_IDLE = intArrayOf(R.attr.state_idle)
private var STATE_BUSY = intArrayOf(R.attr.state_busy)
private var mStateNotAvail : Boolean = false
private var mStateIdle : Boolean = false
private var mStateBusy : Boolean = false
init {
initAttrs(context, attrs)
}
private fun initAttrs(context: Context, attrs: AttributeSet?) {
attrs?.let {
val attrArr = context.obtainStyledAttributes(attrs, R.styleable.StateView)
try {
mStateNotAvail = attrArr.getBoolean(R.styleable.StateView_state_not_available, false)
mStateIdle = attrArr.getBoolean(R.styleable.StateView_state_idle, false)
mStateBusy = attrArr.getBoolean(R.styleable.StateView_state_busy, false)
}
finally {
attrArr.recycle()
}
}
}
fun setStateBusy(state: Boolean) {
mStateNotAvail = false
mStateIdle = false
mStateBusy = state
invalidate()
requestLayout()
}
override fun onCreateDrawableState(extraSpace: Int): IntArray {
val drawableStates = super.onCreateDrawableState(extraSpace + 1)
if(mStateNotAvail)
mergeDrawableStates(drawableStates, STATE_NOT_AVAILABLE)
else if(mStateIdle)
mergeDrawableStates(drawableStates, STATE_IDLE)
else
mergeDrawableStates(drawableStates, STATE_BUSY)
return drawableStates
}
Использование:
<com.abc.package.components.StateView
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/viewState"
app:state_idle="true" ----> not working!
android:layout_marginLeft="10dp"/>
Проблема в том, что StateView
не выполняет рендеринг. Я попытался установить состояние программно, оно не работает так же хорошо, используя setStateBusy
. Какие-либо ведет? Спасибо.