Recyclerview with multiple countdown timers causes flickering

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

I want to show how much time is left inside each cell of my RecyclerView...for that I have used a countdown timer for each. In each row I start a counter and manage onTick()...all works as expected...I've got a timer tick for each row and my cell is also updating but my cell is flickering now....and it goes crazy when I scroll.

Here is my adapter...

if (product.getProductType().equalsIgnoreCase("Auction Product")) {                 isAuction=true;                 viewHolder.img_product_type.setImageResource(R.drawable.bid);                 viewHolder.txt_timeleft.setVisibility(View.VISIBLE);                start_countDown(product.getStart(),product.getStop(),viewHolder.txt_timeleft);             } 

counter code is as below....

private void start_countDown(String start, String stop, final TextView txt_timeleft) {         try {             //Log.e("hetal",start+"....."+stop);             SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");              Calendar start_date = Calendar.getInstance();             start_date.setTime(format.parse(start));              Calendar end_date = Calendar.getInstance();             end_date.setTime(format.parse(stop));              final Calendar today = Calendar.getInstance();             CountDownTimer timer;              txt_timeleft.setTextColor(Color.DKGRAY);             if(today.before(start_date)){                 txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));                 txt_timeleft.setText(context.getString(R.string.auction_not_start));                 Animation anim = new AlphaAnimation(0.0f, 1.0f);                 anim.setDuration(1000); //You can manage the time of the blink with this parameter                 anim.setStartOffset(20);                 anim.setRepeatMode(Animation.REVERSE);                 anim.setRepeatCount(Animation.INFINITE);                 txt_timeleft.startAnimation(anim);                 return;             }             if (!today.before(end_date)) {                  txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));                 txt_timeleft.setText(context.getString(R.string.time_out));                         Animation anim = new AlphaAnimation(0.0f, 1.0f);                         anim.setDuration(1000); //You can manage the time of the blink with this parameter                         anim.setStartOffset(20);                         anim.setRepeatMode(Animation.REVERSE);                         anim.setRepeatCount(Animation.INFINITE);                 txt_timeleft.startAnimation(anim);                 return;             }              timer = new CountDownTimer(end_date.getTimeInMillis(), 1000) {                 @Override                 public void onTick(long millisUntilFinished) {                      Calendar calendar = Calendar.getInstance();                     calendar.setTimeInMillis(millisUntilFinished);                      long diff = calendar.getTimeInMillis() - today.getTimeInMillis();                      long seconds = diff / 1000 % 60;                     long minutes = diff / (60 * 1000) % 60;                     long hours = diff / (60 * 60 * 1000) % 24;                     //long days = (int) diff / (24 * 60 * 60 * 1000);                     long days = TimeUnit.MILLISECONDS.toDays(diff);                       String left = "";                     if (days > 0)                         left += days + " " + context.getString(R.string.txt_day) + " ,";                     if (hours > 0)                         left += hours + " " + context.getString(R.string.txt_hour) + " ,";                     if (minutes > 0)                         left += minutes + " " + context.getString(R.string.txt_minute) + " ,";                      left += seconds + " " + context.getString(R.string.txt_second);                      final String finalLeft = left;                               if (finalLeft.equals("0") || finalLeft.contains("-")) {                                 txt_timeleft.setText(context.getString(R.string.time_out));                                 txt_timeleft.setTextColor(context.getResources().getColor(R.color.red));                                 Animation anim = new AlphaAnimation(0.0f, 1.0f);                                 anim.setDuration(1000); //You can manage the time of the blink with this parameter                                 anim.setStartOffset(20);                                 anim.setRepeatMode(Animation.REVERSE);                                 anim.setRepeatCount(Animation.INFINITE);                                 txt_timeleft.startAnimation(anim);                             } else                                 txt_timeleft.setText(finalLeft);                 }                  @Override                 public void onFinish() {                  }             };             timer.start();         }catch (Exception ex){             ex.printStackTrace();         }     } 

回答1:

You need to add count down timer in your onCreateViewHolder method of RecyclerView because onCreateViewHolder will be called only once.

onBindViewHolder will be called every time user scroll up or down

please check below code.

public class UsageDetailsAdapter extends RecyclerView.Adapter {  Context mContext; int position; DecoView decoView;  public UsageDetailsAdapter(Context context) {      this.mContext = context; }  @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_adapter_usage_details, parent, false);     decoView = (DecoView) view.findViewById(R.id.dynamicArcView);       Toast.makeText(mContext,""+ position, Toast.LENGTH_SHORT).show();       position++;     return new ViewHolder(view);   }  @Override public void onBindViewHolder(ViewHolder holder, int position) {      /*     * onBindViewHolder will be called every time user scroll up or down     *     * */   }  @Override public int getItemCount() {     return 10; }  public class ViewHolder extends RecyclerView.ViewHolder {      public ViewHolder(View itemView) {         super(itemView);         decoView = (DecoView) itemView.findViewById(R.id.dynamicArcView);         decoView.setBackgroundColor(mContext.getResources().getColor(R.color.textColorPrimary));         /*         * View holder will be called once, but if user scroll before completing arc view         * animation will not be completed.         *         * */     } } 

}



