通过数据绑定设置条目时,旋转程序获得空适配器

问题描述 投票:1回答:1

我正在使用像这样的数据绑定将条目添加到android中的AppCompatSpinner

   <androidx.appcompat.widget.AppCompatSpinner
        android:id="@+id/spinner2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/textInputLayout14"
        app:layout_constraintTop_toBottomOf="@+id/textInputLayout14"
        android:entries="@{viewModel.arrays}"
        app:selectedValue="@={viewModel.beneficiary.mandal}"
        />

ViewModel中的数组属性是:

private String[] arrays=new String[]{"Hello","Hi","Bye"};
    @Bindable
    public String[] getArrays() {
        return arrays;
    }

    public void setArrays(String[] arrays) {
        this.arrays = arrays;
    }

但是问题是我在Binding adapter中得到了空适配器:

 @BindingAdapter(value = {"selectedValue", "selectedValueAttrChanged"}, requireAll = false)
    public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InverseBindingListener newTextAttrChanged) {
        pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                newTextAttrChanged.onChange();
                Log.d(TAG, "onItemSelected: "+newSelectedValue);
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        if (newSelectedValue != null) {
            if(pAppCompatSpinner.getAdapter()!=null) {
                int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue);
                pAppCompatSpinner.setSelection(pos, true);
            }else{
                Log.d(TAG, "Adapter NULL: ");
            }
        }
    }


    @InverseBindingAdapter(attribute = "selectedValue", event = "selectedValueAttrChanged")
    public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) {
        return (String) pAppCompatSpinner.getSelectedItem();
    }

我的适配器为空,并且所选的值也未反映在viewmodel中。而且,当我使用@array/stringArr设置条目时,它的工作没有任何问题

android mvvm android-databinding android-viewmodel
1个回答
0
投票

这是我用于通过BindingAdapter在XML中绑定Spinner的代码。XML:

<data>
    <import type="java.util.List" />
    <variable
        name="stateData"
        type="List&lt;com.xyz.model.remote.result.State>" />
</data>

<androidx.appcompat.widget.AppCompatSpinner
    android:id="@+id/spState"
    android:layout_width="0dp"
    android:layout_height="@dimen/_30sdp"
    android:layout_marginTop="@dimen/_5sdp"
    android:backgroundTint="@color/textColor"
    android:minWidth="0dp"
    android:minHeight="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/ivState"
    app:layout_constraintTop_toTopOf="parent"
    bind:listitem="@layout/item_view"
    bind:onStateSelected="@{viewModel.onStateSelectedListener}"
    bind:selectedStateId="@={viewModel.signUpFormFields.stateId}"
    bind:states="@{stateData}" />

BindingAdapter.kt

@BindingAdapter(
    value = ["states", "defaultSelectedId", "onStateSelected", "selectedStateId", "selectedStateIdAttrChanged"],
    requireAll = false
)
@JvmStatic
fun bindStateSpinnerEntries(
    spinner: AppCompatSpinner,
    stateList: List<State>? = arrayListOf(),
    selectedId: Int? = -1,
    itemSelectedListener: AdapterView.OnItemSelectedListener,
    newId: Int?,
    idAttrChanged: InverseBindingListener
) {

    if (stateList == null) {
        val tempList = arrayListOf<State>()
        tempList.add(0, State(-1, -1, spinner.context.getString(R.string.login_state_hint)))
        spinner.adapter = StateSpAdapter(
            spinner.context,
            R.layout.item_dropdown,
            R.layout.item_view,
            tempList
        )
        spinner.setSelection(0)
        return
    }
    (stateList as ArrayList).add(
        0,
        State(-1, -1, spinner.context.getString(R.string.login_state_hint))
    )
    spinner.adapter = StateSpAdapter(
        spinner.context,
        R.layout.item_dropdown,
        R.layout.item_view,
        stateList
    )
    var selectedPos = 0
    if (selectedId != null) {
        for (state in stateList) {
            if (state.id == selectedId) {
                break
            }
            selectedPos++
        }
    }

    if (selectedPos < stateList.size) spinner.setSelection(selectedPos) else spinner.setSelection(
        0
    )
    spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(
            parent: AdapterView<*>,
            view: View,
            position: Int,
            id: Long
        ) {
            idAttrChanged.onChange()
            itemSelectedListener.onItemSelected(parent, view, position, id)
        }

        override fun onNothingSelected(parent: AdapterView<*>) {}
    }
}

@InverseBindingAdapter(
    attribute = "selectedStateId",
    event = "selectedStateIdAttrChanged"
)
@JvmStatic
fun captureSelectedStateId(powerSpinnerView: AppCompatSpinner): Int {
    return (powerSpinnerView.selectedItem as State).id
}

ViewModel

观察状态更改侦听器。

val onStateSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onNothingSelected(parent: AdapterView<*>?) {

        }

        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
            stateReceived.postValue(true)
            errState.postValue(false)
        }
    }

片段中,观察并绑定状态列表。

mFragmentBinding.stateData = stateList
© www.soinside.com 2019 - 2024. All rights reserved.