首页 > 解决方案 > 如何防止方向改变时片段的重新创建问题?

问题描述

在我的应用程序中,我使用带有导航组件和 mvvm 架构的导航抽屉。

我的问题是屏幕旋转片段重新创建时。如何防止这种情况?请问有什么建议或示例代码吗?

我的代码就像:

主要活动 :

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)


        drawerLayout = findViewById(R.id.drawer_layout)
        navView = findViewById(R.id.nav_view)


        navController = findNavController(R.id.nav_host_fragment)
        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.nav_home,
                R.id.nav_productInsight,
                R.id.nav_turkey,
                R.id.nav_usa,
                R.id.nav_china
            ), drawerLayout
        )
            setupActionBarWithNavController(navController, appBarConfiguration)
            navView.setupWithNavController(navController)
            navView.setNavigationItemSelectedListener { menuItem ->
            when (menuItem.itemId) {
                R.id.nav_home -> {

                    navController.navigate(R.id.nav_home)

                    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
                        drawerLayout.closeDrawer(GravityCompat.START)
                    }
                    true
                }
                R.id.nav_productInsight -> {

                    navController.navigate(R.id.nav_productInsight)

                    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
                        drawerLayout.closeDrawer(GravityCompat.START)
                    }
                    true
                }
                R.id.nav_turkey -> {
                    val menuItemView = findViewById<View>(R.id.nav_turkey)
                    showPopupTurkey(menuItemView)
                    false
                }
                R.id.nav_usa -> {
                    val menuItemView = findViewById<View>(R.id.nav_usa)
                    showPopupUsa(menuItemView)
                    false
                }
                R.id.nav_china -> {
                    val menuItemView = findViewById<View>(R.id.nav_china)
                    showPopupChina(menuItemView)
                    false
                }
                R.id.nav_logout -> {
                    showLogOutDialog()
                    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
                        drawerLayout.closeDrawer(GravityCompat.START)
                    }
                    true
                }
                else -> {
                    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
                        drawerLayout.closeDrawer(GravityCompat.START)
                    }
                    false
                }
            }
        }

    }

视图模型类:

class HomeViewModel @ViewModelInject constructor(
    private val dataUseCase: DataUseCase,
    private val networkHelper: NetworkHelper
):ViewModel(){

    fun getCountryProductionInformationChartList (filterId : String?,productId:String?) : LiveData<ResultData<BaseChartModel<ProductionQuantityModel>?>> {
        return flow {
            emit(ResultData.Loading())
            try {
                emit(dataUseCase.getCountryProductionInformationChartList (filterId,productId))
            } catch (e: Exception) {
                e.printStackTrace()
                emit(ResultData.Exception())
            }
        }.asLiveData(Dispatchers.IO)
    }

}

我的家庭片段:

@AndroidEntryPoint
class HomeFragment : BaseFragment() {


    private lateinit var mContext: Context
    private lateinit var mView : View


    private val mainViewModel: HomeViewModel by viewModels()

    private val mainObserver = Observer<ResultData<BaseChartModel<ProductionQuantityModel>?>> { resultData ->
        when(resultData) {
            is ResultData.Loading -> {
                mView.scrollView.visibility = View.GONE
                emptyDataText.visibility = View.GONE
                showLoading()
            }
            is ResultData.Success -> {
                hideLoading()
                mView.scrollView.visibility = View.VISIBLE
                emptyDataText.visibility = View.GONE
                resultData.data?.let {
                    setQtyChart(mView, it)
                    setPPMChart(mView, it)
                    setKPIChart(mView, it)
                    setBreakDownChart(mView, it)
                }
            }
            is ResultData.Failed -> {
                hideLoading()
                mView.scrollView.visibility = View.GONE
                emptyDataText.visibility = View.VISIBLE
                emptyDataText.text = resultData.message
            }
            is ResultData.Exception -> {
                hideLoading()
                mView.scrollView.visibility = View.GONE
                emptyDataText.visibility = View.GONE
                Toast.makeText(mContext,"Error!",Toast.LENGTH_SHORT).show()
            }
        }
    }

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

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_home, container, false)
        mView = root
        getProductionQuantities()
        return root
    }

如何处理这个重新创建的问题?顺便说一句,安全 args 数据正在消失。

标签: androidmvvmrotationfragmentkotlin-coroutines

解决方案


你可以setRetainInstanceState(true)在你的活动中使用。看更多


推荐阅读