回答2:

thanx Hammad Tariq Sahi i have used your logic and solve my problem in this way....i have also refereed this link

in my adapter

ArrayList viewHoldersList;     private Handler handler = new Handler();     private Runnable updateRemainingTimeRunnable = new Runnable() {         @Override         public void run() {             synchronized (viewHoldersList) {                 for (ViewHolder holder : viewHoldersList) {                     holder.updateTimeRemaining();                 }             }         }     }; 

inside constructor of my adapter

viewHoldersList = new ArrayList(); startUpdateTimer(); 

and added this method to calculate time

private void startUpdateTimer() {         Timer tmr = new Timer();         tmr.schedule(new TimerTask() {             @Override             public void run() {                 handler.post(updateRemainingTimeRunnable);             }         }, 1000, 1000);     } 

added two methods to my viewholder class

public void setData(Product product){             this.product = product;         }         public void updateTimeRemaining() {             if(product.getProductType().equalsIgnoreCase("Auction Product")) {                 Log.e("hetal",product.getProductType());                 try {                     String start = product.getStart();                     String stop = product.getStop();                      //txt_timeleft.setText("");                     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                      Calendar start_date = Calendar.getInstance();                     start_date.setTime(format.parse(start));                      Calendar end_date = Calendar.getInstance();                     end_date.setTime(format.parse(stop));                      final Calendar today = Calendar.getInstance();                     CountDownTimer timer;                      long timeDiff = end_date.getTimeInMillis() - today.getTimeInMillis();                     if (timeDiff > 0) {                         long seconds = timeDiff / 1000 % 60;                         long minutes = timeDiff / (60 * 1000) % 60;                         long hours = timeDiff / (60 * 60 * 1000) % 24;                         //long days = (int) diff / (24 * 60 * 60 * 1000);                         long days = TimeUnit.MILLISECONDS.toDays(timeDiff);                           String left = "";                         if (days > 0)                             left += days + " " + context.getString(R.string.txt_day) + " ,";                         if (hours > 0)                             left += hours + " " + context.getString(R.string.txt_hour) + " ,";                         if (minutes > 0)                             left += minutes + " " + context.getString(R.string.txt_minute) + " ,";                          left += seconds + " " + context.getString(R.string.txt_second);                          final String finalLeft = left;                         txt_timeleft.setText(finalLeft);                     } else {                         txt_timeleft.setText("Time Out !!");                     }                 } catch (Exception ex) {                     ex.printStackTrace();                 }             }         } 

and finally inside onBindViewHolder

synchronized (viewHoldersList) {                 viewHolder.setData(product);                 if(viewHoldersList.size()

works perfect....thanx all



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!