Android创建列表视图,多个倒数计时器无法正常工作

时间:2016-03-09 19:48:11

标签: java android listview timer countdown

我是android新手。目前,我在listfragment类的listview中的每个项目中尝试创建倒数计时器时遇到问题。计时器没有倒计时,它被卡在那里。任何人都可以帮我找我的问题吗?

这是我的listview类。

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
    }
}
}

这是我的适配器类。

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;

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);
    int convert = Integer.parseInt(schedule.getscheduleDuration());
    countdown = 60 * convert * 1000;
    startTimer();
    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;

            scheduleDuration.setText(String.format("%02d:%02d:%02d", seconds / 3600,
                    (seconds % 3600) / 60, (seconds % 60)));
            // format the textview to show the easily readable format

        }

        @Override
        public void onFinish() {
            // this function will be called when the timecount is finished
            scheduleDuration.setText("Time up!");
        }

    }.start();
}
}

这是我的getSchedule类:

public class getSchedule {
String scheduleId;
String scheduleName;
String scheduleDuration;

public String getscheduleId(){
    return scheduleId;
}

public void setscheduleId(String id){
    this.scheduleId=id;
}

public String getscheduleName(){
    return scheduleName;
}

public void setscheduleName(String name){
    this.scheduleName=name;
}

public String getscheduleDuration(){
    return scheduleDuration;
}

public void setscheduleDuration(String duration){
    this.scheduleDuration = duration;
}
}

我正在尝试检索数据库中每个项目的持续时间(以分钟为单位),并为列表视图中的每个项目创建倒数计时器。但是计时器刚刚停留在那里......请帮助我。谢谢。

2 个答案:

答案 0 :(得分:0)

使用更新的适配器

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();

    }
}

答案 1 :(得分:0)

每次加载视图时都会启动计时器。这意味着如果您在列表视图中向上和向下滚动几次,最终可能会在后台运行数百次。很坏。你也没有使用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);