Improve: Convert setup*() functions to suspend function

Update: Implement Immersive mode to fix bottom navigation color
For future use of flows and other suspend function
This commit is contained in:
LooKeR 2022-01-25 03:00:23 +05:30
parent 8b60fe4f98
commit 3677ee646a
8 changed files with 32 additions and 27 deletions

View File

@ -7,6 +7,7 @@ import android.view.*
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
@ -72,15 +73,16 @@ class MainActivityX : AppCompatActivity() {
currentTheme = Preferences[Preferences.Key.Theme].getResId(resources.configuration) currentTheme = Preferences[Preferences.Key.Theme].getResId(resources.configuration)
setTheme(currentTheme) setTheme(currentTheme)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainXBinding.inflate(layoutInflater) binding = ActivityMainXBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.lifecycleOwner = this binding.lifecycleOwner = this
toolbar = binding.toolbar toolbar = binding.toolbar
if (savedInstanceState == null && (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { if (savedInstanceState == null && (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
handleIntent(intent) handleIntent(intent)
} }
setContentView(binding.root) WindowCompat.setDecorFitsSystemWindows(window, false)
} }
override fun onStart() { override fun onStart() {
@ -90,7 +92,7 @@ class MainActivityX : AppCompatActivity() {
toolbar.menu.setGroupDividerEnabled(true) toolbar.menu.setGroupDividerEnabled(true)
} }
toolbar.isFocusableInTouchMode = true toolbar.isFocusableInTouchMode = true
binding.collapsingToolbar.title = getString(R.string.application_name) toolbar.title = getString(R.string.application_name)
val navHostFragment = val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragment_content) as NavHostFragment supportFragmentManager.findFragmentById(R.id.fragment_content) as NavHostFragment

View File

@ -3,14 +3,17 @@ package com.looker.droidify.ui.fragments
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
abstract class BaseNavFragment : Fragment() { abstract class BaseNavFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
lifecycleScope.launchWhenCreated {
setupAdapters() setupAdapters()
setupLayout() setupLayout()
} }
}
abstract fun setupAdapters() abstract suspend fun setupAdapters()
abstract fun setupLayout() abstract suspend fun setupLayout()
} }

View File

