繁体   English   中英

Kotlin recyclerview 分页重启(Pagination)

[英]Kotlin recyclerview pagination restarts (Pagination)

我目前正在开发一个基于 TMDB 的 Kotlin 应用程序,试图实现我实现的分页,但是当添加更多项目时,recyclerview“重新启动”(将我发送到列表顶部)。

我认为问题可能是我的适配器或我设置 recylerview 的方式。

有什么建议吗?

我的适配器

class SearchMovieAdapter(val movieList: ArrayList<MovieData>, val listener: ClickListener) :
    RecyclerView.Adapter<SearchMovieAdapter.SearchViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchViewHolder {
        val view: LayoutInflater = LayoutInflater.from(parent.context)
        return SearchViewHolder(view.inflate(R.layout.search_item, parent, false))
    }

    override fun onBindViewHolder(holder: SearchViewHolder, position: Int) {
        return holder.bindInfo(movieList[position])
    }

    override fun getItemCount(): Int {
        return movieList.size
    }



    inner class SearchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var itemImage: ImageView = itemView.findViewById(R.id.imageFound)
        fun bindInfo(movie: MovieData) {
            itemView.setOnClickListener{
                //listener.OnItemClick(movie.id.toString(), image.context)
                listener.OnItemClick(movie, itemImage.context)
            }
            // title.text = movie.title
            if (movie.poster_path != null) {

                Picasso.get().load("https://image.tmdb.org/t/p/w500${movie.poster_path}")
                    .into(itemImage)
            }
        }

    }

执行

class SearchPage :
    ClickListener,
    AppCompatActivity() {
    private lateinit var editableText: EditText
    private lateinit var listOfSearchedMovies: RecyclerView
    var searchedQuery: ArrayList<MovieData> = ArrayList()
    var queryText: String = ""
    var indexPage = 1
    val indexLimit = 3
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search_page)

        editableText = findViewById(R.id.buscarPeli)

        //When user click enter key on keyboard
        editableText.setOnKeyListener(View.OnKeyListener { _, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN) {
                //Perform Code
                val query: String = editableText.text.toString()
                queryText = query
                
                //Search movies data
                if (searchedQuery.isEmpty()) {
                    setSearchedTitle(query, indexPage.toString())
                }

                editableText.text.clear()
                hideKeyboard()
                Toast.makeText(this, query, Toast.LENGTH_SHORT).show()
                return@OnKeyListener true
            }
            false
        })


    }

    private fun hideKeyboard() {
        val view = this.currentFocus
        if (view != null) {
            val hide = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            hide.hideSoftInputFromWindow(view.windowToken, 0)
        }
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
    }

    private fun setSearchedTitle(query: String, index: String) {

        val retrofitBuilder = Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(com.example.recyclerview.BASE_URL)
            .build()
            .create(API_interface::class.java)
        val retrofitData = retrofitBuilder.searchMovies(query, index)
        retrofitData.enqueue(object : Callback<MoviesResponse?> {
            override fun onResponse(
                call: Call<MoviesResponse?>,
                response: Response<MoviesResponse?>
            ) {
                if (response.isSuccessful) {
                    //searchedQuery.clear()
                    val totalResults = response.body()!!.results.size

                    for (i in 0 until totalResults)
                        searchedQuery.add(response.body()!!.results[i])
                }
                //Log.d("Respuesta", "Lista respuesta ${searchedQuery.size} ")
                //index=index+1
                setMoviesRecyclerView(searchedQuery)
            }

            override fun onFailure(call: Call<MoviesResponse?>, t: Throwable) {
                Toast.makeText(this@SearchPage, "${t.message}", Toast.LENGTH_SHORT).show()
            }
        })
    }


    private fun setMoviesRecyclerView(searchedQuery: ArrayList<MovieData>) {
        val loading: ProgressBar = findViewById(R.id.movieResultsLoading)
        listOfSearchedMovies = findViewById(R.id.searcheMovies)
        listOfSearchedMovies.apply {
            val layoutManager: RecyclerView.LayoutManager =
                GridLayoutManager(listOfSearchedMovies.context, 2)
            listOfSearchedMovies.layoutManager = layoutManager
            adapter = SearchMovieAdapter(searchedQuery, this@SearchPage)
            listOfSearchedMovies.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)
                    if (!recyclerView.canScrollVertically(1)) {
                        indexPage++
                        if (indexPage > indexLimit) {
                            Toast.makeText(
                                recyclerView.context,
                                "¡That's all!",
                                Toast.LENGTH_LONG
                            ).show()
                        } else {
                            setSearchedTitle(queryText, indexPage.toString())
                        }
                    }
                }
            })

        }
    }



}

我尝试添加另一种方法来仅将项目添加到列表中,但是这样做视图不会刷新

问题是您每次收到一些新数据时都在初始化适配器。
尝试在 SearchMovieAdapter class 中添加一个insertMovie函数, SearchMovieAdapter函数添加单个项目并通知其插入:

fun insertMovie(newMovie: MovieData) {
    this.movieList.add(newMovie)
    notifyItemInserted(movieList.size - 1)
}

然后在每次收到新的 object 时使用它来更新您的适配器:

retrofitData.enqueue(object : Callback<MoviesResponse?> {
            override fun onResponse(
                call: Call<MoviesResponse?>,
                response: Response<MoviesResponse?>
            ) {
                if (response.isSuccessful) {
                    //searchedQuery.clear()
                    val totalResults = response.body()!!.results.size

                    for (i in 0 until totalResults) {
                        adapter.insertMovie(response.body()!!.results[i])
                    }
                }
            }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM