2017-05-07 1 views
0

RecyclerViewでカウントダウンタイマーを実装する際に問題があります。 RecyclerViewへのデータ入力はDialogから行われます。ここで、ユーザーはアイテムの名前を入力し、SeekBar時間を秒単位で設定し、カスタムウィジェットで日付を選択します。情報はRealmデータベースに保存されます。RecyclerViewAdapterでタイマーを実装する

問題は、アプリケーションを再起動したり、新しいアイテムを追加したりすると、すべてのアイテムのすべてのタイマーが再起動し、最初からカウントを開始するという問題です。アプリがアクティブでなくても、新しいアイテムを追加しているときでも、数え切れないほどカウントされるタイマーを実装する方法。事前にお手伝いいただきありがとうございます。

public class AdapterDrops extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements SwipeListener { 

public static final int COUNT_FOOTER = 1; 
public static final int COUNT_NO_ITEMS = 1; 
public static final int ITEM = 0; 
public static final int NO_ITEM = 1; 
public static final int FOOTER = 2; 
private final ResetListener mResetListener; 
private MarkListener mMarkListener; 
//inflater object which converts xml file to view object 
private LayoutInflater mInflater; 
public RealmResults<Drop> mResults; 
private AddListener mAddListener; 
private int mFilterOption; 
private Realm mRealm; 
private Context mContext; 
Handler handler; 
public long duration; 


public AdapterDrops(Context context, Realm realm, RealmResults<Drop> results, AddListener listener, MarkListener markListener, ResetListener resetListener) { 
    mContext = context; 
    mInflater = LayoutInflater.from(context); 
    update(results); 
    mRealm = realm; 
    mAddListener = listener; 
    mMarkListener = markListener; 
    mResetListener = resetListener; 

} 

public void update(RealmResults<Drop> results) { 
    mResults = results; 
    mFilterOption = AppBucketDrops.load(mContext); 
    //notification do Apdapter that database was changed 
    notifyDataSetChanged(); 

} 

@Override 
public long getItemId(int position) { 
    if (position < mResults.size()) { 
     return mResults.get(position).getAdded(); 
    } 
    return RecyclerView.NO_ID; 
} 

@Override 
public int getItemViewType(int position) { 
    if (!mResults.isEmpty()) { 
     if (position < mResults.size()) { 
      return ITEM; 
     } else { 
      return FOOTER; 
     } 
    } else { 
     if (mFilterOption == Filter.COMPLETE || 
       mFilterOption == Filter.INCOMPLETE) { 
      if (position == 0) { 
       return NO_ITEM; 
      } else { 
       return FOOTER; 
      } 
     } else { 
      return ITEM; 
     } 
    } 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    if (viewType == FOOTER) { 
     View view = mInflater.inflate(R.layout.footer, parent, false); 
     //footerHolder class which we created below 
     return new FooterHolder(view); 
    } else if (viewType == NO_ITEM) { 
     View view = mInflater.inflate(R.layout.no_item, parent, false); 
     return new NoItemsHolder(view); 
    } else { 
     //layourInflater converts xml file to java View object 
     View view = mInflater.inflate(R.layout.row_drop, parent, false); 
     return new DropHolder(view, mMarkListener); 
    } 
} 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    if (holder instanceof DropHolder) { 
     DropHolder dropHolder = (DropHolder) holder; 
     //returning an item from the paricular position 
     Drop drop = mResults.get(position); 
     //seting MtextView to proper drop.getWhat text 
     dropHolder.setWhat(drop.getWhat()); 
     dropHolder.setWhen(drop.getWhen()); 
     dropHolder.setTimer(drop.getTimer()); 
     dropHolder.setBackground(drop.isCompleted()); 
    } 

} 

@Override 
public int getItemCount() { 
    if (!mResults.isEmpty()) { 
     return mResults.size() + COUNT_FOOTER; 
    } else { 
     if (mFilterOption == Filter.LEAST_TIME_LEFT 
       || mFilterOption == Filter.MOST_TIME_LEFT 
       || mFilterOption == Filter.NONE) { 
      return 0; 
     } else { 
      return COUNT_NO_ITEMS + COUNT_FOOTER; 
     } 
    } 

} 


@Override 
public void onSwipe(int position) { 
    //delete item with transaction from database 
    if (position < mResults.size()) { 
     mRealm.beginTransaction(); 
     mResults.get(position).deleteFromRealm(); 
     mRealm.commitTransaction(); 
     notifyItemRemoved(position); 
    } 
    resetFilterIfEmpty(); 
} 

private void resetFilterIfEmpty() { 
    if (mResults.isEmpty() && (mFilterOption == Filter.COMPLETE || mFilterOption == Filter.INCOMPLETE)) { 
     mResetListener.onReset(); 
    } 
} 

