Set counter inside RecyclerView

后端 未结 2 1738
北恋
北恋 2021-01-15 14:24

I have count down timer as image below :

now these timers will start count down in each item, i tried many times to change this from my Adapter

2条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-15 14:38

    Edit

    Here's a sample that can be used to update the visible items in your RecyclerView. I assume you use LinearLayoutManager for your RecyclerView's layout.

    First of all, remove CountDownTimer from your code. The problem with it is that it uses the main thread's looper to loop through the messages (actually it uses the "current thread" but since you initialize it in your main thread, current thread is main thread now) and it can only be scheduled for a finite interval.

    Now the new part. Assume there's your fragment that inits the RecyclerView and all its related parts. Let's say that these are the fields available in your fragment:

    private AdapterItems myAdapter;
    private LinearLayoutManager layoutManager;
    private ScheduledFuture updateFuture;
    

    Then put the following part into your onCreateView(...) after you're done with all the view, adapter and other initializations:

    if (updateFuture == null) {
        final Handler mainHandler = new Handler(Looper.getMainLooper());
        updateFuture = Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                final int firstVisible = layoutManager.findFirstVisibleItemPosition();
                final int lastVisible = layoutManager.findLastVisibleItemPosition();
    
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        myAdapter.notifyItemRangeChanged(firstVisible, lastVisible - firstVisible + 1);
                    }
                });
            }
        }, 0, 1000, TimeUnit.MILLISECONDS);
    }
    

    Here's a little explanation of the code. We create a new single threaded ScheduledExecutorService which can be used to schedule runnables at fixed rate (scheduleAtFixedRate(...)). Every 1000 milliseconds from the call of this method, there's going to be a new execution.

    Now the inner part. Every layout manager (except the base class LayoutManager) has two very important methods: findFirstVisibleItemPosition() and findLastVisibleItemPosition(). As the names show, these can be used to find the first and last visible items' position in the adapter. Then we use these informations to call the RecyclerView's adapter's (myAdapter) notifyItemRangeChanged(...) which will update only the given items' view in the range by calling onBindViewHolder(...) automatically.

    Note the mainHandler which is used to call the notifyItemRangeChanged(...) method on the UI thread as you cannot update the UI from a non-UI thread (and the one created by the ScheduledExecutorService is non-UI).

    Don't forget to cancel your ScheduledFuture when you don't need the updates anymore by calling its cancel() method (e.g. in your fragment's onDestroyView()).

    if (updateFuture != null) {
        updateFuture.cancel(true);
        updateFuture = null;
    }
    

    Original

    You have your Items class which, I assume, contains all the data (images, text, etc.) for the list items. You should put the target date to this class as well, this way all your items can have different target dates. If you want to update this date later on, you'll have to change it in the appropriate Items instance and call notifyItemChanged(position) on your adapter.

提交回复
热议问题