Java Android正在创建多个倒计时计时器不工作的listview
我是android新手。目前,我在尝试在listfragment类中的listview中的每个项目中创建倒计时计时器时遇到问题。计时器没有倒计时,它在那里被卡住了。有人能帮我找出我的问题吗 这是我的listview类Java Android正在创建多个倒计时计时器不工作的listview,java,android,listview,timer,countdown,Java,Android,Listview,Timer,Countdown,我是android新手。目前,我在尝试在listfragment类中的listview中的每个项目中创建倒计时计时器时遇到问题。计时器没有倒计时,它在那里被卡住了。有人能帮我找出我的问题吗 这是我的listview类 public class OneFragment extends ListFragment { View rootView; TextView scheduleId; ListAdapter listadapter; @Override public void onActivit
public class OneFragment extends ListFragment {
View rootView;
TextView scheduleId;
ListAdapter listadapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final DBController controller = new DBController(getActivity());
final ArrayList<HashMap<String, String>> scheduleList = controller.getAllSchedules();
if (scheduleList.size()!=0){
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
scheduleId = (TextView) view.findViewById(R.id.scheduleId);
String getId = scheduleId.toString();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getActivity(), getId, duration);
toast.show();
controller.deleteSchedule(getId);
onResume();
}
});
ArrayList schedule = new ArrayList();
schedule.clear();
String query = "SELECT * FROM schedules";
Cursor c1 = controller.selectQuery(query);
if (c1 != null & c1.getCount() != 0) { //if there is item in the cursor
if (c1.moveToFirst()) { //start to move to position
do {
getSchedule schedule1 = new getSchedule(); //create object of the class getParticipant
schedule1.setscheduleId(c1.getString(c1
.getColumnIndex("scheduleId"))); //set the friend id in the object
schedule1.setscheduleName(c1.getString(c1
.getColumnIndex("scheduleName"))); //set the friend name in the object
schedule1.setscheduleDuration(c1.getString(c1.getColumnIndex("scheduleDuration")));
schedule.add(schedule1); //add the object to arraylist
} while (c1.moveToNext()); //if still have item in the cursor, loop again
}
}
c1.close();
listadapter = new ListAdapter(getActivity(), schedule);//create object of adapter class by
//passing a context and arraylist
listadapter.notifyDataSetChanged();
setListAdapter(listadapter); //set the adapter
}
}
Handler handler = new Handler();
Runnable updateRunnable= new Runnable() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() { listadapter.notifyDataSetChanged(); }
});
handler.postDelayed(this, 1000);
}
};
@Override
public void onResume() { //when user resume from an intent
super.onResume();
handler.post(updateRunnable);
if (getListView() != null) { //if the list view is not null
updateData(); //call the method updateData() to update the listView
}
}
@Override
public void onStop() {
super.onStop();
handler.removeCallbacks(updateRunnable);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_one, container, false);
return rootView;
}
public void updateData(){
final DBController controller = new DBController(getActivity());
final ArrayList<HashMap<String, String>> scheduleList = controller.getAllSchedules();
if (scheduleList.size()!=0){
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
scheduleId = (TextView) view.findViewById(R.id.scheduleId);
String getId = scheduleId.toString();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getActivity(), getId, duration);
toast.show();
controller.deleteSchedule(getId);
onResume();
}
});
ArrayList schedule = new ArrayList();
schedule.clear();
String query = "SELECT * FROM schedules";
Cursor c1 = controller.selectQuery(query);
if (c1 != null & c1.getCount() != 0) { //if there is item in the cursor
if (c1.moveToFirst()) { //start to move to position
do {
getSchedule schedule1 = new getSchedule(); //create object of the class getParticipant
schedule1.setscheduleId(c1.getString(c1
.getColumnIndex("scheduleId"))); //set the friend id in the object
schedule1.setscheduleName(c1.getString(c1
.getColumnIndex("scheduleName"))); //set the friend name in the object
schedule1.setscheduleDuration(c1.getString(c1.getColumnIndex("scheduleDuration")));
schedule.add(schedule1); //add the object to arraylist
} while (c1.moveToNext()); //if still have item in the cursor, loop again
}
}
c1.close();
ListAdapter listadapter = new ListAdapter(getActivity(), schedule);//create object of adapter class by
//passing a context and arraylist
listadapter.notifyDataSetChanged();
setListAdapter(listadapter); //set the adapter
}
}
}
我试图检索数据库中每个项目的持续时间(以分钟为单位),并为listview中的每个项目创建一个倒计时计时器。但是计时器在那里失灵了…请帮帮我。谢谢。使用更新的适配器
public class ListAdapter extends BaseAdapter {
Context ctx;
private CountDownTimer countDownTimer;
private long countdown;
private TextView scheduleDuration;
LayoutInflater lInflater;
private Handler mHandler = new Handler();
ArrayList<getSchedule> objects;
private String Duration = "";
boolean flag = true;
ListAdapter(Context context, ArrayList<getSchedule> scheduleList) {
ctx = context; //set the context
objects = scheduleList; //set the arraylist
lInflater = (LayoutInflater) ctx //set the layout
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return objects.size();
}
@Override
public Object getItem(int position) {
return objects.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
getSchedule schedule = objects.get(position);
final DBController controller = new DBController(ctx);
View view = convertView;
if (view == null) { //if view is null
view = lInflater.inflate(R.layout.view_schedule_entry, parent, false);
}
final TextView scheduleId = (TextView)view.findViewById(R.id.scheduleId);
scheduleId.setText(schedule.getscheduleId());
TextView scheduleName = (TextView)view.findViewById(R.id.scheduleName);
scheduleName.setText(schedule.getscheduleName());
scheduleDuration = (TextView)view.findViewById(R.id.scheduleDuration);
scheduleDuration.setText(Duration);
int convert = Integer.parseInt(schedule.getscheduleDuration());
countdown = 60 * convert * 1000;
if(flag){
startTimer();
flag = false;
}
return view;
}
private void startTimer() {
countDownTimer = new CountDownTimer(countdown, 500) {
// 500 means, onTick function will be called at every 500
// milliseconds
@Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
Duration =String.format("%02d:%02d:%02d", seconds / 3600,
(seconds % 3600) / 60, (seconds % 60));
// format the textview to show the easily readable format
notifyDataSetChanged();
}
@Override
public void onFinish() {
// this function will be called when the timecount is finished
Duration = "Time up!";
notifyDataSetChanged();
}
}.start();
}
}
公共类ListAdapter扩展了BaseAdapter{
上下文ctx;
私人倒计时;
私人长倒计时;
私有文本视图计划持续时间;
拉平机;
私有处理程序mHandler=新处理程序();
阵列列表对象;
私有字符串持续时间=”;
布尔标志=真;
ListAdapter(上下文上下文,ArrayList scheduleList){
ctx=context;//设置上下文
objects=scheduleList;//设置arraylist
lInflater=(LayoutInflater)ctx//设置布局
.getSystemService(上下文布局\充气机\服务);
}
@凌驾
public int getCount(){
返回objects.size();
}
@凌驾
公共对象getItem(int位置){
返回对象。获取(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
getSchedule=objects.get(位置);
最终DBController=新DBController(ctx);
视图=转换视图;
if(view==null){//if视图为null
视图=lInflater.充气(R.layout.view\u schedule\u entry,parent,false);
}
final TextView scheduleId=(TextView)view.findViewById(R.id.scheduleId);
scheduleId.setText(schedule.getscheduleId());
TextView scheduleName=(TextView)view.findViewById(R.id.scheduleName);
scheduleName.setText(schedule.getscheduleName());
scheduleDuration=(TextView)view.findViewById(R.id.scheduleDuration);
scheduleDuration.setText(持续时间);
int convert=Integer.parseInt(schedule.getscheduleDuration());
倒计时=60*convert*1000;
国际单项体育联合会(旗){
startTimer();
flag=false;
}
返回视图;
}
私有void startTimer(){
倒计时=新倒计时(倒计时,500){
//500表示每500次调用一次onTick函数
//毫秒
@凌驾
公共void onTick(长LeftTimein毫秒){
长秒=LeftTimein毫秒/1000;
持续时间=字符串。格式(“%02d:%02d:%02d”),秒/3600,
(秒数%3600)/60,(秒数%60));
//格式化文本视图以显示易于阅读的格式
notifyDataSetChanged();
}
@凌驾
公共无效onFinish(){
//时间计数完成后将调用此函数
Duration=“时间到了!”;
notifyDataSetChanged();
}
}.start();
}
}
每次加载视图时都会启动计时器。这意味着,如果在listview中上下滚动几次,最终可能会在后台运行数百次。非常糟糕。此外,您没有使用ViewHolder。您应该使用一个,它将大大提高性能。除此之外,我认为正确的方法如下。(我最近也做了同样的事情)
getSchedule对象应该有一个函数,用于计算该倒计时还剩多少时间:
public function String getTimeLeft(){
String timeLeft;
.
.
return timeLeft;
}
在适配器的getView方法中,执行以下操作:
timeLeftTextView.setText(getSchedule.getTimeLeft());
在你的活动中
// class variables
Handler handler = new Handler();
Runnable updateRunnable= new Runnable() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() { adapter.notifyDataSetChanged(); }
});
handler.postDelayed(this, 1000);
}
};
@Override
protected void onResume() {
super.onResume();
handler.postRunnable(updateRunnable);
}
@Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(updateRunnable);
}
不要忘记调用
handler.removeCallbacks(updateRunnable)代码>嗨,谢谢你的帮助。计时器现在正在移动,但它完全乱了。这就像进入一个多重循环。例如,它从59开始,然后是58,然后是59,58,57,58,57,56,59,58,59诸如此类……嗨,谢谢你的帮助。然而,它仍然受到阻碍。我已经按照您的指示进行了操作,我已经在我的getscheduleDuration类中包含了getscheduleDuration()函数。我已将持续时间转换为字符串并存储在getSchedule类中,然后在ListAdapter类中将其转换回整数。我已经更新了我的问题。你能检查一下我有没有做错什么吗?你没有照我说的做。您仍然在每次getView调用时启动计时器。我给你提供了另一个选择…处理器方法,而不是计时器。不是两个人同时在一起。如果您遵循我的方法,那么您的所有listview元素将只使用一个处理程序进行更新,而使用您的方法创建数百个计时器!除此之外,您没有正确实施计时器方法。ListView中的视图是循环使用的。你不能在后台线程中引用它们,否则你会像allready一样出现奇怪的行为。这会导致ListView“闪烁”,具体取决于你在其中的内容。(即,数据将不断从对象中重新加载)
timeLeftTextView.setText(getSchedule.getTimeLeft());
// class variables
Handler handler = new Handler();
Runnable updateRunnable= new Runnable() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() { adapter.notifyDataSetChanged(); }
});
handler.postDelayed(this, 1000);
}
};
@Override
protected void onResume() {
super.onResume();
handler.postRunnable(updateRunnable);
}
@Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(updateRunnable);
}