Я создаю пользовательское представление, которое имеет несколько пользовательских атрибутов, два из которых являются перечислениями.Я использую привязку данных и MutableLiveData для обновления моих представлений.Это работает без проблем, но у меня возникают проблемы с тем, чтобы заставить его работать с моим enum.Кто-нибудь может помочь?
Все примеры кода были обрезаны, чтобы показать только то, что связано с проблемой.Если что-то важное отсутствует, пожалуйста, укажите это.Это мой макет:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<variable
name="viewModel"
type="com.myapp.wifi.WifiItemViewModel"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/margin_16"
android:paddingBottom="@dimen/margin_16"
>
<components.wifi.WifiIconComponent
android:id="@+id/img_wifi_icon"
style="@style/WrapContent"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginEnd="8dp"
app:wifiState="@{viewModel.wifiState}"
app:termsAndConditionsAccepted="@{viewModel.termsAccepted}"
app:layout_constraintEnd_toEndOf="@id/guideline_start"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/text_wifi_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="@style/H5"
android:text="@{viewModel.wifiName}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/guideline_start"
app:layout_constraintEnd_toEndOf="@id/guideline_end"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Мой пользовательский вид - WifiIconComponent
.Вот как я объявляю его пользовательские атрибуты в attrs.xml
:
<declare-styleable name="WifiIconComponent">
<attr name="wifiState" format="enum">
<enum name="NotAdded" value="0"/>
<enum name="NotAvailable" value="1"/>
<enum name="Available" value="2"/>
<enum name="ConnectedWithoutInternet" value="3"/>
<enum name="Connected" value="4"/>
</attr>
<attr name="termsAndConditionsAccepted" format="boolean"/>
<attr name="iconSizing" format="enum">
<enum name="small" value="0"/>
<enum name="medium" value="1"/>
<enum name="large" value="2"/>
</attr>
</declare-styleable>
И это файл класса представления:
class WifiIconComponent @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ImageView(context, attrs, defStyleAttr) {
private var wifiState = WifiState.NOT_ADDED
private var termsAndConditionsAccepted = false
private var iconSize = WifiIconSize.SMALL
init {
attrs?.let {
val attributes = context.obtainStyledAttributes(it, R.styleable.WifiIconComponent)
termsAndConditionsAccepted =
attributes.getBoolean(R.styleable.WifiIconComponent_termsAndConditionsAccepted, false)
iconSize = WifiIconSize.values()[attributes.getInt(R.styleable.WifiIconComponent_iconSizing, 0)]
wifiState = WifiState.values()[attributes.getInt(R.styleable.WifiIconComponent_wifiState, 0)]
attributes.recycle()
}
setImageDrawable(getStateIcon())
}
private fun getStateIcon(): Drawable? {
val resource = when (iconSize) {
WifiIconSize.SMALL -> getSmallIcon()
WifiIconSize.MEDIUM -> getMediumIcon()
WifiIconSize.LARGE -> getLargeIcon()
}
return context.getDrawable(resource)
}
// rest of class
}
Это модель представления, указанная в макете:
class WifiItemViewModel(state: WifiConnectionState, val termsAccepted: Boolean) {
val description = dummyArg.description
var wifiState = MutableLiveData(state.wifiState)
val wifiStateAsString = MutableLiveData(wifiState.value.toString())
val wifiName = MutableLiveData(state.name)
val switchVisibility = MutableLiveData(View.GONE)
val activationState = MutableLiveData(state.isActivated)
// the rest of the class is unrelated to the problem
}
Теперь, если я просто установлю любое значение в макете, например, app:wifiState="Connected"
, все будет работать нормально.В блоке init заданное значение корректно переводится в правильное состояние моего перечисления в коде:
enum class WifiState {
NOT_ADDED,
NOT_AVAILABLE,
AVAILABLE,
CONNECTED_WITHOUT_INTERNET,
CONNECTED_WITH_INTERNET
}
Но если я связываю его с MutableLiveData в моей viewModel (как я делаю в приведенном выше макете), я получаю эту ошибку:
****/ data binding error ****msg:Cannot find the setter for attribute 'app:wifiState' with parameter type androidx.lifecycle.MutableLiveData<components.wifi.WifiState> on components.wifi.WifiIconComponent.
Я предполагаю, что это связано с наличием в основном двух разных перечислений для одинаковых значений, одного в коде и одного в xml.Есть ли другой способ сделать это?Или, если мой подход в порядке, как мне заставить его работать?Кто может помочь?