如何根据时间和日期更改文本?
How to change text based on time and date?
所以我需要两个选项之一,但不知道从哪里开始。
我在 recyclerview 中有一个列表卡片视图。每个卡片视图都需要实现倒计时计时器并能够同时 运行。 (似乎是更难的选择)或
根据指定时间是否已过或系统时间是否达到指定分钟和小时更新卡片视图中的文本。
要制作带有不同计时器的卡片,您需要线程。 Android 中最简单的方法是 AsyncTask
。因此,您创建了一堆 AsyncTask
(可能您想要一个 ArrayList
,您将向其中添加 AsyncTask
),然后循环简单地 .execute()
它们。
制作 AsyncTask
非常简单。您只需创建一个派生自 AsyncTask
的新 class 并实现 doInBackground()
方法。
P.S。如果您正在为 Android 3.0 及更高版本开发,您将需要以这种方式启动 AsyncTasks:
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
这将使他们运行同时
更新
正如其他人在其他帖子中所说,您必须知道何时启动和停止计时器,因为这会给您带来麻烦。
我设法在不取消回收器的情况下完成这项工作,所以这是我的代码。
public class ViewHolderContentCard extends RecyclerView.ViewHolder {
public TextView cardTv;
public CountdownUtils countdownUtils;
public ViewHolderContentCard(final View itemView) {
super(itemView);
cardTv = (TextView) itemView.findViewById(R.id.cardCountDownTvID);
countdownUtils = new CountdownUtils(cardTv);
}}
public class ContentRecyclerAdapterCard extends RecyclerView.Adapter<ViewHolderContentCard> {
private ArrayList<Content> mContentArrayList;
public ContentRecyclerAdapterCard(ArrayList<Content> contentArrayList) {
this.mContentArrayList = contentArrayList;
}
@Override
public ViewHolderContentCard onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_content, parent, false);
ViewHolderContentCard viewHolderContentCard = new ViewHolderContentCard(view);
return viewHolderContentCard;
}
@Override
public void onBindViewHolder(ViewHolderContentCard holder, int position) {
holder.cardTextTv.setText(mContentArrayList.get(position).getmTitle());
//update count down
holder.countdownUtils.updateCountdownTv(mContentArrayList.get(position));
}
@Override
public int getItemCount() {
return mContentArrayList.size();
}}
public class CountdownUtils {
private TextView mTextView;
private CountDownTimer mTimer;
public CountdownUtils(TextView textView) {
mTextView = textView;
}
public void updateCountdownTv(Content content) {
//cancel old timer to make sure one timer is updating one card
cleanUpTimer();
//get beginning and expiration period
String dateFrom = content.getmDateFrom();
String dateTo = content.getmDateTo();
String timeFrom = content.getmTimeFrom();
String timeTo = content.getmTimeTo();
//process dates and update the countdown
processCountDownAndUpdateUI(mTextView, dateFrom, dateTo, timeFrom, timeTo);
}
private void processCountDownAndUpdateUI(final TextView textView, String dateFrom, String dateTo, String timeFrom, String timeTo) {
try {
//format date and time
Date beginningPeriod = getDateFromString(dateFrom, timeFrom);
Date expirationPeriod = getDateFromString(dateTo, timeTo);
//check beginning period with current time
if (System.currentTimeMillis() < beginningPeriod.getTime()) {
//we know that the is not available yet so display staring period - update the UI
textView.setText("Starting from: " + dateFrom + " " + timeFrom);
} else if (expirationPeriod.getTime() > System.currentTimeMillis()) {
long availabilityPeriod = getAvailabilityPeriod(expirationPeriod);
if (availabilityPeriod != 0) {
//we have a valid avilability period so we need to start the countdown - update the UI
startCountDownTimer(textView, availabilityPeriod);
}
}
} catch (ParseException e) {
e.printStackTrace();
}
}
private void startCountDownTimer(final TextView textView, long availabilityPeriod) {
//create countdown timer, count each second
mTimer = new CountDownTimer(availabilityPeriod, 1000) {
@Override
public void onTick(long millisUntilFinished) {
//format string will be displayed
String timeSting = String.format("%d days %02d:%02d:%02d",
TimeUnit.MILLISECONDS.toDays(millisUntilFinished),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millisUntilFinished)),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
//display countdown
textView.setText(timeSting);
}
@Override
public void onFinish() {
//expired inform the user
textView.setText("Expired");
}
}.start();
}
private long getAvailabilityPeriod(Date periodFrom) {
long availabilityPeriod = 0;
//get expiration date as long
long expPeriod = periodFrom.getTime();
//check availability period
if (expPeriod > System.currentTimeMillis()) {
availabilityPeriod = expPeriod - System.currentTimeMillis();
}
return availabilityPeriod;
}
private Date getDateFromString(String date, String time) throws ParseException {
//extract data as date and time
Date formattedDate = new SimpleDateFormat("yyyy/MM/dd HH:mm").parse(date + " " + time);
return formattedDate;
}
public void cleanUpTimer() {
if (mTimer != null){
mTimer.cancel();
} }}
所以我需要两个选项之一,但不知道从哪里开始。
我在 recyclerview 中有一个列表卡片视图。每个卡片视图都需要实现倒计时计时器并能够同时 运行。 (似乎是更难的选择)或
根据指定时间是否已过或系统时间是否达到指定分钟和小时更新卡片视图中的文本。
要制作带有不同计时器的卡片,您需要线程。 Android 中最简单的方法是 AsyncTask
。因此,您创建了一堆 AsyncTask
(可能您想要一个 ArrayList
,您将向其中添加 AsyncTask
),然后循环简单地 .execute()
它们。
制作 AsyncTask
非常简单。您只需创建一个派生自 AsyncTask
的新 class 并实现 doInBackground()
方法。
P.S。如果您正在为 Android 3.0 及更高版本开发,您将需要以这种方式启动 AsyncTasks:
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
这将使他们运行同时
更新
正如其他人在其他帖子中所说,您必须知道何时启动和停止计时器,因为这会给您带来麻烦。 我设法在不取消回收器的情况下完成这项工作,所以这是我的代码。
public class ViewHolderContentCard extends RecyclerView.ViewHolder {
public TextView cardTv;
public CountdownUtils countdownUtils;
public ViewHolderContentCard(final View itemView) {
super(itemView);
cardTv = (TextView) itemView.findViewById(R.id.cardCountDownTvID);
countdownUtils = new CountdownUtils(cardTv);
}}
public class ContentRecyclerAdapterCard extends RecyclerView.Adapter<ViewHolderContentCard> {
private ArrayList<Content> mContentArrayList;
public ContentRecyclerAdapterCard(ArrayList<Content> contentArrayList) {
this.mContentArrayList = contentArrayList;
}
@Override
public ViewHolderContentCard onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_content, parent, false);
ViewHolderContentCard viewHolderContentCard = new ViewHolderContentCard(view);
return viewHolderContentCard;
}
@Override
public void onBindViewHolder(ViewHolderContentCard holder, int position) {
holder.cardTextTv.setText(mContentArrayList.get(position).getmTitle());
//update count down
holder.countdownUtils.updateCountdownTv(mContentArrayList.get(position));
}
@Override
public int getItemCount() {
return mContentArrayList.size();
}}
public class CountdownUtils {
private TextView mTextView;
private CountDownTimer mTimer;
public CountdownUtils(TextView textView) {
mTextView = textView;
}
public void updateCountdownTv(Content content) {
//cancel old timer to make sure one timer is updating one card
cleanUpTimer();
//get beginning and expiration period
String dateFrom = content.getmDateFrom();
String dateTo = content.getmDateTo();
String timeFrom = content.getmTimeFrom();
String timeTo = content.getmTimeTo();
//process dates and update the countdown
processCountDownAndUpdateUI(mTextView, dateFrom, dateTo, timeFrom, timeTo);
}
private void processCountDownAndUpdateUI(final TextView textView, String dateFrom, String dateTo, String timeFrom, String timeTo) {
try {
//format date and time
Date beginningPeriod = getDateFromString(dateFrom, timeFrom);
Date expirationPeriod = getDateFromString(dateTo, timeTo);
//check beginning period with current time
if (System.currentTimeMillis() < beginningPeriod.getTime()) {
//we know that the is not available yet so display staring period - update the UI
textView.setText("Starting from: " + dateFrom + " " + timeFrom);
} else if (expirationPeriod.getTime() > System.currentTimeMillis()) {
long availabilityPeriod = getAvailabilityPeriod(expirationPeriod);
if (availabilityPeriod != 0) {
//we have a valid avilability period so we need to start the countdown - update the UI
startCountDownTimer(textView, availabilityPeriod);
}
}
} catch (ParseException e) {
e.printStackTrace();
}
}
private void startCountDownTimer(final TextView textView, long availabilityPeriod) {
//create countdown timer, count each second
mTimer = new CountDownTimer(availabilityPeriod, 1000) {
@Override
public void onTick(long millisUntilFinished) {
//format string will be displayed
String timeSting = String.format("%d days %02d:%02d:%02d",
TimeUnit.MILLISECONDS.toDays(millisUntilFinished),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(millisUntilFinished)),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
//display countdown
textView.setText(timeSting);
}
@Override
public void onFinish() {
//expired inform the user
textView.setText("Expired");
}
}.start();
}
private long getAvailabilityPeriod(Date periodFrom) {
long availabilityPeriod = 0;
//get expiration date as long
long expPeriod = periodFrom.getTime();
//check availability period
if (expPeriod > System.currentTimeMillis()) {
availabilityPeriod = expPeriod - System.currentTimeMillis();
}
return availabilityPeriod;
}
private Date getDateFromString(String date, String time) throws ParseException {
//extract data as date and time
Date formattedDate = new SimpleDateFormat("yyyy/MM/dd HH:mm").parse(date + " " + time);
return formattedDate;
}
public void cleanUpTimer() {
if (mTimer != null){
mTimer.cancel();
} }}