Intereting Posts
Robolectric includeAndroidResources не найден Android установлен в одном действии, а затем появляется кнопка в другой активности Как работают классы обработчиков в Android Виртуальное устройство GenyMotion открывается и сразу исчезает Разница между setTranslationX / Y и offsetLeftAndRight / offsetTopAndBottom? Обнаружение движения с использованием Accelerometer в Android Android позволяет загружать несколько файлов (максимум 150 МБ) на PHP Server Android My Location-Fix Genymotion не получил ip-адрес из виртуальной коробки Чтобы получить дату и время с Timestamp Android Записывать приложения на C или C ++ для Android? Получить токен id в приложении Android и проверить его на сервере backend (как использовать токен?) Как использовать сеть для совместного использования файлов p2p на платформе Android? Android. Представления, наложенные на последний кадр полноэкранного видео, не перерисовываются правильно при включении и выключении экрана. Использование Tesseract для распознавания рукописного ввода

ListView с таймером Coundown. Таймер мерцает при прокрутке списка

В моем приложении мне нужно показать таймер обратного отсчета для каждого элемента в списке. Я смог сделать это с помощью CountDownTimer . Но проблема заключается в прокрутке списка вверх или вниз, таймер начинает мерцать. Искал много, но не смог найти решение.

Класс моего адаптера

 public class BuyListingListAdapter extends BaseAdapter { private Context mContext; private ArrayList<VehicleAttributes> mVehicleList = new ArrayList<VehicleAttributes>(); private Date currentDate; //Saving position in map to check if timer has been //started for this row private HashMap<Integer, Boolean> timerMap = new HashMap<Integer, Boolean>(); public BuyListingListAdapter(Context context, ArrayList<VehicleAttributes> vehicleList, boolean showGridView) { this.mContext = context; this.mVehicleList = vehicleList; this.showGridView = showGridView; currentDate = new Date(System.currentTimeMillis()); int listSize = mVehicleList.size(); for (int i = 0; i < listSize; i++) timerMap.put(i, false); } @Override public int getCount() { return mVehicleList.size(); } @Override public Object getItem(int position) { return mVehicleList.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); convertView = inflater.inflate(R.layout.row_buy_listing_grid, parent, false); holder = new ViewHolder(); holder.timer_layout = (LinearLayout) convertView .findViewById(R.id.timer_layout); holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_days); holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_hours); holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_mins); holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_secs); holder.listing_status = (ImageView) convertView .findViewById(R.id.listing_status); convertView.setTag(holder); } else holder = (ViewHolder) convertView.getTag(); final VehicleAttributes vehicleAttributes = mVehicleList.get(position); AuctionModel mAuctionModel = vehicleAttributes.getAuctionDetailModel(); if (mAuctionModel != null) { holder.img_auction.setVisibility(View.VISIBLE); Date auctionStartDate = Util .getDateFromString(mAuctionModel.getStarted_at(), "yyyy-MM-dd hh:mm:ss", "GMT"); Date auctionEndDate = Util.getDateFromString( mAuctionModel.getEnded_at(), "yyyy-MM-dd hh:mm:ss", "GMT"); long diff = currentDate.getTime() - auctionEndDate.getTime(); if (diff < 0) diff = -diff; else diff = 0; if (timerMap.get(position) == null || !timerMap.get(position)) { timerMap.put(position, true); MyCountDown countDown = new MyCountDown(position, diff, 1000, holder.txt_remaining_days, holder.txt_remaining_hours, holder.txt_remaining_mins, holder.txt_remaining_secs); countDown.start(); } } return convertView; } private class MyCountDown extends CountDownTimer { RobotoCondensedBoldTextView txt_remaining_days; RobotoCondensedBoldTextView txt_remaining_hours; RobotoCondensedBoldTextView txt_remaining_mins; RobotoCondensedBoldTextView txt_remaining_secs; int position; public MyCountDown(int position, long millisInFuture, long countDownInterval, RobotoCondensedBoldTextView txt_remaining_days, RobotoCondensedBoldTextView txt_remaining_hours, RobotoCondensedBoldTextView txt_remaining_mins, RobotoCondensedBoldTextView txt_remaining_secs) { super(millisInFuture, countDownInterval); this.position = position; this.txt_remaining_days = txt_remaining_days; this.txt_remaining_hours = txt_remaining_hours; this.txt_remaining_mins = txt_remaining_mins; this.txt_remaining_secs = txt_remaining_secs; } @Override public void onFinish() { } @Override public void onTick(long millisUntilFinished) { updateTimerLabel(position, millisUntilFinished, txt_remaining_days, txt_remaining_hours, txt_remaining_mins, txt_remaining_secs); } } private void updateTimerLabel(int position, long millis, RobotoCondensedBoldTextView txt_remaining_days, RobotoCondensedBoldTextView txt_remaining_hours, RobotoCondensedBoldTextView txt_remaining_mins, RobotoCondensedBoldTextView txt_remaining_secs) { String days = String.format("%02d", TimeUnit.MILLISECONDS.toDays(millis)); String hours = String.format( "%02d", TimeUnit.MILLISECONDS.toHours(millis) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS .toDays(millis))); String mins = String.format( "%02d", TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS .toHours(millis))); String secs = String.format( "%02d", TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS .toMinutes(millis))); txt_remaining_days.setText(days); txt_remaining_hours.setText(hours); txt_remaining_mins.setText(mins); txt_remaining_secs.setText(secs); } static class ViewHolder { NetworkImageView mVehicleImage; RobotoCondensedBoldTextView txt_remaining_days, txt_remaining_hours, txt_remaining_mins, txt_remaining_secs; LinearLayout timer_layout; } } 

Solutions Collecting From Web of "ListView с таймером Coundown. Таймер мерцает при прокрутке списка"

ОБНОВИТЬ

Я обновил свой ответ здесь, посмотрите: (он использует cardview с recyclerview, но тот же принцип может применяться и для listview). Как изменить текст на основе времени и даты?

Вы должны заботиться о создании экземпляра countdowntimer и при его отмене. Если вы не отмените таймер, он обновит неверные представления.

Ok позволяет сначала поговорить о проблеме

 if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); convertView = inflater.inflate(R.layout.row_buy_listing_grid, parent, false); holder = new ViewHolder(); holder.timer_layout = (LinearLayout) convertView .findViewById(R.id.timer_layout); holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_days); holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_hours); holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_mins); holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_secs); holder.listing_status = (ImageView) convertView .findViewById(R.id.listing_status); convertView.setTag(holder); } else holder = (ViewHolder) convertView.getTag(); 