@ -15,6 +15,7 @@ import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.paged.PagedModelAdapter import com.mikepenz.fastadapter.paged.PagedModelAdapter
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.collectLatest
// TODO create categories layouts that hold the apps in horizontal layout // TODO create categories layouts that hold the apps in horizontal layout
class ExploreFragment : MainNavFragmentX() { class ExploreFragment : MainNavFragmentX() {
@ -44,11 +45,11 @@ class ExploreFragment : MainNavFragmentX() {
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } } .flatMapSingle { list -> RxUtils.querySingle { list.mapNotNull { it.trueData } } }
.map { list -> list.asSequence().map { Pair(it.id, it) }.toMap() } .map { list -> list.asSequence().map { Pair(it.id, it) }.toMap() }
.observeOn(AndroidSchedulers.mainThread()) .subscribeOn(AndroidSchedulers.mainThread())
.subscribe { repositories = it } .subscribe { repositories = it }
} }
override fun setupAdapters() { override suspend fun setupAdapters() {
appsItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) { appsItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) } it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
} }
@ -61,8 +62,8 @@ class ExploreFragment : MainNavFragmentX() {
} }
} }
override fun setupLayout() { override suspend fun setupLayout() {
viewModel.productsList.observe(requireActivity()) { viewModel.productsList.collectLatest {
appsItemAdapter.submitList(it) appsItemAdapter.submitList(it)
appsFastAdapter?.notifyDataSetChanged() appsFastAdapter?.notifyDataSetChanged()
} }

View File

@ -17,6 +17,7 @@ import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.paged.PagedModelAdapter import com.mikepenz.fastadapter.paged.PagedModelAdapter
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.collectLatest
class InstalledFragment : MainNavFragmentX() { class InstalledFragment : MainNavFragmentX() {
@ -52,7 +53,7 @@ class InstalledFragment : MainNavFragmentX() {
.subscribe { repositories = it } .subscribe { repositories = it }
} }
override fun setupAdapters() { override suspend fun setupAdapters() {
installedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) { installedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) } it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
} }
@ -74,14 +75,14 @@ class InstalledFragment : MainNavFragmentX() {
} }
} }
override fun setupLayout() { override suspend fun setupLayout() {
binding.buttonUpdated.setOnClickListener { binding.buttonUpdated.setOnClickListener {
binding.updatedRecycler.apply { binding.updatedRecycler.apply {
visibility = if (visibility == View.VISIBLE) View.GONE else View.VISIBLE visibility = if (visibility == View.VISIBLE) View.GONE else View.VISIBLE
} }
} }
viewModel.productsList.observe(requireActivity()) { viewModel.productsList.collectLatest {
binding.updatedBar.visibility = binding.updatedBar.visibility =
if (it.any { item -> item.data_item?.canUpdate == true }) View.VISIBLE else View.GONE if (it.any { item -> item.data_item?.canUpdate == true }) View.VISIBLE else View.GONE
updatedItemAdapter.submitList(it) updatedItemAdapter.submitList(it)

View File

@ -17,6 +17,7 @@ import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.paged.PagedModelAdapter import com.mikepenz.fastadapter.paged.PagedModelAdapter
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.collectLatest
class LatestFragment : MainNavFragmentX() { class LatestFragment : MainNavFragmentX() {
@ -53,7 +54,7 @@ class LatestFragment : MainNavFragmentX() {
.subscribe { repositories = it } .subscribe { repositories = it }
} }
override fun setupAdapters() { override suspend fun setupAdapters() {
updatedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) { updatedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) } it.data_item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
} }
@ -75,8 +76,8 @@ class LatestFragment : MainNavFragmentX() {
} }
} }
override fun setupLayout() { override suspend fun setupLayout() {
viewModel.productsList.observe(requireActivity()) { viewModel.productsList.collectLatest {
newItemAdapter.submitList(it) newItemAdapter.submitList(it)
updatedItemAdapter.submitList(it) updatedItemAdapter.submitList(it)
} }

View File

@ -6,7 +6,7 @@ import com.looker.droidify.ui.activities.MainActivityX
import com.looker.droidify.ui.viewmodels.MainNavFragmentViewModelX import com.looker.droidify.ui.viewmodels.MainNavFragmentViewModelX
abstract class MainNavFragmentX : BaseNavFragment() { abstract class MainNavFragmentX : BaseNavFragment() {
val mainActivityX: MainActivityX private val mainActivityX: MainActivityX
get() = requireActivity() as MainActivityX get() = requireActivity() as MainActivityX
val viewModel: MainNavFragmentViewModelX by viewModels { val viewModel: MainNavFragmentViewModelX by viewModels {
MainNavFragmentViewModelX.Factory(mainActivityX.db, source) MainNavFragmentViewModelX.Factory(mainActivityX.db, source)

View File

@ -40,7 +40,7 @@ class PrefsRepositoriesFragment : BaseNavFragment() {
return binding.root return binding.root
} }
override fun setupAdapters() { override suspend fun setupAdapters() {
syncConnection.bind(requireContext()) syncConnection.bind(requireContext())
reposFastAdapter = FastAdapter.with(reposItemAdapter) reposFastAdapter = FastAdapter.with(reposItemAdapter)
@ -52,7 +52,7 @@ class PrefsRepositoriesFragment : BaseNavFragment() {
} }
} }
override fun setupLayout() { override suspend fun setupLayout() {
viewModel.productsList.observe(requireActivity()) { viewModel.productsList.observe(requireActivity()) {
reposItemAdapter.set( reposItemAdapter.set(
it.mapNotNull { dbRepo -> it.mapNotNull { dbRepo ->

View File

@ -1,8 +1,8 @@
package com.looker.droidify.ui.viewmodels package com.looker.droidify.ui.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.asFlow
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.DataSource import androidx.paging.DataSource
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
@ -14,10 +14,7 @@ import com.looker.droidify.entity.ProductItem
import com.looker.droidify.ui.fragments.Request import com.looker.droidify.ui.fragments.Request
import com.looker.droidify.ui.fragments.Source import com.looker.droidify.ui.fragments.Source
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -92,7 +89,7 @@ class MainNavFragmentViewModelX(val db: DatabaseX, source: Source) : ViewModel()
.build() .build()
} }
val request = request(source) val request = request(source)
val productsList: LiveData<PagedList<Product>> by lazy { val productsList: Flow<PagedList<Product>> by lazy {
LivePagedListBuilder( LivePagedListBuilder(
db.productDao.queryList( db.productDao.queryList(
installed = request.installed, installed = request.installed,
@ -102,7 +99,7 @@ class MainNavFragmentViewModelX(val db: DatabaseX, source: Source) : ViewModel()
order = request.order, order = request.order,
numberOfItems = request.numberOfItems numberOfItems = request.numberOfItems
), pagedListConfig ), pagedListConfig
).build() ).build().asFlow()
} }
fun fillList(source: Source) { fun fillList(source: Source) {