Skip to content

Commit

Permalink
Merge pull request #881 from android/dlam/fix-refresh
Browse files Browse the repository at this point in the history
Fix scroll to top behavior in PagingWithNetworkSample
  • Loading branch information
dlam authored Jul 22, 2020
2 parents 160f148 + 90caae0 commit 1816dea
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,33 @@ import androidx.paging.PagingSource.LoadParams.Append
import androidx.paging.PagingSource.LoadParams.Prepend
import androidx.paging.PagingSource.LoadResult.Page
import com.android.example.paging.pagingwithnetwork.reddit.api.RedditApi
import com.android.example.paging.pagingwithnetwork.reddit.repository.inMemory.byItem.ItemKeyedSubredditPagingSource
import com.android.example.paging.pagingwithnetwork.reddit.vo.RedditPost
import retrofit2.HttpException
import java.io.IOException

/**
* A [PagingSource] that uses the before/after keys returned in page requests.
*
* @see [com.android.example.paging.pagingwithnetwork.reddit.repository.inMemory.byItem.ItemKeyedSubredditPagingSource]
* @see ItemKeyedSubredditPagingSource
*/
class PageKeyedSubredditPagingSource(
private val redditApi: RedditApi,
private val subredditName: String
private val redditApi: RedditApi,
private val subredditName: String
) : PagingSource<String, RedditPost>() {
override suspend fun load(params: LoadParams<String>): LoadResult<String, RedditPost> {
return try {
val data = redditApi.getTop(
subreddit = subredditName,
after = if (params is Append) params.key else null,
before = if (params is Prepend) params.key else null,
limit = params.loadSize
subreddit = subredditName,
after = if (params is Append) params.key else null,
before = if (params is Prepend) params.key else null,
limit = params.loadSize
).data

Page(
data = data.children.map { it.data },
prevKey = data.before,
nextKey = data.after
data = data.children.map { it.data },
prevKey = data.before,
nextKey = data.after
)
} catch (e: IOException) {
LoadResult.Error(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,18 @@ import androidx.lifecycle.AbstractSavedStateViewModelFactory
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadState
import com.android.example.paging.pagingwithnetwork.GlideApp
import com.android.example.paging.pagingwithnetwork.R
import com.android.example.paging.pagingwithnetwork.reddit.ServiceLocator
import com.android.example.paging.pagingwithnetwork.reddit.repository.RedditPostRepository
import kotlinx.android.synthetic.main.activity_reddit.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filter

/**
* A list activity that shows reddit posts in the given sub-reddit.
Expand All @@ -55,14 +58,14 @@ class RedditActivity : AppCompatActivity() {
private val model: SubRedditViewModel by viewModels {
object : AbstractSavedStateViewModelFactory(this, null) {
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
val repoTypeParam = intent.getIntExtra(KEY_REPOSITORY_TYPE, 0)
val repoType = RedditPostRepository.Type.values()[repoTypeParam]
val repo = ServiceLocator.instance(this@RedditActivity)
.getRepository(repoType)
.getRepository(repoType)
@Suppress("UNCHECKED_CAST")
return SubRedditViewModel(repo, handle) as T
}
Expand All @@ -83,8 +86,8 @@ class RedditActivity : AppCompatActivity() {
val glide = GlideApp.with(this)
adapter = PostsAdapter(glide)
list.adapter = adapter.withLoadStateHeaderAndFooter(
header = PostsLoadStateAdapter(adapter),
footer = PostsLoadStateAdapter(adapter)
header = PostsLoadStateAdapter(adapter),
footer = PostsLoadStateAdapter(adapter)
)

lifecycleScope.launchWhenCreated {
Expand All @@ -102,10 +105,13 @@ class RedditActivity : AppCompatActivity() {
}

lifecycleScope.launchWhenCreated {
@OptIn(ExperimentalPagingApi::class, ExperimentalCoroutinesApi::class)
adapter.dataRefreshFlow.collectLatest {
list.scrollToPosition(0)
}
@OptIn(FlowPreview::class)
adapter.loadStateFlow
// Only emit when REFRESH LoadState for RemoteMediator changes.
.distinctUntilChangedBy { it.refresh }
// Only react to cases where Remote REFRESH completes i.e., NotLoading.
.filter { it.refresh is LoadState.NotLoading }
.collect { list.scrollToPosition(0) }
}
}

Expand Down

0 comments on commit 1816dea

Please sign in to comment.