【问题标题】:Orientation change is not preserved while using viewmodel使用视图模型时不保留方向更改
【发布时间】:2022-01-05 04:56:19
【问题描述】:

MVVM 清洁架构的新手。构建一个具有由回收器视图组成的单屏幕的应用程序。数据是通过改造获取的。根据文档,ViewModel 能够承受配置更改,但在我的情况下,当我将方向从纵向更改为横向时,它不起作用。不知道这个问题,请指教

**NewsViewModel.Kt**   

import android.util.Log
import androidx.lifecycle.*
import com.example.recyclerviewjsonarray.model.NewsList
import com.example.recyclerviewjsonarray.network.remote.RetrofitInstanceDto
import com.example.recyclerviewjsonarray.network.remote.RetrofitServiceDto
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

private const val TAG ="NewsViewModel"

//viewmodel for handling clean archietecture
 class NewsViewModel : ViewModel() {
    //Mutable live data for the news list
  private val _newsMutableLiveData: MutableLiveData<NewsList> = MutableLiveData()

  val newsMutableLiveData : LiveData<NewsList> get() =
      _newsMutableLiveData

    //viewmodel will observe the latest updated data with the help of mutable live data
   fun newsListObserver(): LiveData<NewsList> {
       return newsMutableLiveData
  }

    /* making an api call using viewmodel scope (custom coroutines scope can be used as well)
       launch is like a builder . Here it is launching Dispatcher.IO for memory intensive operation
       Now inside we will create synchronized retrofit instance and fetch the response
       in the form of getDataFromApi() with a delay of 2 seconds respectively
       post value is called lastly for setting the value from a background thread */


    fun getDataFromApi() {
        Log.i(TAG,"init")
        viewModelScope.launch(Dispatchers.IO) {
            val retrofitInstance = RetrofitInstanceDto.getRetrofitInstance().create(RetrofitServiceDto::class.java)
            val response = retrofitInstance.getDataFromApi()
            delay(1500)
            _newsMutableLiveData.postValue(response)
        }
    }


**NewsListFragment.kt**


import android.os.Bundle
import android.util.Log

import android.view.*
import androidx.fragment.app.Fragment
import android.widget.Toast

import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.recyclerviewjsonarray.R
import com.example.recyclerviewjsonarray.databinding.FragmentNewsListBinding
import com.example.recyclerviewjsonarray.model.NewsList
import kotlinx.android.synthetic.main.fragment_news_list.*

private const val TAG ="NewsListFragment"
//The view of MVVM architecture
class NewsListFragment : Fragment() {
   /* view binding with late init as dont want to redraw again n again
    also late init promises no nullable data when it is called later */
    private lateinit var binding: FragmentNewsListBinding
    //Kotlin property delegate used to define viewmodels
    private val viewmodel: NewsViewModel by viewModels()
    private lateinit var newsAdapter: NewsListAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        binding = FragmentNewsListBinding.inflate(layoutInflater)
        Log.i(TAG,"onCreate")

        //Creating the observer which updates the UI(Main Thread)
        viewmodel.newsMutableLiveData.observe(viewLifecycleOwner, {
            if(it!=null )
            {
                hideProgressBar()
                Log.i(TAG,"Received the data")
                initAdapterModel()
                newsAdapter.setLatestData(it.rows,activity)

            }
            else {
                showProgressBar()
                Toast.makeText(activity,"No data",Toast.LENGTH_LONG).show()
            }

        })
        viewmodel.getDataFromApi()
        return binding.root

    }

    override fun onPause() {
        super.onPause()

    }

    //Binding the recycler view adapter and with the news adapter
    private fun initAdapterModel() {
        binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
        newsAdapter = NewsListAdapter()
        binding.recyclerView.adapter = newsAdapter
    }
    private fun hideProgressBar() {
        progressBar.visibility = View.INVISIBLE
    }

    private fun showProgressBar() {
        progressBar.visibility = View.VISIBLE
    }
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.scrolltotop,menu)
        super.onCreateOptionsMenu(menu, inflater)

    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        binding.recyclerView.smoothScrollToPosition(0)
        return super.onOptionsItemSelected(item)
    }
    companion object {

        @JvmStatic
        fun newInstance() =
            NewsListFragment()
    }
}
    
    
    }

【问题讨论】:

    标签: viewmodel orientation android-livedata


    【解决方案1】:

    我通过使用事件和保存实例状态找到了解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      相关资源
      最近更新 更多