Skip to content

Instantly share code, notes, and snippets.

@parthdesai1208
Last active November 29, 2022 14:01
Show Gist options
  • Save parthdesai1208/dce9d804ae100aa20f27c5818cd4287b to your computer and use it in GitHub Desktop.
Save parthdesai1208/dce9d804ae100aa20f27c5818cd4287b to your computer and use it in GitHub Desktop.
Flow APIs
*********************************************************StateFlow Demo**************************************************************
Step-1) build.gradle
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.6"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.6"
Step-2) data class
data class Resource<out T>(val status: Status, val data: T?, val message: String?) {
companion object {
fun <T> success(data: T?): Resource<T> {
return Resource(Status.SUCCESS, data, null)
}
fun <T> error(msg: String, data: T?): Resource<T> {
return Resource(Status.ERROR, data, msg)
}
fun <T> loading(data: T?): Resource<T> {
return Resource(Status.LOADING, data, null)
}
}
}
enum class Status {
SUCCESS,
ERROR,
LOADING
}
step-3) ViewModel
@ExperimentalCoroutinesApi
private val users = MutableStateFlow<Resource<List<ApiUser>>>(Resource.loading(null))
//MutableStateFlow has read and write property
@ExperimentalCoroutinesApi
fun fetchUsers() {
viewModelScope.launch {
apiHelper.getUsers()
.catch { e ->
users.value = (Resource.error(e.toString(), null))
}
.collect {
users.value = (Resource.success(it))
}
}
}
//StateFlow is read-only
@ExperimentalCoroutinesApi
fun getUsers(): StateFlow<Resource<List<ApiUser>>> {
return users
}
step-4) Activity
lifecycleScope.launch {
val value = viewModel.getUsers()
value.collect {
when (it.status) {
Status.SUCCESS -> {
progressBar.visibility = View.GONE
it.data?.let { users -> renderList(users) }
recyclerView.visibility = View.VISIBLE
}
Status.LOADING -> {
progressBar.visibility = View.VISIBLE
recyclerView.visibility = View.GONE
}
Status.ERROR -> {
//Handle Error
progressBar.visibility = View.GONE
Toast.makeText(
this@SingleNetworkCallActivity,
it.message,
Toast.LENGTH_LONG
).show()
}
}
}
}
*********************************************************CallBack Flow Demo**************************************************************
Ex-1,
@ExperimentalCoroutinesApi
fun Context.checkNetwork() : Flow<Boolean> = callbackFlow {
val callback = object : ConnectivityManager.NetworkCallback(){
override fun onAvailable(network: Network) {
super.onAvailable(network)
offer(true)
}
override fun onLost(network: Network) {
super.onLost(network)
offer(false)
}
}
val manager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
manager.registerNetworkCallback(NetworkRequest.Builder().run {
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
build()
}, callback)
awaitClose {
manager.unregisterNetworkCallback(callback)
}
}
use it like,
lifecycleScope.launchWhenStarted {
checkNetwork().collect {
val result = when(it){
true -> {"connected with internet"}
false-> {"not connected with internet"}
}
Log.d("main", "onCreate: $result")
}
}
Ex-2,
@ExperimentalCoroutinesApi
fun EditText.onTextChange() : Flow<Editable?> = callbackFlow {
val callback = object : TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
offer(s)
}
}
awaitClose {
removeTextChangedListener(callback)
}
}
use it like,
lifecycleScope.launchWhenStarted {
binding.username.onTextChange().debounce(500L) //debounce() operator will wait for 500 ms then the value will be collected. Awesome!! 🤩🤩
.collect {text->
Log.d("main", "onCreate: $text")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment