Home > database >  Change RecyclerView Layout (from Linear to Grid and reverse) when rotate device automatically
Change RecyclerView Layout (from Linear to Grid and reverse) when rotate device automatically

Time:10-07

I have 4 different "Card List", "Card Magazine" , "Title" and "Grid" and view holders for each one to relate check

CodePudding user response:

since long time I was looking for a soultion and i found it and added it to my old project, i was use shared prefernces but in your case i mean data store it will work normally

  1. you need to create two arrays for each orintation
 <?xml version="1.0" encoding="utf-8"?>
<resources>

    <array name="recyclerViewPortraitList">
        <item>Card List</item>
        <item>Card Magazine</item>
        <item>Title</item>
    </array>

    <array name="recyclerViewLandscapeList">
        <item>Grid with 3 Span</item>
        <item>Grid with 4 Span</item>
    </array>
</resources>
  1. in your data store will be like the following
    private object PreferencesKeys {
        var RECYCLER_VIEW_PORTRAIT_LAYOUT_KEY = stringPreferencesKey("recyclerViewPortraitLayout")
        var RECYCLER_VIEW_LANDSCAPE_LAYOUT_KEY = stringPreferencesKey("recyclerViewLandscapeLayout")
}

suspend fun saveRecyclerViewPortraitLayout(
        recyclerViewLayout: String,
    ) {
        datastore.edit { preferences ->
            preferences[PreferencesKeys.RECYCLER_VIEW_PORTRAIT_LAYOUT_KEY] = recyclerViewLayout
        }
    }

    suspend fun saveRecyclerViewLandscapeLayout(recyclerViewLayout: String) {
        datastore.edit { preferences ->
            preferences[PreferencesKeys.RECYCLER_VIEW_LANDSCAPE_LAYOUT_KEY] = recyclerViewLayout
        }
    }

val readRecyclerViewPortraitLayout:
            Flow<String> = datastore.data.catch { ex ->
        if (ex is IOException) {
            ex.message?.let { Log.e(TAG, it) }
            emit(emptyPreferences())
        } else {
            throw ex
        }
    }.map { preferences ->
        val recyclerViewLayout: String =
            preferences[PreferencesKeys.RECYCLER_VIEW_PORTRAIT_LAYOUT_KEY] ?: "cardLayout"
        recyclerViewLayout
    }


    val readRecyclerViewLandscpaeLayout:
            Flow<String> = datastore.data.catch { ex ->
        if (ex is IOException) {
            ex.message?.let { Log.e(TAG, it) }
            emit(emptyPreferences())
        } else {
            throw ex
        }
    }.map { preferences ->
        val recyclerViewLayout: String =
            preferences[PreferencesKeys.RECYCLER_VIEW_LANDSCAPE_LAYOUT_KEY] ?: "gridWith3Span"
        recyclerViewLayout
    }

  1. in the viewModel
    val readRecyclerViewPortraitLayout =
        dataStoreRepository.readRecyclerViewPortraitLayout.asLiveData()
    val readRecyclerViewLandscapeLayout =
        dataStoreRepository.readRecyclerViewLandscpaeLayout.asLiveData()

 fun saveRecyclerViewPortraitLayout(layout: String) {
        viewModelScope.launch {
            dataStoreRepository.saveRecyclerViewPortraitLayout(layout)
        }
    }

    fun saveRecyclerViewLandscapeLayout(layout: String) {
        viewModelScope.launch {
            dataStoreRepository.saveRecyclerViewLandscapeLayout(layout)
        }
    }
  1. in adapter change constants
 companion object {
        private const val CARD = 0
        private const val CARD_MAGAZINE = 1
        private const val TITLE = 2
        private const val GRID_WITH_3_SPAN = 3
        private const val GRID_WITH_4_SPAN = 4
}

5.and finally in the fragment or activity you can use it like the following

