0

My countdownTimers works fine but my problem is all of them sync with last countdownTimer(bank or item in recyclerview) for example my time interval in item one is 30sec,in item two is 30sec and in item 3 is 60sec when i run my app item 1 and item 2 will be sync with item 3 ,60sec , i think i have one countdownTimer in whole recyclerview and not for per item.

This is my bank list view holder :

private static class BankListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private ImageView mImageViewBankLogo;
        private TextView mBankName;
        private TextView mFirstToken;
        private TextView mSecondToken;
        private Button mButtonAddToken;
        private RelativeLayout mRelativeLayoutFirstTokenRowLayout;
        private RelativeLayout mRelativeLayoutSecondTokenRowLayout;
        private Callback mCallback;
        private ProgressBarView mProgressBarView;
        private CountDownTimer countDownTimer;

        BankListViewHolder(@NonNull View itemView, Callback callback) {

            super(itemView);

            mCallback = callback;

            mImageViewBankLogo = itemView.findViewById(R.id.imageview_banklist_logo);
            mProgressBarView = itemView.findViewById(R.id.imageview_overlay);
            mBankName = itemView.findViewById(R.id.textview_banklist_bankname);
            mFirstToken = itemView.findViewById(R.id.textview_banklist_firsttoken);
            mSecondToken = itemView.findViewById(R.id.textview_banklist_secondtoken);
            mButtonAddToken = itemView.findViewById(R.id.button_banklist_addtoken);
            mRelativeLayoutSecondTokenRowLayout = itemView.findViewById(R.id.relativelayout_banklist_secondtokenrowlayout);
            mRelativeLayoutFirstTokenRowLayout = itemView.findViewById(R.id.relativelayout_banklist_firsttokenrowlayout);
            mButtonAddToken.setOnClickListener(this);
            mRelativeLayoutSecondTokenRowLayout.setOnClickListener(this);
            mRelativeLayoutFirstTokenRowLayout.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {

            if (v.getId() == R.id.relativelayout_banklist_firsttokenrowlayout) {
                BankUtil.copyToClipBoard(mFirstToken.getText().toString(), v.getContext());
                SnackbarUtil.showSnackbarNotify(v, v.getContext().getString(R.string.banklist_copyotp), v.getContext());
            }

            if (v.getId() == R.id.relativelayout_banklist_secondtokenrowlayout) {

                BankUtil.copyToClipBoard(mSecondToken.getText().toString(), v.getContext());
                SnackbarUtil.showSnackbarNotify(v, v.getContext().getString(R.string.banklist_copyotp), v.getContext());
            }

            if (v.getId() == R.id.button_banklist_addtoken) {
                mCallback.navigationToQrScanner(getAdapterPosition());
            }
        }
    }

And this is my onBindViewHolder :

public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {

.
.
.
bankListViewHolder.mFirstToken.setText(setSpaceBetweenCharacters(generateOtp(bank, 1)));
            bankListViewHolder.mSecondToken.setText(setSpaceBetweenCharacters(generateOtp(bank, 2)));
            bankListViewHolder.mButtonAddToken.setVisibility(View.GONE);
            bankListViewHolder.mImageViewBankLogo.setImageDrawable(BankUtil.getLogo(mRoot.getContext(), mBankList.get(position)));

            int currentSecond = (int) (((System.currentTimeMillis() / 1000) -
                    (bank.getToken().getOtpGenerationPeriodInSeconds() / 1000)) % (bank.getToken().getOtpGenerationPeriodInSeconds() / 1000));

            int diff = ((bank.getToken().getOtpGenerationPeriodInSeconds() / 1000) - currentSecond);


            bankListViewHolder.countDownTimer = new CountDownTimer(diff * 1000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {

                    bankListViewHolder.mProgressBarView.setCounter((int) ((bank.getToken().getOtpGenerationPeriodInSeconds() / 1000) -
                            (millisUntilFinished / 1000)) * (360 / (bank.getToken().getOtpGenerationPeriodInSeconds() / 1000)));
                }

                @Override
                public void onFinish() {

                    bankListViewHolder.mFirstToken.setText(generateOtp(bank, 1));
                    bankListViewHolder.mSecondToken.setText(generateOtp(bank, 2));
                    mCallback.updateList();
                    start();

                }
            };
            countDownTimerList.add(bankListViewHolder.countDownTimer);
            bankListViewHolder.countDownTimer.start();
            mCallback.saveCountDownTimer(bankListViewHolder.countDownTimer);

.
.
.
}
milad salimi
  • 1,580
  • 2
  • 12
  • 31

1 Answers1

0

You should not put the countDownTimer in a viewHolder. Keep in mind that a viewHolder is a temporary view and it can be reused by other items. This is the characteristic of a recyclerView (views can be recycled).

You should put the countDownTimer in your List class. One per item. Or create a new ArrayList of countDownTimers.

In the onTick event you can use notifyItemChanged to update their values.

Ferran
  • 1,442
  • 1
  • 6
  • 10
  • Thanks but i put countdownTimer in class as a field and in think we should put it in viewholder like [this] :(https://stackoverflow.com/questions/38890863/multiple-count-down-timers-in-recyclerview-flickering-when-scrolled) – milad salimi May 02 '19 at 08:38