RecyclerView - обновляет элемент imageView видимость один за другим в цикле for - PullRequest
0 голосов
/ 08 апреля 2019

Я звоню notifyItemChanged(position) из цикла for, чтобы установить ImageViewVisibility = inVisible, но все виды изображений отображаются сразу после окончания цикла for.Принимая во внимание, что я хочу показать / скрыть imageView по одному.Что мне нужно сделать, чтобы это исправить?

Текущий вывод:

Все изображения отображаются сразу все вместе, когда заканчивается цикл.(Я имею в виду, что метод OnBindviewHolder вызывается только после окончания цикла for`

Ожидаемый результат:

Что касается циклов, выполняемых для каждого индекса, я хочу показать/ скрыть imageView для каждой строки одну за другой (я имею в виду OnBindviewHolder метод должен вызываться при вызове каждого for цикла)

Что я пробовал:

Я пробовал notifyItemChanged(pos);, notifyDataSetChanged();, notifyItemInserted(pos);, но ни один из них не помог мне получить ожидаемый результат. Я также попробовал https://stackoverflow.com/a/35392153/1684778, но все еще тот же выход.

активность

private List<Multiples> items = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_result); 
    recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); 

    // use a linear layout manager
    layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);

    // specify an adapter (see also next example)
    items.addAll(DataGenerator.getPeopleData(this, of, value));
    mAdapter = new MyAdapter(items);
    recyclerView.setAdapter(mAdapter);


    //----------now give few seconds untill all default data is loaded in the recyclerView----------------
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            //--------------Now call for loop on every 2 seconds so that we can hide or show ImageViews in each 2 seconds 
            MyAdapter m= (MyAdapter) mAdapter;
            for (Multiples item : items) {
                Multiples multiples1=items.get(items.indexOf(item));
                multiples1.setImageShow(true);  // set true to hide loop 

                Log.i("ms","----------in activity--------"+items.indexOf(item));

                m.updateItem(item,items.indexOf(item));  // forward each row to adapter to take effect

                try {   // sleep for 2 seconds so that we can see the effect of above code(hide/show imageView for this row index  items.indexOf(item)
                    Log.i("s","#####################  going to sleep #######################"+items.indexOf(item) );
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }, 2500);

}

адаптер

public void updateItem(final Multiples newItem, final int pos) {
    newItem.setImageShow(true);
    items.set(pos, newItem); //update passed value in your adapter's data structure
    notifyItemChanged(pos);
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    // - get an element from your dataset at this position
    // - replace the contents of the view with that element

    if (holder instanceof MyAdapter.MyViewHolder) {
        final MyAdapter.MyViewHolder view = (MyAdapter.MyViewHolder) holder;
        final Multiples p = items.get(position);
        view.name.setText(p.first + " X " + p.getSecond() + "= " + p.getResult());

        // if(position>0) {
        if (p.imageShow) {
            view.image1.setVisibility(View.VISIBLE);
            view.image.setVisibility(View.INVISIBLE);
        } else {
            view.image1.setVisibility(View.INVISIBLE);
            view.image.setVisibility(View.VISIBLE);
        }
    }
    // }

}

1 Ответ

1 голос
/ 08 апреля 2019

Ваша проблема в том, что вы блокируете основной поток, пытаясь изменить все видимости. Таким образом, хотя вы пытаетесь уснуть, чтобы поместить задержку между операциями, предыдущие не могут быть выполнены, потому что поток заблокирован. Другими словами, вы ставите в очередь все действия, но они не могут вступить в силу, пока вы не освободите основной поток, и система не сможет их обработать, что затем происходит одновременно.

public void run() {
    // THIS IS HAPPENING ON THE MAIN THREAD - ANDROID CAN'T CONTINUE DRAWING
    // UNTIL THIS METHOD FINISHES
        //--------------Now call for loop on each 2 seconds so that we can hide or show ImageViews in each 2 seconds 
        MyAdapter m= (MyAdapter) mAdapter;
        for (Multiples item : items) {
            Multiples multiples1=items.get(items.indexOf(item));
            multiples1.setImageShow(true);  // set true to hide loop 

            Log.i("ms","----------in activity--------"+items.indexOf(item));

            m.updateItem(item,items.indexOf(item));  // forward each row to adapter to take effect

            try {   // sleep for 2 seconds so that we can see the effect of above code(hide/show imageView for this row index  items.indexOf(item)
                Log.i("s","#####################  going to sleep #######################"+items.indexOf(item) );

                // THIS SLEEP IS BLOCKING THE MAIN THREAD - ANDROID CAN'T DRAW
                // UNTIL THE OUTER FUNCTION IS DONE
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    } // THE END OF THE RUN BLOCK - NOW ANDROID CAN RUN THE INSTRUCTIONS THAT
      // HAVE BEEN QUEUED UP, WHICH WILL APPEAR INSTANT

Одна вещь, которую вы могли бы сделать, это запустить runnables в цикле for, как вы уже делаете с основной функцией.

public void run() {
        //--------------Now call for loop on each 2 seconds so that we can hide or show ImageViews in each 2 seconds 
        MyAdapter m= (MyAdapter) mAdapter;

        int index = 0;
        for (Multiples item : items) {
            // DO NOT SLEEP TO NOT BLOCK THE MAIN THREAD - SCHEDULE WORK FOR LATER INSTEAD
            handler.postDelayed(new Runnabled() {
                Multiples multiples1=items.get(items.indexOf(item));
                multiples1.setImageShow(true);  // set true to hide loop 

                // OTHER LOGIC FOR THIS ITEM HERE

            }, 2000 * index++); // SCHEDULE EACH ITEM TO BE 2 SECONDS LATER THAN THE PREVIOUS
        }
    } // THE LOOP FINISHES INSTANTLY AND DOES NOT BLOCK THE MAIN THREAD

Таким образом, вы планируете , чтобы все обновления происходили в нужное время и немедленно освобождали основной поток. Позже, в назначенное время, основной поток может свободно обрабатывать инструкции и выполнять анимацию по желанию.

Надеюсь, это поможет!

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