Spinner Issue in MVVM architecture android

Viewed 393

When I rotate the screen the spinner reset though I am using MVVM architecture. While setting value I set value in view model, but still spinner reset to its orignal state.

In Main Activity I have done this,

    GetBusinessPartners.setOnItemSelectedListener(object:OnItemSelectedListener{
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
         dealMealPreApproval.initsetSpinnerIndex(position)
        }

        override fun onNothingSelected(parent: AdapterView<*>?) {
            TODO("Not yet implemented")
        }

    })

    dealMealPreApproval.getSpinnerValue().observe(this@DealMealPreApproval, Observer {
        GetBusinessPartners.setSelection(it)
    })

in view model i have done this

class MealPolicyViewModel : ViewModel() {

var businessPartners=MutableLiveData<ArrayList<BusinessPartnersModel>>()
var spinnerString=MutableLiveData<Int>()


fun initsetSpinnerIndex(valueOfSpinner:Int){
    spinnerString.value=valueOfSpinner
    Log.d("valueOfValueOFSPinner",valueOfSpinner.toString())

}

fun getSpinnerValue() : LiveData<Int>{

    return spinnerString
}

}

3 Answers

For A small data like double, boolean, string, int you should use onSavedInstance like this, for large amount of data view model will be used.

 override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("MySPinner", GetBusinessPartners.getSelectedItemPosition());

}

Then getValue Like this in OnCreate Method

var counter=0

 if (savedInstanceState != null) {

        counter = savedInstanceState.getInt("MySPinner", 0)

    }

After Spinner Adapter call SetSelection and pass counter in it like,

   ArrayAdapter<BusinessPartnersModel>(context, android.R.layout.simple_list_item_1, list)
            GetBusinessPartners.setSelection(counter)

I still recommend you to use viewmodel with livedata in this case. Please check my solution.

In the viewmodel, you create the livedata that you want to store the data to display on the view. I still recommend using MutableLiveData to set data for live data, and LiveData for view to get data.

class MealPolicyViewModel : ViewModel() {

    private val _businessPartners = MutableLiveData<ArrayList<BusinessPartnersModel>>()
    val businessPartners: LiveData<ArrayList<BusinessPartnersModel>> = _businessPartners

    private val _spinnerString = MutableLiveData<Int>()
    val spinnerString: LiveData<Int> = _spinnerString

    fun initsetSpinnerIndex(valueOfSpinner: Int){
        _spinnerString.value = valueOfSpinner
        Log.d("valueOfValueOFSPinner", valueOfSpinner.toString())
    }
}

In the view, specifically MainActivity, you initialize the viewModel through the lazy variable associated with the built-in extension of the activity-ktx library by viewModels(). Then you observe your livedata in onCreate().

class MainActivity : AppCompatActivity() {
    
    private val viewModel: MealPolicyViewModel by viewModels()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.spinnerString.observe(this) {
            // TODO do something.
        }
    }
}

As you know, livedata will always observe the lifecycle of the view. In case you rotate the screen, the livedata will observe again when you finish rotating the screen.

Try my implementation and let me know if you still get the error.

save the position in viewmodel,did u try that?but do not call it in spinner adapter after item selected, save it in onPasue and the save button(or ending to network button). this is how u get position:

binding.spinnerLessonModelName.selectedItemPosition
Related