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();
}
}
}
大変、アドバイスをいただきありがとうございます。私はあなたが説明したようにそれを作ろうとします。良い一日を ! :) – mateolas
マジックのように動作します!ありがとうございました ! – mateolas