我有一个回收站视图,每行包含多个倒计时器。 现在,我已经设法根据倒计时器更新文本视图,但是当时间结束时,我想更改文本视图以显示"时间结束"而不是计数。
我有一个自定义视图持有者对象,它包含对Model对象的引用。 现在,我有一个可运行的
负责计算时间的对象,我有一个每500毫秒运行一次runnable的处理程序。
现在,倒数计时器工作得很好但是当时间结束时,它只是显示我" 00:00"而不是显示一个meesage"时间结束了"。
这是我的数组适配器代码。其中包含处理倒计时器的代码:
package bikurim.silverfix.com.bikurim.adapters;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import bikurim.silverfix.com.bikurim.models.Family;
import bikurim.silverfix.com.bikurim.R;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.FamilyViewHolder> implements Filterable{
private ArrayList<Family> families;
private ArrayList<Family> dataSet;
private ArrayList<FamilyViewHolder> holders;
private static long currentMillis, timeLeft;
private Timer tmr;
private Handler handler = new Handler();
private Runnable updateRemainingTimeRunnable = new Runnable() {
@Override
public void run() {
synchronized (holders) {
for (FamilyViewHolder holder : holders) {
if(!holder.family.isTimeLeft) {
currentMillis = System.currentTimeMillis();
timeLeft = holder.family.time - currentMillis;
holder.family.time = currentMillis + timeLeft;
if(holder.family.time > currentMillis) {
holder.updateFormatTime(currentMillis);
} else {
holder.family.isTimeLeft = true;
holder.timeLeft.setText("הזמן נגמר");
notifyDataSetChanged();
}
}
}
}
}
};
private FamilyFilter filter;
private boolean flagSearch;
public RecyclerViewAdapter(ArrayList<Family> families) {
this.dataSet = families;
this.families = families;
holders = new ArrayList<FamilyViewHolder>();
startUpdateTimer();
}
private void startUpdateTimer() {
tmr = new Timer();
tmr.schedule(new TimerTask() {
@Override
public void run() {
handler.post(updateRemainingTimeRunnable);
}
}, 500, 500);
}
@Override
public FamilyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.family_list_item, parent, false);
FamilyViewHolder pvh = new FamilyViewHolder(v);
synchronized (holders) {
holders.add(pvh);
}
return pvh;
}
@Override
public void onBindViewHolder(FamilyViewHolder holder, int position) {
Family family = families.get(position);
holder.setData(family);
}
@Override
public int getItemCount() {
return families.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public Filter getFilter() {
if (filter == null)
filter = new FamilyFilter();
return filter;
}
public static class FamilyViewHolder extends RecyclerView.ViewHolder {
public TextView personLname;
public TextView timeLeft;
public TextView visitors;
public Family family;
public FamilyViewHolder(View itemView) {
super(itemView);
personLname = (TextView) itemView.findViewById(R.id.person_Lname);
visitors = (TextView) itemView.findViewById(R.id.visitors);
timeLeft = (TextView) itemView.findViewById(R.id.person_timeLeft);
}
public void setData(Family item) {
family = item;
personLname.setText(family.lastName);
visitors.setText("מבקרים: "+ family.visitorsNum);
updateFormatTime(System.currentTimeMillis());
}
public void updateFormatTime(long currentMillis) {
long timeLeft = family.time - currentMillis;
int seconds = (int) (timeLeft / 1000) % 60;
int minutes = (int) ((timeLeft / (1000 * 60)) % 60);
if(seconds > 10 && minutes > 10)
this.timeLeft.setText(minutes + ":" + seconds);
else if(seconds > 10 && minutes < 10)
this.timeLeft.setText("0" + minutes + ":" + seconds);
else if (seconds < 10 && minutes > 10)
this.timeLeft.setText(minutes + ":0" + seconds);
else if (seconds < 10 && minutes < 10)
this.timeLeft.setText("0" + minutes + ":0" + seconds);
}
}
private class FamilyFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(constraint.length() == 0 || constraint == null) {
results.values = dataSet;
results.count = dataSet.size();
Log.d("Constraint is empty", "TRUE");
} else {
ArrayList<Family> queryResults = new ArrayList<Family>();
for (Family f : dataSet) {
if (constraint.charAt(0) == f.lastName.toUpperCase().indexOf(0)){
queryResults.add(f);
}
else if (f.lastName.toUpperCase().contains(constraint.toString().toUpperCase())) {
queryResults.add(f);
}
}
results.values = queryResults;
results.count = queryResults.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// Now we have to inform the adapter about the new list filtered
families = (ArrayList<Family>) results.values;
notifyDataSetChanged();
}
}
public void stopThread() {
tmr.cancel();
}
}
为什么代码不起作用?
更新: 好的,所以我设法解决了这个问题,但只是在每个将独立工作的ViewHolder中放置一个CountDownTimer对象。
现在时间到了,行项目视图和计时器的背景正在发生变化
问题是,当第一个项目的时间结束时,其他行会受此影响(它们的背景会改变,但计时器仍会正确计算)。
现在是我的适配器代码:
package bikurim.silverfix.com.bikurim.adapters;
import android.content.Context;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import bikurim.silverfix.com.bikurim.Constants;
import bikurim.silverfix.com.bikurim.models.Family;
import bikurim.silverfix.com.bikurim.R;
import bikurim.silverfix.com.bikurim.utils.HolderListener;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.FamilyViewHolder> implements Filterable, HolderListener {
// last position holds the last position of the element that was added, for animation purposes
private int lastPosition = 0;
private Context context;
private ArrayList<Family> families;
private ArrayList<Family> dataSet;
private FamilyFilter filter;
private boolean flagSearch;
public RecyclerViewAdapter(Context context, ArrayList<Family> families) {
this.context = context;
this.dataSet = families;
this.families = families;
}
@Override
public FamilyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.family_list_item, parent, false);
FamilyViewHolder pvh = new FamilyViewHolder(v, this);
return pvh;
}
@Override
public void onBindViewHolder(FamilyViewHolder holder, int position) {
Family family = families.get(position);
holder.setData(family);
}
@Override
public int getItemCount() {
return families != null ? families.size() : 0;
}
/* The following 2 methods are an implementations of the HolderListener.
* Inside every view holder lies an instance of HolderListener, for communication between the two*/
@Override
public void startAnimationOnItem(FamilyViewHolder holder) {
setAnimation(holder.cardView, holder.getAdapterPosition());
}
@Override
public void onTimeEnds(Family family) {
Toast.makeText(context, family.lastName, Toast.LENGTH_SHORT).show();
}
public void removeData(int pos) {
families.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, getItemCount());
}
public static class FamilyViewHolder extends RecyclerView.ViewHolder {
public CardView cardView;
public TextView personLname;
public TextView timeLeft;
public TextView visitors;
public Family family;
private CountDownTimer timer;
private HolderListener listener;
public FamilyViewHolder(View itemView, HolderListener listener) {
super(itemView);
this.listener = listener;
cardView = (CardView) itemView.findViewById(R.id.cv);
personLname = (TextView) itemView.findViewById(R.id.person_Lname);
visitors = (TextView) itemView.findViewById(R.id.visitors);
timeLeft = (TextView) itemView.findViewById(R.id.person_timeLeft);
}
public void setData(Family item) {
family = item;
personLname.setText(family.lastName);
visitors.setText("מבקרים: " + family.visitorsNum);
setUpTimer();
}
public void setUpTimer() {
long timeLeftInMillis = family.time - System.currentTimeMillis();
timer = new CountDownTimer(timeLeftInMillis, 1000) {
public void onTick(long millisUntilFinished) {
timeLeft.setText(updateFormatTime(millisUntilFinished));
family.time = System.currentTimeMillis() + millisUntilFinished;
}
public void onFinish() {
notifyTimeEnd();
cancel();
}
};
timer.start();
}
public void notifyTimeEnd() {
family.isTimeLeft = true;
timeLeft.setText("הזמן נגמר ");
cardView.setBackgroundResource(R.color.time_up_bg);
listener.startAnimationOnItem(this);
listener.onTimeEnds(family);
}
}
/* Starts a slide in animation for a given Card View */
private void setAnimation(View viewToAnimate, int position) {
if(position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
public static String updateFormatTime(long millisUntilFinished) {
String result = "";
int seconds = (int) (millisUntilFinished / 1000) % 60;
int minutes = (int) ((millisUntilFinished / (1000 * 60)) % 60);
if (seconds > 10 && minutes > 10)
result = minutes + ":" + seconds;
else if (seconds > 10 && minutes < 10)
result = "0" + minutes +ing ":" + seconds;
else if (seconds < 10 && minutes > 10)
result = minutes + ":0" + seconds;
else if (seconds < 10 && minutes < 10)
result = "0" + minutes + ":0" + seconds;
return result;
}
}
在我的活动中,我有一个ItemTouchHelper对象,用于支持滑动到删除机制。以下是此代码:
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
final int pos = viewHolder.getAdapterPosition();
AlertDialog.Builder builder = new AlertDialog.Builder(FamilyListActivity.this);
builder.setMessage(R.string.confirmation_message)
.setPositiveButton(R.string.proceed_confirmation_dialog, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
adapter.removeData(pos);
String name = ((RecyclerViewAdapter.FamilyViewHolder) viewHolder).family.lastName;
Toast.makeText(FamilyListActivity.this, "משפחת "+name+" נמחקה מהרשימה", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}).setNegativeButton(R.string.cancel_confirmation_dialog, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
adapter.notifyItemChanged(pos);
dialog.dismiss();
}
});
builder.show();
}
};
为什么当一个项目删除时,它会影响列表中的所有其他项目?
答案 0 :(得分:0)
尝试
public void updateFormatTime(long currentMillis) {
long timeLeft = family.time - currentMillis;
int seconds = (int) (timeLeft / 1000) % 60;
int minutes = (int) ((timeLeft / (1000 * 60)) % 60);
if(seconds > 10 && minutes > 10)
this.timeLeft.setText(minutes + ":" + seconds);
else if(seconds > 10 && minutes < 10)
this.timeLeft.setText("0" + minutes + ":" + seconds);
else if (seconds < 10 && minutes > 10)
this.timeLeft.setText(minutes + ":0" + seconds);
else if(seconds == 0 && minutes == 0)
this.timeLeft.setText("Time is Over");
else if (seconds < 10 && minutes < 10)
this.timeLeft.setText("0" + minutes + ":0" + seconds);
}
答案 1 :(得分:0)
您的代码不必要地过于复杂,但是当您进行更新时,TextView
文本会使用这样一个简单的三元运算符:
youTextView.setText(resultText.equals("00:00") ? "Time is over" : resultText);
假设resultText
String var是您从runnable获得的结果。