Reputation:
I want to load just one element with one scroll gesture. Now it is like one scroll gesture loads 1 or few new elements (depends on time of scroll gesture). As a solution I could do this gesture in shorter time than 500ms or make this postDelayed's delay longer but I guess there are better solutions for that. Do you have any ideas how to do that?
This app is written in MVP pattern. Here is my code:
CurrencyFragmentList.kt
private fun addScrollerListener() {
rvItem.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(_rvItem: RecyclerView, newState: Int) {
super.onScrollStateChanged(_rvItem, newState)
Log.e("scroll", isLoading.toString())
if (!isLoading) {
if (!_rvItem.canScrollVertically(1)) {
loadMore()
isLoading = true
}
}
}
})
}
private fun loadMore() {
showProgressDialog()
var numberOfDays = mainPresenter.getNumberOfMinusDays()
numberOfDays++
mainPresenter.saveNumberOfMinusDaysIntoSp(numberOfDays)
var dateMinusXDays = mainPresenter.currentDateMinusXDaysToStr(numberOfDays)
val nextLimit = listSize + 1
for (i in listSize until nextLimit) {
if (mainPresenter.checkIfSuchDateExistsinSp(dateMinusXDays)) {
Log.d("such date already exists in shared prefs", dateMinusXDays)
handler.postDelayed({
mainPresenter.processDateWithoutMakingACall(dateMinusXDays)
}, 500)
} else {
mainPresenter.makeACall(dateMinusXDays)
Log.d("retrofit call made", dateMinusXDays)
}
}
itemAdapter.notifyDataSetChanged()
}
override fun hideProgressDialog() {
if (apiResponseList.size > 1) {
apiResponseList.removeAt(apiResponseList.size - 1)
listSize = apiResponseList.size
itemAdapter.notifyItemRemoved(listSize)
} else progress_bar.visibility = View.GONE
isLoading = false
}
override fun assignResponseToRecyclerview(apiResponse: ApiResponse?) {
rvItem.apply {
layoutManager = _layoutManager
apiResponseList.add(apiResponse!!)
itemAdapter = activity?.let { ItemAdapter(apiResponseList, it) }!!
adapter = itemAdapter
}
Log.e("assign", isLoading.toString())
}
MainPresenter.kt
override fun makeACall(date: String?) {
//view.showProgressDialog()
date?.let { restModel.fetchApiResponse(this, it) }
}
fun processDateWithoutMakingACall(date: String) {
val apiResponse = processRawJson(sp.getString(date, "").toString())
passResponseToView(apiResponse)
}
override fun processRawJson(rawJson: String): ApiResponse {
val parser = JsonParser()
val rootObj = parser.parse(rawJson).asJsonObject
var ratesObj = JsonObject()
var ratesKeys: Set<String> = HashSet()
val ratesArrayList: ArrayList<Currency> = ArrayList()
val rootKeys = rootObj.keySet();
var baseValue = ""
var dateValue = ""
for (key in rootKeys) {
if (key == "base")
baseValue = rootObj.get(key).asString
if (key == "date")
dateValue = rootObj.get(key).asString
if (key == "rates") {
ratesObj = rootObj.get(key).asJsonObject
ratesKeys = ratesObj.keySet()
}
}
for (key2 in ratesKeys) {
Log.e("ratesKey", key2)
Log.e("ratesValue", ratesObj.get(key2).asFloat.toString())
ratesArrayList.add(Currency(key2, ratesObj.get(key2).asFloat))
}
saveRawJsonIntoSp(rawJson, dateValue)
return ApiResponse(baseValue, dateValue, ratesArrayList, false)
}
override fun passResponseToView(apiResponse: ApiResponse?) {
view.hideProgressDialog()
view.assignResponseToRecyclerview(apiResponse)
}
RestModel.kt
override fun fetchApiResponse(presenter: MainPresenter, date: String) {
job = CoroutineScope(Dispatchers.IO).launch {
val response = userService.getCurrenciesForDate(date)
withContext(Dispatchers.Main) {
if (response.isSuccessful) {
val rawJson = response.body()
val apiResponse = presenter.processRawJson(rawJson)
presenter.passResponseToView(apiResponse)
}
}
}
}
Any help will be really appreciated. Thank you in advance!
Upvotes: 1
Views: 88
Reputation: 101
Try out the SnapHelper, it might slow layout manager to make more callbacks and stop overloading
Upvotes: 0