Skip to content

Commit

Permalink
part 7: adding infinite scroll and updating news manager to allow pag…
Browse files Browse the repository at this point in the history
…ination
  • Loading branch information
juanchosaravia committed Apr 9, 2016
1 parent 2f90d6d commit 3bedf81
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.droidcba.kedditbysteps.commons

import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log

class InfiniteScrollListener(
val func: () -> Unit,
val layoutManager: LinearLayoutManager) : RecyclerView.OnScrollListener() {

private var previousTotal = 0
private var loading = true
private var visibleThreshold = 2
private var firstVisibleItem = 0
private var visibleItemCount = 0
private var totalItemCount = 0

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)

if (dy > 0) {
visibleItemCount = recyclerView.childCount;
totalItemCount = layoutManager.itemCount;
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();

if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
Log.i("InfiniteScrollListener", "End reached");
func()
loading = true;
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ package com.droidcba.kedditbysteps.commons
import com.droidcba.kedditbysteps.commons.adapter.AdapterConstants
import com.droidcba.kedditbysteps.commons.adapter.ViewType

data class RedditNews(
val after: String,
val before: String,
val news: List<RedditNewsItem>)

data class RedditNewsItem(
val author: String,
val title: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.droidcba.kedditbysteps.R
import com.droidcba.kedditbysteps.commons.InfiniteScrollListener
import com.droidcba.kedditbysteps.commons.RedditNews
import com.droidcba.kedditbysteps.commons.RxBaseFragment
import com.droidcba.kedditbysteps.commons.extensions.inflate
import com.droidcba.kedditbysteps.features.news.adapter.NewsAdapter
Expand All @@ -15,6 +17,7 @@ import rx.schedulers.Schedulers

class NewsFragment : RxBaseFragment() {

private var redditNews: RedditNews? = null
private val newsManager by lazy { NewsManager() }

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Expand All @@ -25,7 +28,10 @@ class NewsFragment : RxBaseFragment() {
super.onActivityCreated(savedInstanceState)

news_list.setHasFixedSize(true)
news_list.layoutManager = LinearLayoutManager(context)
val linearLayout = LinearLayoutManager(context)

This comment has been minimized.

This comment has been minimized.

Copy link
@zlaela

zlaela Mar 17, 2018

I got around that by calling notifyDataSetChanged() after (news_list.adapter as NewsAdapter).addNews(retrievedNews.news) in requestNews()

news_list.layoutManager = linearLayout
news_list.clearOnScrollListeners()
news_list.addOnScrollListener(InfiniteScrollListener({ requestNews() }, linearLayout))

This comment has been minimized.

Copy link
@kevincianfarini

kevincianfarini Jul 23, 2017

Would it have any performance or method count benefit to use this::requestNews rather than using a lambda to wrap it?

Do lambdas count towards the apk method limit?

This comment has been minimized.

Copy link
@AmitBarjatya

AmitBarjatya Sep 3, 2017

I am not sure about the performance part but lambdas certainly do not count towards the 65k method limit.

Check the section on Retrolambdas in this article by AJ Alt from keepsafe.
https://medium.com/keepsafe-engineering/lessons-from-converting-an-app-to-100-kotlin-68984a05dcb6

initAdapter()

if (savedInstanceState == null) {
Expand All @@ -34,11 +40,17 @@ class NewsFragment : RxBaseFragment() {
}

private fun requestNews() {
val subscription = newsManager.getNews()
/**
* first time will send empty string for after parameter.
* Next time we will have redditNews set with the next page to
* navigate with the after param.
*/
val subscription = newsManager.getNews(redditNews?.after ?: "")
.subscribeOn(Schedulers.io())
.subscribe (
{ retrievedNews ->
(news_list.adapter as NewsAdapter).addNews(retrievedNews)
redditNews = retrievedNews
(news_list.adapter as NewsAdapter).addNews(retrievedNews.news)
},
{ e ->
Snackbar.make(news_list, e.message ?: "", Snackbar.LENGTH_LONG).show()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
package com.droidcba.kedditbysteps.features.news

import com.droidcba.kedditbysteps.api.RestAPI
import com.droidcba.kedditbysteps.commons.RedditNews
import com.droidcba.kedditbysteps.commons.RedditNewsItem
import rx.Observable

/**
* News Manager allows you to request more news from Reddit.
* News Manager allows you to request news from Reddit API.
*
* @author juancho
*/
class NewsManager(private val api: RestAPI = RestAPI()) {

fun getNews(limit: String = "10"): Observable<List<RedditNewsItem>> {
/**
*
* Returns Reddit News paginated by the given limit.
*
* @param after indicates the next page to navigate.
* @param limit the number of news to request.
*/
fun getNews(after: String, limit: String = "10"): Observable<RedditNews> {
return Observable.create {
subscriber ->
val callResponse = api.getNews("", limit)
val callResponse = api.getNews(after, limit)
val response = callResponse.execute()

if (response.isSuccessful) {
val news = response.body().data.children.map {
val dataResponse = response.body().data
val news = dataResponse.children.map {
val item = it.data
RedditNewsItem(item.author, item.title, item.num_comments,
item.created, item.thumbnail, item.url)
}
subscriber.onNext(news)
val redditNews = RedditNews(
dataResponse.after ?: "",
dataResponse.before ?: "",
news)

subscriber.onNext(redditNews)
subscriber.onCompleted()
} else {
subscriber.onError(Throwable(response.message()))
Expand Down

0 comments on commit 3bedf81

Please sign in to comment.