Refactor initAdapter
This commit is contained in:
parent
d13b34ed0d
commit
c2dd66c54f
|
@ -2,25 +2,32 @@ package com.h.pixeldroid.posts.feeds
|
|||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ProgressBar
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.size
|
||||
import androidx.paging.LoadState
|
||||
import androidx.paging.LoadStateAdapter
|
||||
import androidx.paging.PagingDataAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.h.pixeldroid.R
|
||||
import com.h.pixeldroid.databinding.FragmentFeedBinding
|
||||
import com.h.pixeldroid.databinding.ErrorLayoutBinding
|
||||
import com.h.pixeldroid.databinding.LoadStateFooterViewItemBinding
|
||||
|
||||
/**
|
||||
* Shows or hides the error in the different FeedFragments
|
||||
*/
|
||||
private fun showError(errorText: String, show: Boolean = true, binding: FragmentFeedBinding){
|
||||
if(show){
|
||||
binding.motionLayout.transitionToEnd()
|
||||
binding.errorLayout.errorText.text = errorText
|
||||
} else if(binding.motionLayout.progress == 1F){
|
||||
binding.motionLayout.transitionToStart()
|
||||
private fun showError(
|
||||
errorText: String, show: Boolean = true,
|
||||
motionLayout: MotionLayout,
|
||||
errorLayout: ErrorLayoutBinding){
|
||||
|
||||
if(show) {
|
||||
motionLayout.transitionToEnd()
|
||||
errorLayout.errorText.text = errorText
|
||||
} else if(motionLayout.progress == 1F) {
|
||||
motionLayout.transitionToStart()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,28 +36,32 @@ private fun showError(errorText: String, show: Boolean = true, binding: Fragment
|
|||
*
|
||||
* Makes the UI respond to various [LoadState]s, including errors when an error message is shown.
|
||||
*/
|
||||
internal fun <T: Any> initAdapter(binding: FragmentFeedBinding, adapter: PagingDataAdapter<T, RecyclerView.ViewHolder>) {
|
||||
binding.list.adapter = adapter.withLoadStateFooter(
|
||||
internal fun <T: Any> initAdapter(
|
||||
progressBar: ProgressBar, swipeRefreshLayout: SwipeRefreshLayout,
|
||||
recyclerView: RecyclerView, motionLayout: MotionLayout, errorLayout: ErrorLayoutBinding,
|
||||
adapter: PagingDataAdapter<T, RecyclerView.ViewHolder>) {
|
||||
|
||||
recyclerView.adapter = adapter.withLoadStateFooter(
|
||||
footer = ReposLoadStateAdapter { adapter.retry() }
|
||||
)
|
||||
|
||||
adapter.addLoadStateListener { loadState ->
|
||||
|
||||
if(!binding.progressBar.isVisible && binding.swipeRefreshLayout.isRefreshing) {
|
||||
if(!progressBar.isVisible && swipeRefreshLayout.isRefreshing) {
|
||||
// Stop loading spinner when loading is done
|
||||
binding.swipeRefreshLayout.isRefreshing = loadState.refresh is LoadState.Loading
|
||||
swipeRefreshLayout.isRefreshing = loadState.refresh is LoadState.Loading
|
||||
} else {
|
||||
// ProgressBar should stop showing as soon as the source stops loading ("source"
|
||||
// meaning the database, so don't wait on the network)
|
||||
val sourceLoading = loadState.source.refresh is LoadState.Loading
|
||||
if(!sourceLoading && binding.list.size > 0){
|
||||
binding.list.isVisible = true
|
||||
binding.progressBar.isVisible = false
|
||||
} else if(binding.list.size == 0
|
||||
if(!sourceLoading && recyclerView.size > 0){
|
||||
recyclerView.isVisible = true
|
||||
progressBar.isVisible = false
|
||||
} else if(recyclerView.size == 0
|
||||
&& loadState.append is LoadState.NotLoading
|
||||
&& loadState.append.endOfPaginationReached){
|
||||
binding.progressBar.isVisible = false
|
||||
showError(binding = binding, errorText = "Nothing to see here :(")
|
||||
progressBar.isVisible = false
|
||||
showError(motionLayout = motionLayout, errorLayout = errorLayout, errorText = "Nothing to see here :(")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,13 +74,15 @@ internal fun <T: Any> initAdapter(binding: FragmentFeedBinding, adapter: PagingD
|
|||
?: loadState.prepend as? LoadState.Error
|
||||
?: loadState.refresh as? LoadState.Error
|
||||
errorState?.let {
|
||||
showError(binding = binding, errorText = it.error.toString())
|
||||
showError(motionLayout = motionLayout, errorLayout = errorLayout, errorText = it.error.toString())
|
||||
}
|
||||
if(errorState == null) {
|
||||
showError(motionLayout = motionLayout, errorLayout = errorLayout, show = false, errorText = "")
|
||||
}
|
||||
if (errorState == null) showError(binding = binding, show = false, errorText = "")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to the show the a [RecyclerView] item for a [LoadState], with a callback to retry if
|
||||
* the retry button is pressed.
|
||||
|
|
|
@ -70,7 +70,8 @@ open class CachedFeedFragment<T: FeedContentDatabase> : BaseFragment() {
|
|||
|
||||
binding = FragmentFeedBinding.inflate(layoutInflater)
|
||||
|
||||
initAdapter(binding, adapter)
|
||||
initAdapter(binding.progressBar, binding.swipeRefreshLayout,
|
||||
binding.list, binding.motionLayout, binding.errorLayout, adapter)
|
||||
|
||||
//binding.progressBar.visibility = View.GONE
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
|
|
|
@ -67,7 +67,8 @@ open class UncachedFeedFragment<T: FeedContent> : BaseFragment() {
|
|||
|
||||
binding = FragmentFeedBinding.inflate(layoutInflater)
|
||||
|
||||
initAdapter(binding, adapter)
|
||||
initAdapter(binding.progressBar, binding.swipeRefreshLayout, binding.list,
|
||||
binding.motionLayout, binding.errorLayout, adapter)
|
||||
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
//It shouldn't be necessary to also retry() in addition to refresh(),
|
||||
|
|
|
@ -33,8 +33,5 @@ class ProfilePagingSource(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getRefreshKey(state: PagingState<String, Status>): String? =
|
||||
state.anchorPosition?.run {
|
||||
state.closestItemToPosition(this)?.id
|
||||
}
|
||||
override fun getRefreshKey(state: PagingState<String, Status>): String? = null
|
||||
}
|
|
@ -9,8 +9,6 @@ import android.view.ViewGroup
|
|||
import android.widget.*
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.size
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -24,7 +22,7 @@ import com.h.pixeldroid.R
|
|||
import com.h.pixeldroid.databinding.ActivityProfileBinding
|
||||
import com.h.pixeldroid.databinding.FragmentProfilePostsBinding
|
||||
import com.h.pixeldroid.posts.PostActivity
|
||||
import com.h.pixeldroid.posts.feeds.ReposLoadStateAdapter
|
||||
import com.h.pixeldroid.posts.feeds.initAdapter
|
||||
import com.h.pixeldroid.posts.feeds.uncachedFeeds.FeedViewModel
|
||||
import com.h.pixeldroid.posts.feeds.uncachedFeeds.UncachedContentRepository
|
||||
import com.h.pixeldroid.posts.feeds.uncachedFeeds.profile.ProfileContentRepository
|
||||
|
@ -88,14 +86,13 @@ class ProfileActivity : BaseActivity() {
|
|||
).get(FeedViewModel::class.java) as FeedViewModel<Status>
|
||||
|
||||
profileAdapter = ProfilePostsAdapter()
|
||||
initAdapter(binding, profileAdapter)
|
||||
initAdapter(binding.profileProgressBar, binding.profileRefreshLayout,
|
||||
binding.profilePostsRecyclerView, binding.motionLayout, binding.profileErrorLayout,
|
||||
profileAdapter)
|
||||
|
||||
binding.profilePostsRecyclerView.layoutManager = GridLayoutManager(this, 3)
|
||||
|
||||
binding.profileRefreshLayout.setOnRefreshListener {
|
||||
//It shouldn't be necessary to also retry() in addition to refresh(),
|
||||
//but if we don't do this, reloads after an error fail immediately...
|
||||
profileAdapter.retry()
|
||||
profileAdapter.refresh()
|
||||
}
|
||||
|
||||
|
@ -139,52 +136,6 @@ class ProfileActivity : BaseActivity() {
|
|||
binding.profileRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the [RecyclerView] adapter for the different FeedFragments.
|
||||
*
|
||||
* Makes the UI respond to various [LoadState]s, including errors when an error message is shown.
|
||||
*/
|
||||
internal fun <T: Any> initAdapter(binding: ActivityProfileBinding, adapter: PagingDataAdapter<T, RecyclerView.ViewHolder>) {
|
||||
binding.profilePostsRecyclerView.adapter = adapter.withLoadStateFooter(
|
||||
footer = ReposLoadStateAdapter { adapter.retry() }
|
||||
)
|
||||
|
||||
adapter.addLoadStateListener { loadState ->
|
||||
|
||||
if(!binding.profileProgressBar.isVisible && binding.profileRefreshLayout.isRefreshing) {
|
||||
// Stop loading spinner when loading is done
|
||||
binding.profileRefreshLayout.isRefreshing = loadState.refresh is LoadState.Loading
|
||||
} else {
|
||||
// ProgressBar should stop showing as soon as the source stops loading ("source"
|
||||
// meaning the database, so don't wait on the network)
|
||||
val sourceLoading = loadState.source.refresh is LoadState.Loading
|
||||
if(!sourceLoading && binding.profilePostsRecyclerView.size > 0){
|
||||
binding.profilePostsRecyclerView.isVisible = true
|
||||
binding.profileProgressBar.isVisible = false
|
||||
} else if(binding.profilePostsRecyclerView.size == 0
|
||||
&& loadState.append is LoadState.NotLoading
|
||||
&& loadState.append.endOfPaginationReached){
|
||||
binding.profileProgressBar.isVisible = false
|
||||
showError(errorText = "Nothing to see here :(")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Toast on any error, regardless of whether it came from RemoteMediator or PagingSource
|
||||
val errorState = loadState.source.append as? LoadState.Error
|
||||
?: loadState.source.prepend as? LoadState.Error
|
||||
?: loadState.source.refresh as? LoadState.Error
|
||||
?: loadState.append as? LoadState.Error
|
||||
?: loadState.prepend as? LoadState.Error
|
||||
?: loadState.refresh as? LoadState.Error
|
||||
errorState?.let {
|
||||
showError(errorText = it.error.toString())
|
||||
}
|
||||
if (errorState == null) showError(show = false, errorText = "")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
onBackPressed()
|
||||
return true
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
tools:visibility="visible">
|
||||
|
||||
<include
|
||||
android:id="@+id/profileErrorLayout"
|
||||
layout="@layout/error_layout"
|
||||
tools:layout_editor_absoluteX="50dp" />
|
||||
|
||||
|
|
Loading…
Reference in New Issue