Код выше в представлении списка будет повторно использовать элемент для компонентов, например, когда мы загружаем список, в списке отображаются только 6 элементов, просмотр списка создает эти элементы, но при прокрутке вверх и вниз вместо создания нового элемента он будет повторно использоваться Тот же вид для следующих позиций, поэтому, когда вы передаете свое представление countDown таймеру, чтобы обновить время, когда одни и те же представления обновляются с помощью другого таймера обратного отсчета

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

  LayoutInflater inflater = LayoutInflater.from(parent.getContext()); convertView = inflater.inflate(R.layout.row_buy_listing_grid, parent, false); holder = new ViewHolder(); holder.timer_layout = (LinearLayout) convertView .findViewById(R.id.timer_layout); holder.txt_remaining_days = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_days); holder.txt_remaining_hours = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_hours); holder.txt_remaining_mins = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_mins); holder.txt_remaining_secs = (RobotoCondensedBoldTextView) convertView .findViewById(R.id.txt_remaining_secs); holder.listing_status = (ImageView) convertView .findViewById(R.id.listing_status); convertView.setTag(holder); 

Просто удалите if(convertview==null) и разрешите раздувание нового представления для каждой строки.

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

Фрагменты – это путь: http://developer.android.com/guide/components/fragments.html

Изменить. В вашем случае вы можете запустить отдельную базу данных таймеров для каждого элемента списка, а затем просто перечислите свои элементы в своем списке. Когда пользователь должен знать время, они нажимают на ваш список, который вызывает базу данных в течение текущего времени. Это текущее время отображается в списке. Это НЕ живое, поэтому время не изменится. Это позволит избежать проблескивания.