'ScrollListener does not work with tmdb api kotlin
I was requested to build an app in kotlin that fetch 120 movies from tmdb api, using coroutines, mvvm and injections.My app worked great until I added the pagination using scrollListener, in order to add more pages. From some reason it is not working I am not seeing any list on the screen but the rest of the app works fine.Can someone please help me and see if my code is correct? Please I know my code is pretty long but I am really need some help with this task Thank you
MainActivity class:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel :MoviesViewModel
private lateinit var moviesAdapter: MoviesAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initRecyclerView()
getData()
}
private fun getData(){
viewModel=ViewModelProvider(this,defaultViewModelProviderFactory)[MoviesViewModel::class.java]
viewModel.movies.observe(this@MainActivity, Observer { item ->
item?.let { res ->
when (res.status) {
Status.SUCCESS -> {
item.data?.let { movies->
moviesAdapter.differ.submitList(movies.results)
val totalPages=movies.totalResults / Constants.QUERY_PAGE_SIZE+2
isLastPage=viewModel.page == totalPages
if(isLastPage){
binding.recyclerView.setPadding(0,0,0,0)
}}}
Status.ERROR -> {
Toast.makeText(applicationContext, "Unable to load data right now", Toast.LENGTH_LONG).show()
res.message?.let { Log.e("Error", it) }
}}}})}
private fun initRecyclerView(){
moviesAdapter=MoviesAdapter()
binding.recyclerView.apply{
layoutManager= LinearLayoutManager(this@MainActivity)
adapter=moviesAdapter
addOnScrollListener([email protected])
}}
var isLoading:Boolean=false
var isLastPage:Boolean=false
var isScrolling:Boolean=false
val scrollListener=object : RecyclerView.OnScrollListener(){
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if(newState== AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling=true
}}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager=recyclerView.layoutManager as LinearLayoutManager
val firstVisibleItemPosition=layoutManager.findFirstVisibleItemPosition()
val visibleItemCount=layoutManager.childCount
val totalItemCount=layoutManager.itemCount
val isNotLoadingAndNotLastPage=!isLoading&&!isLastPage
val isAtLastItem=firstVisibleItemPosition+visibleItemCount>=totalItemCount
val isNotAtBeginning=firstVisibleItemPosition>=0
val isTotalMoreThanVisible=totalItemCount>=(Constants.QUERY_PAGE_SIZE)
val shouldPaginate=isNotLoadingAndNotLastPage&&isAtLastItem&&isNotAtBeginning&&isTotalMoreThanVisible&&isScrolling
if(shouldPaginate){
viewModel.getData()
isScrolling=false
}}}}
ViewModel class:
@HiltViewModel
class MoviesViewModel @Inject constructor(var repository: Repository): ViewModel() {
public var page=1
public var moviesResonse: Results?=null
val movies: MutableLiveData<Resource<Results>> = MutableLiveData()
fun getData() = viewModelScope.launch {
movies.postValue(Resource.loading(data=null))
val response=repository.getMovies(api_key = Constants.API_KEY,
start_year = Constants.START_YEAR,
end_year = Constants.END_YEAR,
page = page)
movies.postValue(handleMoviesResponse(response))
}
public fun handleMoviesResponse(response:Response<Results>):Resource<Results>{
if(response.isSuccessful) {
response.body()?.let { res->
page++
if(moviesResonse==null){
moviesResonse=res
}else{
val oldMovies= moviesResonse?.results
val newMovies=res.results
oldMovies?.addAll(newMovies)
}
return Resource.success(moviesResonse ?: res)
}}
return error(response.message())
}}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