public void markComplete(int position) { 
    //checking that item is not a footer 
    if (position < mResults.size()) { 
     mRealm.beginTransaction(); 
     mResults.get(position).setCompleted(true); 
     mRealm.commitTransaction(); 
     notifyItemChanged(position); 
    } 
} 

public static class DropHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
    TextView mTextWhat; 
    TextView mTextWhen; 
    MarkListener mMarkListener; 
    Context mContext; 
    View mItemView; 
    TextView mTimer; 
    //timer 
    Handler handler; 
    public long timeRemaining; 
    public Drop drop; 

    public DropHolder(View itemView, MarkListener listener) { 
     super(itemView); 
     mItemView = itemView; 
     mContext = itemView.getContext(); 
     itemView.setOnClickListener(this); 
     mTextWhat = (TextView) itemView.findViewById(R.id.tv_what); 
     mTextWhen = (TextView) itemView.findViewById(R.id.tv_when); 
     mTimer = (TextView) itemView.findViewById(R.id.tv_timer); 
     mMarkListener = listener; 

    } 

    public void setWhat(String what) { 
     mTextWhat.setText(what); 
    } 

    public Drop getDrop(Drop drop) { 
     return drop; 
    } 

    public void setTimer(long timer) { 

     handler = new Handler(); 
     timeRemaining = timer * 1000; 
     final Runnable runnable = new Runnable() { 
      @Override 
      public void run() { 
       timeRemaining = timeRemaining - 1000; 

       if (timeRemaining > 0) { 
        handler.postDelayed(this, 1000); 
        timeRemaining = timeRemaining/1000; 
        mTimer.setText(Long.toString(timeRemaining)); 
        timeRemaining = timeRemaining * 1000; 
       } 
       if (timeRemaining == 0) { 
        mTimer.setText("Czas na lek !"); 
       } 
      } 
     }; 
     //kickstart 
     handler.postDelayed(runnable, 1000); 
    } 

    @Override 
    public void onClick(View v) { 
     mMarkListener.onMark(getAdapterPosition()); 
    } 

    public void setBackground(boolean completed) { 
     Drawable drawable; 
     if (completed) { 
      drawable = ContextCompat.getDrawable(mContext, R.color.colorLightBlueAfterClick); 
     } else { 
      drawable = ContextCompat.getDrawable(mContext, R.drawable.bg_row_drop); 
     } 
     /*if(Build.VERSION.SDK_INT > 15){ 
      mItemView.setBackground(drawable); 
     } else{ 
      mItemView.setBackgroundDrawable(drawable); 
     }*/ 
     Util.setBackground(mItemView, drawable); 

    } 

    public void setWhen(long when) { 
     mTextWhen.setText(DateUtils.getRelativeTimeSpanString(when, System.currentTimeMillis(), DateUtils.DAY_IN_MILLIS, 0)); 

    } 
} 

public static class NoItemsHolder extends RecyclerView.ViewHolder { 

    public NoItemsHolder(View itemView) { 
     super(itemView); 
    } 
} 

public class FooterHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
    Button mBtnAdd; 

    public FooterHolder(View itemView) { 
     super(itemView); 
     mBtnAdd = (Button) itemView.findViewById(R.id.btn_footer); 
     mBtnAdd.setOnClickListener(this); 

    } 

    @Override 
    public void onClick(View v) { 
     //were using from this place AddListener 
     mAddListener.add(); 
    } 
} 

}

答えて

0

代わりのカウントダウン時間を節約し、終了日時(日時今+カウントダウン)とベースその上にロジックを保存します。アプリがリセットまたはビューをリセットすると、カウントダウンロジックは、datetimeとend datetimeを比較することで途絶えたところで続行されます。

さらに、あなたが投稿したコードは、ユーザが見ることができないものであっても、すべてのビューに対して毎秒Runnableを投稿しています。これは、アプリケーションのパフォーマンスが低下します。代わりに、RecyclerView.AdapterをホストするActivityによって制御される可能性のある単一のタイマーを作成し、RecyclerView.Adapter.onBindViewHolder()を呼び出してUIを更新するRecyclerView.Adapter.notifyDataSetChanged()を呼び出します。したがって、アダプタはすべての目に見えるUI要素を更新します。つまり、カウントダウンUI(目に見えるUIのみ)が毎秒更新されます。スクロールするときでさえ、RecyclerView.Adapter.onBindViewHolder()と呼ばれるので注意が必要です。これにより、データセットが大きい場合にアプリのパフォーマンスが大幅に向上します。

+0

大変、アドバイスをいただきありがとうございます。私はあなたが説明したようにそれを作ろうとします。良い一日を ! :) – mateolas

+0

マジックのように動作します!ありがとうございました ! – mateolas

関連する問題