2016-08-11 28 views
3

我已經在片段活動中爲每個RecyclerView項目實現了倒計時器。倒數計時器顯示剩餘時間到期。倒數計時器工作正常,但向上滾動時開始閃爍。搜索了很多,但沒有得到很好的參考。誰能幫我?RecyclerView在滾動時多次倒計時定時器

這是我RecyclerView適配器

public class MyOfferAdapter extends RecyclerView.Adapter<MyOfferAdapter.FeedViewHolder>{ 
private final Context mContext; 
private final LayoutInflater mLayoutInflater; 
private ArrayList<Transactions> mItems = new ArrayList<>(); 
private ImageLoader mImageLoader; 
private String imageURL; 
private View mView; 
private String mUserEmail; 

public MyOfferAdapter(Context context) { 
    mContext = context; 
    mLayoutInflater = LayoutInflater.from(context); 
    VolleySingleton mVolley = VolleySingleton.getInstance(mContext); 
    mImageLoader = mVolley.getImageLoader(); 
} 


public void addItems(ArrayList<Transactions> items,String userEmail) { 
    int count = mItems.size(); 
    mItems.addAll(items); 
    mUserEmail = userEmail; 
    notifyItemRangeChanged(count, items.size()); 
} 


@Override 
public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    mView = mLayoutInflater.inflate(R.layout.my_feed_item_layout, parent, false); 
    return new FeedViewHolder(mView); 
} 

@Override 
public void onBindViewHolder(final FeedViewHolder holder, final int position) { 
    holder.desc.setText(mItems.get(position).getDescription());//replace by title 
    holder.scratchDes.setText(mItems.get(position).getScratchDescription()); 

    long timer = mItems.get(position).getTimerExpiryTimeStamp(); 
    Date today = new Date(); 
    final long currentTime = today.getTime(); 
    long expiryTime = timer - currentTime; 


    new CountDownTimer(expiryTime, 500) { 
     public void onTick(long millisUntilFinished) { 
      long seconds = millisUntilFinished/1000; 
      long minutes = seconds/60; 
      long hours = minutes/60; 
      long days = hours/24; 
      String time = days+" "+"days" +" :" +hours % 24 + ":" + minutes % 60 + ":" + seconds % 60; 
      holder.timerValueTimeStamp.setText(time); 
     } 

     public void onFinish() { 
      holder.timerValueTimeStamp.setText("Time up!"); 
     } 
    }.start(); 

} 

@Override 
public int getItemCount() { 
    return mItems.size(); 
} 

public static class FeedViewHolder extends RecyclerView.ViewHolder { 
    TextView desc; 
    TextView scratchDes; 
    TextView timerValueTimeStamp; 
    ImageView feedImage; 
    CardView mCv; 

    public FeedViewHolder(View itemView) { 
     super(itemView); 
     mCv = (CardView) itemView.findViewById(R.id.cv_fil); 
     desc = (TextView) itemView.findViewById(R.id.desc_tv_fil); 
     feedImage = (ImageView) itemView.findViewById(R.id.feed_iv_fil); 
     scratchDes = (TextView) itemView.findViewById(R.id.tv_scratch_description); 
     timerValueTimeStamp = (TextView) itemView.findViewById(R.id.tv_timer_value_time_stamp); 

    } 

} 

這是

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="wrap_content"> 

<android.support.v7.widget.CardView  xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/cv_fil" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_margin="@dimen/card_margin" 
    android:layout_gravity="center" 
    app:cardUseCompatPadding="true" 
    app:cardElevation="4dp" 
    android:elevation="6dp"> 

    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <ImageView 
      android:id="@+id/feed_iv_fil" 
      android:layout_width="match_parent" 
      android:layout_height="200dp" 
      android:layout_alignParentTop="true" 
      android:scaleType="fitXY" 
      android:tint="@color/grey_tint_color" /> 

     <TextView 
      android:id="@+id/tv_scratch_description" 
      style="@style/ListItemText" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="center" 
      android:text="casul shoes" 
      android:fontFamily="sans-serif-light" 
      android:padding="10dp" /> 


     <TextView 
      android:id="@+id/tv_timer_value_time_stamp" 
      style="@style/CardTitle" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerInParent="true" 
      /> 

     <TextView 
      android:id="@+id/desc_tv_fil" 
      style="@style/VendorNameText" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_below="@id/feed_iv_fil" 
      android:textColor="#3f3e3f" 
      android:padding="10dp" 
      /> 

    </RelativeLayout> 


</android.support.v7.widget.CardView> 

適配器用我的XML文件,這是我RecyclerView的屏幕截圖 enter image description here

回答

10

這個問題很簡單。

RecyclerView重用持有者,每次調用綁定來更新其中的數據。

由於每次綁定任何數據時都會創建一個倒數計時器,因此最終會有多個計時器更新同一個查看人。

這裏最好的做法是將FeedViewHolder中的倒計時器作爲參考,在綁定數據(如果啓動)之前取消它並重新計劃到期望的持續時間。

public void onBindViewHolder(final FeedViewHolder holder, final int position) { 
    ... 
    if (holder.timer != null) { 
     holder.timer.cancel(); 
    } 
    holder.timer = new CountDownTimer(expiryTime, 500) { 
     ... 
    }.start(); 
} 

public static class FeedViewHolder extends RecyclerView.ViewHolder { 
    ... 
    CountDownTimer timer; 

    public FeedViewHolder(View itemView) { 
     ... 
    } 
} 

這樣,您將啓動另一個計時器之前取消這一觀點持有人任何當前的定時器實例。

+0

可以請你分享一下代碼片段 –

+0

非常感謝你......它的工作非常好 –

+0

@Lupsaa我注意到其他解決方案使用Handler和Runnable方法和對象來更新主線程中的新線程。我想知道,與解決方案相比,這些解決方案對於RecyclerView列表中的大量項目是否會更好。你能評論嗎?請參閱GergelyKőrössy的答案:http://stackoverflow.com/questions/32166375/set-counter-inside-recyclerview和H Raval的答案:http://stackoverflow.com/questions/35860780/recyclerview-with-multiple -countdown老前輩死因忽隱忽現。 – AJW