Android ListView adapter wont refresh

2019-03-29 10:51发布

I'm having a lot of trouble refreshing a list view with a custom adapter. I've been searching online for the past hour and I can't seem to find any solution that will make my list view refresh.

I've tried notifyDataSetChanged, and also listView.invalidate, but nothing seems to be working. Any help would be greatly appreciated. I can see the data being updated using logcat, but it is not being refreshed on the screen and I have no idea why.

Below is the code.

ArrayList<Student> students = new ArrayList<Student>();

listview = (ListView) findViewById(R.id.listView);
adapter = new StudentAdapter(this, R.layout.listitemlayout, students);  
listview.setAdapter(adapter);

Custom Adapter

public class StudentAdapter extends ArrayAdapter<Student>{

    Context context; 
    int layoutResourceId;    
    ArrayList<Student> data = null;

    public StudentAdapter(Context context, int layoutResourceId, ArrayList<Student> data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    public void updateStudentsList(ArrayList<Student> newlist){
        data.clear();
        data = newlist;
        this.notifyDataSetChanged();
    }

    public void updateStudentTime(){
        for (Student s : data) {
            s.updateElapsedTime();          
        }
        this.notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null){
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            Student student = data.get(position);

            TextView title = (TextView)row.findViewById(R.id.txtTitle);
            title.setText(student.getFirstname() + " " + student.getLastname());

            TextView subTitle = (TextView)row.findViewById(R.id.txtSubTitle);
            subTitle.setText(student.getStudentID());       

            TextView duration = (TextView)row.findViewById(R.id.textDuration);
            duration.setText(student.getElapsedTime());
        }
        return row;
    }
}

I update the data using a thread every so often.

Runnable runnable = new Runnable() {
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        // Updates how long the student is in the centre.
                        adapter.updateStudentTime();
                        adapter.notifyDataSetChanged();
                        listview.invalidate();
                        Log.i("Debug", "Running on UI Thread");
                    }
                });
                handler.postDelayed(this, 1000);
            }
        };
        handler.postDelayed(runnable, 1000);

2条回答
聊天终结者
2楼-- · 2019-03-29 10:56

Think the below code prevent you refresh the list.

if(row == null){    
...
}

The code said that when the list refresh. It will be check the row is null (mean the row display in Screen is created or not ). When you refresh the list, the row already created. So it is NOT NULL, the new data will not set !

You should change something like this:

public View getView(int position, View convertView, ViewGroup parent) {

    View row = convertView;

    if(row == null){
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

    } 

    Student student = data.get(position);
    ...

}
查看更多
劳资没心,怎么记你
3楼-- · 2019-03-29 11:04

ListView will recycle the view, so you must set data in getView. and if(row == null){ means that data will not refresh, only use the old data.

you should do like this:

Class ViewHolder {
   TextView title;
   TextView subTitle;
   TextView duration;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ViewHolder holder = null;
    if(row == null){
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        Student student = data.get(position);
        holder = new ViewHolder();
        holder.title = (TextView)row.findViewById(R.id.txtTitle);
        holder.subTitle = (TextView)row.findViewById(R.id.txtSubTitle);
        holder.duration = (TextView)row.findViewById(R.id.textDuration);
        row.setTag(holder);
    } else {
        holder = row.getTag();
    }
    holder.title.setText(student.getFirstname() + " " + student.getLastname());
    holder.subTitle.setText(student.getStudentID());   
    holder.duration.setText(student.getElapsedTime());    
    return row;
}
查看更多
登录 后发表回答