emirhangulmez / android-flow-mvvm-sample

Android MVVM sample app that uses kotlin coroutines flow (without LiveData)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Android MVVM sample app that uses kotlin coroutines flow (without LiveData)

This is a sample app that uses kotlin coroutines flow.

It is MVVM Architecture without LiveData.

There is a user search feature on Github.

Screenshot

top detail

Architecture

ViewModel -> View

Use kotlin coroutines flow with StateFlow.

After transformed to hot stream with ViewModelScope, bind to view with LifecycleScope.

class TopViewModel(
    private val repository: RepoRepository
): ViewModel() {
    private val resource = repository
        .getRepoList("Google")
        .stateIn(viewModelScope, SharingStarted.Eagerly, Resource.Loading)
    val data = resource.map { it.valueOrNull.orEmpty() }
}
inline fun <T> AppCompatActivity.bind(
    source: Flow<T>,
    crossinline action: (T) -> Unit
) {
    source.onEach { action.invoke(it) }
        .launchIn(lifecycleScope)
}
class TopActivity : AppCompatActivity() {
    private val viewModel: TopViewModel by viewModel()

    private lateinit var binding: ActivityTopBinding
    private lateinit var adapter: RepoAdapter

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_top)
        adapter = RepoAdapter()

        bind(viewModel.data) {
            adapter.setList(it)
        }
    }
}

View -> ViewModel

Call a ViewModel function, and emit to MutableSharedFlow.

class TopViewModel(
    private val repository: RepoRepository
) : ViewModel() {
    private val submitEvent = MutableSharedFlow<Unit>()
    private val resource = submitEvent
        .flatMapLatest { repository.getRepoList("Google") }
        .stateIn(viewModelScope, SharingStarted.Eagerly, Resource.Loading)

    fun submit() {
        viewModelScope.launch {
            submitEvent.emit(Unit)
        }
    }
}
class TopActivity : AppCompatActivity() {
    private val viewModel: TopViewModel by viewModel()

    private lateinit var binding: ActivityTopBinding

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_top)
        binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                viewModel.submit()
                return false
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                return false
            }
        })
    }
}

View <-> ViewModel (2-way data binding)

Combine the above two.

class TopViewModel(
    private val repository: RepoRepository
) : ViewModel() {
    private val _userName = MutableStateFlow("Google")
    val userName: Flow<String> = _userName

    fun setUserName(userName: String) {
        _userName.value = userName
    }
}
class TopActivity : AppCompatActivity() {
    private val viewModel: TopViewModel by viewModel()

    private lateinit var binding: ActivityTopBinding

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_top)
        binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                return false
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                viewModel.setUserName(newText.orEmpty())
                return false
            }
        })

        bind(viewModel.userName) {
            val current = binding.searchView.query.toString()
            // Need to compare with current value
            if (current != it) {
                setQuery(query, false)
            }
        }
    }
}

Libraries

About

Android MVVM sample app that uses kotlin coroutines flow (without LiveData)


Languages

Language:Kotlin 100.0%