private fun setUpRecyclerViewLayout() {
        if (requireActivity().resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {

            postViewModel.readRecyclerViewPortraitLayout.observe(viewLifecycleOwner) { layout ->

                recyclerViewLayout = layout
                
                when (layout) {
                    "cardLayout" -> {
                        adapter.viewType = 0
                        binding.apply {
                            homeRecyclerView.layoutManager = linearLayoutManager
                            homeRecyclerView.adapter = adapter
                            homeRecyclerView.setHasFixedSize(true)
                        }

                    }
                    "cardMagazineLayout" -> {
                        binding.homeRecyclerView.layoutManager = linearLayoutManager
                        adapter.viewType = 1
                        binding.homeRecyclerView.adapter = adapter
                    }
                    "titleLayout" -> {
                        binding.homeRecyclerView.layoutManager = titleLayoutManager
                        adapter.viewType = 2
                        binding.homeRecyclerView.adapter = adapter
                    }
                }
            }
        } else {
            postViewModel.readRecyclerViewLandscapeLayout.observe(viewLifecycleOwner) { layout ->

                recyclerViewLayout = layout

                when (layout) {

                    "gridWith3Span" -> {
      
                        binding.homeRecyclerView.layoutManager = gridWith3SpanLayoutManager
                        adapter.viewType = 3
                        binding.homeRecyclerView.adapter = adapter
                    }
                    "gridWith4Span" -> {
            
                        binding.homeRecyclerView.layoutManager = gridWith4SpanLayoutManager
                        adapter.viewType = 4
                        binding.homeRecyclerView.adapter = adapter

                    }
                }
            }
        }

    }


    private fun changeAndSaveLayout() {

        val builder = AlertDialog.Builder(requireContext())
        builder.setTitle(getString(R.string.choose_layout))

        //        SharedPreferences.Editor editor = sharedPreferences.edit();

        if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            builder.setItems(
                resources.getStringArray(R.array.recyclerViewPortraitList)
            ) { _: DialogInterface?, index: Int ->
                try {
                    when (index) {
                        0 -> {
                            adapter.viewType = 0
                            binding.homeRecyclerView.layoutManager = linearLayoutManager
                            binding.homeRecyclerView.adapter = adapter
                            postViewModel.saveRecyclerViewPortraitLayout("cardLayout")
                        }
                        1 -> {
                            adapter.viewType = 1
                            binding.homeRecyclerView.layoutManager = linearLayoutManager
                            binding.homeRecyclerView.adapter = adapter
                            postViewModel.saveRecyclerViewPortraitLayout("cardMagazineLayout")

                        }
                        2 -> {
                            adapter.viewType = 2
                            binding.homeRecyclerView.layoutManager = titleLayoutManager
                            binding.homeRecyclerView.adapter = adapter
                            postViewModel.saveRecyclerViewPortraitLayout("titleLayout")
                        }
                        else -> {
                            throw Exception("Unknown layout")
                        }
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "changeAndSaveLayout: "   e.message)
                    Log.e(TAG, "changeAndSaveLayout: "   e.cause)
                }
            }
        } else {
            builder.setItems(
                resources.getStringArray(R.array.recyclerViewLandscapeList)
            ) { _: DialogInterface?, index: Int ->
                try {
                    when (index) {
                        0 -> {
                            adapter.viewType = 3
                            binding.homeRecyclerView.layoutManager = gridWith3SpanLayoutManager
                            binding.homeRecyclerView.adapter = adapter
                            postViewModel.saveRecyclerViewLandscapeLayout("gridWith3Span")
                        }
                        1 -> {
                            adapter.viewType = 4
                            binding.homeRecyclerView.layoutManager = gridWith4SpanLayoutManager
                            binding.homeRecyclerView.adapter = adapter
                            postViewModel.saveRecyclerViewLandscapeLayout("gridWith4Span")

                        }
                        else -> {
                            throw Exception("Unknown layout")
                        }
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "changeAndSaveLayout: "   e.message)
                    Log.e(TAG, "changeAndSaveLayout: "   e.cause)
                }
            }
        }
        val alertDialog = builder.create()
        alertDialog.show()
    }

if you setting configuration changes in manifest like that android:configChanges="orientation|screenSize"you will need to call the setUpRecyclerViewLayout() from onConfigurationChanged

 override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        setUpRecyclerViewLayout()
    }
  • Related