RecyclerView-在for循环中逐一更新项imageView的可见性

时间:2019-04-07 23:10:57

标签: android android-recyclerview recycler-adapter

我正在从for循环调用notifyItemChanged(position)来设置ImageViewVisibility = inVisible,但是for循环结束后会立即显示所有图像视图。而我想一次显示/隐藏imageView。 我该怎么做才能解决此问题?

当前输出:

在for循环结束时,所有图像视图一次都可见。 (我的意思是  仅在for循环结束之后才调用OnBindviewHolder方法。

预期输出:

对于为每个索引执行的循环,我想逐行显示/隐藏每行的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 个答案:

答案 0 :(得分:1)

您的问题是,当您尝试更改所有可见性时,您正在阻塞主线程。因此,尽管您正在尝试在操作之间进行延迟,但是前一个操作由于线程被阻塞而无法执行。换句话说,您正在排队所有动作,但是直到您释放主线程并且系统可以对其进行处理,这些动作才能生效,然后所有这些动作同时发生。

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

您可以做的一件事是在for循环中触发可运行对象,就像您已经在使用main函数一样。

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

这样,您安排所有更新将在您需要的时间进行,并立即释放主线程。稍后,在预定的时间,主线程可以自由处理指令并根据需要制作动画。

希望有帮助!