Несколько таймеров обратного отсчета в представлении ресайклера

Мой countdownTimers работает нормально, но моя проблема в том, что все они синхронизируются с последним countdownTimer (банк или элемент в recyclerview), например, мой временной интервал в первом элементе составляет 30 секунд, во втором элементе - 30 секунд, а в элементе 3 - 60 секунд, когда я запускаю свой элемент приложения 1 и элемент 2 будут синхронизированы с элементом 3, 60 секунд, я думаю, что у меня есть один countdownTimer в целом recyclerview, а не для каждого элемента.

Это держатель представления списка моих банков:

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());
            }
        }
    }

А это мой 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);

.
.
.
}

person milad salimi    schedule 02.05.2019    source источник


Ответы (1)


Вы не должны помещать countDownTimer в viewHolder. Имейте в виду, что viewHolder — это временное представление, и его можно повторно использовать другими элементами. Это характеристика recyclerView (представления могут быть переработаны).

Вы должны поместить countDownTimer в свой класс List. По одному на предмет. Или создайте новый ArrayList из countDownTimers.

В событии onTick вы можете использовать notifyItemChanged для обновления их значений.

person Ferran    schedule 02.05.2019
comment
Спасибо, но я поместил countdownTimer в класс как поле и думаю, что мы должны поместить его в средство просмотра, например [это] :(stackoverflow.com/questions/38890863/) - person milad salimi; 02.05.2019