почему элементы просмотра ресайклера не меняются местами? - PullRequest
0 голосов
/ 14 июля 2020

У меня есть вид ресайклера, и в нем есть предметы. Теперь я использую пузырьковую сортировку, чтобы переставить их. Но adapter.notifyItemMoved не работает должным образом в l oop (это медленно). Пожалуйста, посмотрите на приведенный ниже код и помогите, я добавил комментарии, чтобы вы поняли. Еще одна вещь, я не могу отсортировать список в начале до адаптации. Поэтому, пожалуйста, не воспринимайте это как решение. Я знаю, что это решение, но в моем случае оно не сработает.

//rv_all is a recycler view
for (i in 0 until rv_all.childCount)
{
    for (j in 0 until rv_all.childCount - 1)
    {
        /* i have added tag while binding in ViewHolder
         itemView.stdate.tag = "date" */
        val date1 =
            sdf.parse(rv_all.getChildAt(j).findViewWithTag < TextView("date").text.toString())
        val date2 =
            sdf.parse(rv_all.getChildAt(j + 1).findViewWithTag < TextView("date").text.toString())
        if (date1 != null && date2 != null)
        {
            if (date1.before(date2))
            {
                //alllist is a list used to adapt to recycler view
                Collections.swap(alllist, j, j + 1)
                alladapter.notifyItemMoved(j, j + 1)
                // problem is here ,it is working fine when not in a loop but in loop it is doing nothing
                // i have debugged and used breakpoints and what i saw that alllist is swapping elements but adapter child are not rearranging
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 14 июля 2020

вы повторяете дочерние элементы RecyclerView (почему дважды? Вы нигде не используете i, это неэффективно)

for (i in 0 until rv_all.childCount) {
    for (j in 0 until rv_all.childCount - 1) {

, но это только View s - first child / View находится в позиции 0, второй 1 и c. Когда вы прокручиваете немного вниз и ваш RecyclerView первый видимый элемент, например, 10-й в alllist, тогда все еще первый видимый View находится в позиции 0, как всегда

, поэтому эти строки не имеют смысла:

Collections.swap(alllist,j,j+1)
alladapter.notifyItemMoved(j,j+1)

они всегда меняют местами и уведомляют элементы в начале массива, начиная с 0, но ваш RecyclerView можно прокрутить немного вниз, например, до 10-го элемента - тогда строки выше меняют элементы в alllist, но notifyItemMoved ничего не делает, поскольку RecyclerView не нужно перерисовывать первые элементы, они «прокручиваются»

короче: позиция View нарисована в RecyclerView! = позиция в данных array

вы можете добавить тег "real_position" в адаптере к каждому дочернему элементу, тогда вы все равно можете перебирать видимые дочерние элементы / View s, получать View s с findViewByTag, но swap и notifyItemMoved для позиций в массиве данных ("real_position" получено из тега), не видимые дочерние позиции в родительском RecyclerView

var realPosition : Integer = rv_all.getChildAt(j).tag as Integer // set in adapter
Collections.swap(alllist, realPosition, realPosition+1)
alladapter.notifyItemMoved(realPosition, realPosition+1) 
0 голосов
/ 14 июля 2020

Вы можете попробовать использовать notifyDataSetChanged ():

class MovieAdapter(...) : RecyclerView.Adapter<MovieViewHolder>() {

var data: List<Movies> = list
    set(value) {
        field = value
        notifyDataSetChanged()
    }
...

Для более эффективного способа обновления используйте DiffUtil.ItemCallback <...> (). См. Документы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...