kir*_*403 12 android android-radiogroup android-databinding
我正在互联网上搜索如何执行新的酷Android数据绑定RadioGroup,我没有找到一篇关于它的博客文章.
它是一个简单的场景,基于所选的单选按钮,我想使用android数据绑定附加一个回调事件.我没有在xml部分找到允许我定义回调的任何方法.
就像这里是我的RadioGroup:
<RadioGroup
android:id="@+id/split_type_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checkedButton="@+id/split_type_equal"
android:gravity="center"
<!-- which tag ? -->
android:orientation="horizontal">
...
</RadioGroup>
Run Code Online (Sandbox Code Playgroud)
我如何附上处理方法将被称为上RadioGroup的checkChnged事件将触发使用数据绑定?
我尝试onClick在布局文件中使用(不知道它是否相同)并在Activity中定义方法并在布局文件中使用它来定位它:
<variable
name="handler"
type="com.example.MainActivity"/>
...
<RadioGroup
android:onClick="handler.onCustomCheckChanged"
.. >
Run Code Online (Sandbox Code Playgroud)
并定义了这样的方法onCustomCheckChanged:
public void onCustomCheckChanged(RadioGroup radio, int id) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
但是,它给了我编译错误:
错误:(58,36)侦听器类android.view.View.OnClickListener与方法onClick不匹配任何方法handler.onCustomCheckChanged的签名
我见过很多博客提到它是可能的,RadioGroup但他们没有真正说出如何.我怎么处理这个data-binding?
kir*_*403 20
在深入研究这些方法之后,我在SO上发现了这个问题,这有助于我理解如何绑定单个侦听器方法.
以下是RadioGroup的用法:
在RadioGroup听众中你有一个方法onCheckedChanged(RadioGroup g, int id).因此,您可以通过将其实例作为布局文件中的变量传递并调用具有相同签名的方法,将该方法直接绑定到您的处理程序或您的活动.
所以调用布局文件如下:
<RadioGroup
android:id="@+id/split_type_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checkedButton="@+id/split_type_equal"
android:gravity="center"
android:onCheckedChanged="@{handler.onSplitTypeChanged}"
android:orientation="horizontal">
...
</RadioGroup>
Run Code Online (Sandbox Code Playgroud)
在我的活动或处理程序中,我需要简单地为方法提供相同的名称和签名,如下所示:
public void onSplitTypeChanged(RadioGroup radioGroup,int id) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
只要确保方法是公开的.
注意:这适用于任何(大多数,我没有尝试过所有)监听器方法.喜欢EditText你可以提供android:onTextChanged等等.
Jua*_*dez 13
我正在使用一个字符串,在这种情况下我有绑定基于 viewModel.getCommuteType() viewModel.setCommuteType(String)
<RadioGroup
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:checked="@{viewModel.commuteType.equals(Commute.DRIVING)}"
android:onClick="@{()->viewModel.setCommuteType(Commute.DRIVING)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D"/>
<RadioButton
android:checked="@{viewModel.commuteType.equals(Commute.BICYCLE)}"
android:onClick="@{()->viewModel.setCommuteType(Commute.BICYCLE)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"/>
<RadioButton
android:checked="@{viewModel.commuteType.equals(Commute.WALKING)}"
android:onClick="@{()->viewModel.setCommuteType(Commute.WALKING)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="W"/>
<RadioButton
android:checked="@{viewModel.commuteType.equals(Commute.BUS)}"
android:onClick="@{()->viewModel.setCommuteType(Commute.BUS)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="T"/>
Run Code Online (Sandbox Code Playgroud)
几个小时后,我发现了一种简单的方法:在android中进行双向数据绑定。它是livedata和Kotlin 的基本骨架。您也可以使用ObservableField()
layout.xml
<data>
<variable
name="VM"
type="...YourViewModel" />
</data>
<LinearLayout
android:id="@+id/settings_block_env"
...
>
<RadioGroup
android:id="@+id/env_radioGroup"
android:checkedButton="@={VM.radio_checked}">
<RadioButton
android:id="@+id/your_id1"/>
<RadioButton
android:id="@+id/your_id2" />
<RadioButton
android:id="@+id/your_id3"/>
<RadioButton
android:id="@+id/your_id4"/>
</RadioGroup>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
class YourViewModel(): ViewModel {
var radio_checked = MutableLiveData<Int>()
init{
radio_checked.postValue(R.id.your_id1)//def value
}
//other code
}
Run Code Online (Sandbox Code Playgroud)
通常你更关心什么实际上是检查,而不是“东西被检查”。在这种情况下,替代解决方案是忽略 RadioGroup 并绑定所有项目,如下所示:
<RadioGroup (...) >
<RadioButton (...)
android:checked="@={viewModel.optionA}"/>
<RadioButton (...)
android:checked="@={viewModel.optionB}"/>
<RadioButton (...)
android:checked="@={viewModel.optionC}"/>
</RadioGroup>
Run Code Online (Sandbox Code Playgroud)
其中 optionA、optionB 和 optionC 在 ViewModel 中定义如下:
public final ObservableBoolean optionA = new ObservableBoolean();
public final ObservableBoolean optionB = new ObservableBoolean();
public final ObservableBoolean optionC = new ObservableBoolean();
Run Code Online (Sandbox Code Playgroud)
这通常就足够了,但是如果您想在点击时立即做出反应,那么您可以添加回调并像这样使用它们:
OnPropertyChangedCallback userChoosedA = new OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
(...) // basically propertyId can be ignored in such case
}
};
optionA.addOnPropertyChangedCallback(userChoosedA);
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是您不需要比较和跟踪“id”。
在我当前的项目中,我是这样做的。我的项目中有三种货币,我通过 RadioGroup 选择其中一种。
它是货币枚举:
enum class Currency(val value: Byte) {
USD(0),
EUR(1),
RUB(2);
companion object Create {
fun from(sourceValue: Byte): Currency = values().first { it.value == sourceValue }
fun from(sourceValue: String): Currency = values().first { it.toString() == sourceValue }
}
}
Run Code Online (Sandbox Code Playgroud)
我的 ViewModel 的一部分:
class BaseCurrencyViewModel : ViewModelBase<BaseCurrencyModelInterface>() {
/**
* Selected currency
*/
val currency: MutableLiveData<Currency> = MutableLiveData()
/**
*
*/
init {
currency.value = Currency.USD // Init value
}
}
Run Code Online (Sandbox Code Playgroud)
我的布局的一部分(注意RadioGroup和RadioButton标签中的绑定):
<RadioGroup
android:id="@+id/currencySwitchers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:selectedCurrency = "@{viewModel.currency}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent">
<RadioButton
android:id="@+id/usdSwitcher"
android:text="USD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="USD"
/>
<RadioButton
android:id="@+id/eurSwitcher"
android:text="EUR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="EUR"
/>
<RadioButton
android:id="@+id/rubSwitcher"
android:text="RUB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="RUB"
/>
</RadioGroup>
Run Code Online (Sandbox Code Playgroud)
最后一部分 - 绑定适配器。
@BindingAdapter("selectedCurrency")
fun setSelectedCurrency(view: View, value: MutableLiveData<Currency>?) {
view.getParentActivity()?.let { parentActivity ->
value?.observe(parentActivity, Observer { value ->
view.findViewWithTag<RadioButton>(value.toString())
?.also {
if(!it.isChecked) {
it.isChecked = true
}
}
}
)
(view as RadioGroup).setOnCheckedChangeListener { radioGroup, checkedId ->
val currency = Currency.from(radioGroup.findViewById<RadioButton>(checkedId).tag as String)
if(value != null && value.value != currency) {
value.value = currency
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我在 RadioGroup 和 ViewModel 中的属性之间进行了双向绑定。
| 归档时间: |
|
| 查看次数: |
12872 次 |
| 最近记录: |