Android的ListView的适配器不会刷新适配器、Android、ListView

2023-09-06 03:14:46 作者:◇、囡亾忲兲嫃

我有很多的麻烦刷新列表视图自定义适配器。我一直在网上寻找过去一小时,我似乎无法找到任何解决方案,这将使我的列表视图刷新。

我已经试过notifyDataSetChanged,也listView.invalidate,但似乎没有奏效。任何帮助将大大AP preciated。我可以看到数据使用的logcat被更新,但它没有被刷新的屏幕上,我不知道为什么。

下面是code。

 的ArrayList<学生>学生=新的ArrayList<学生>();

列表视图=(ListView控件)findViewById(R.id.listView);
适配器=新StudentAdapter(这一点,R.layout.listitemlayout,学生);
listview.setAdapter(适配器);
 

自定义适配器

 公共类StudentAdapter扩展ArrayAdapter<学生> {

    上下文语境;
    INT layoutResourceId;
    ArrayList的<学生>数据= NULL;

    公共StudentAdapter(上下文的背景下,诠释layoutResourceId,ArrayList的<学生>数据){
        超级(上下文,layoutResourceId,数据);
        this.layoutResourceId = layoutResourceId;
        this.context =背景;
        this.data =数据;
    }

    公共无效updateStudentsList(ArrayList中<学生> newlist){
        data.clear();
        数据= newlist;
        this.notifyDataSetChanged();
    }

    公共无效updateStudentTime(){
        对于(学生S:数据){
            s.updateElapsedTime();
        }
        this.notifyDataSetChanged();
    }

    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        查看排= convertView;
        如果(行== NULL){
            LayoutInflater充气=((活动)上下文).getLayoutInflater();
            行= inflater.inflate(layoutResourceId,父母,假);

            学生学生= data.get(位置);

            TextView的标题=(TextView中)row.findViewById(R.id.txtTitle);
            title.setText(student.getFirstname()++ stu​​dent.getLastname());

            TextView的字幕=(TextView中)row.findViewById(R.id.txtSubTitle);
            subTitle.setText(student.getStudentID());

            TextView的持续时间=(TextView中)row.findViewById(R.id.textDuration);
            duration.setText(student.getElapsedTime());
        }
        返回行;
    }
}
 

我使用一个线程,每隔一段时间更新数据。

 可运行可运行=新的Runnable(){
            公共无效的run(){
                runOnUiThread(新的Runnable(){
                    公共无效的run(){
                        //更新学生在市中心多长时间。
                        adapter.updateStudentTime();
                        adapter.notifyDataSetChanged();
                        listview.invalidate();
                        Log.i(调试,运行UI线程);
                    }
                });
                handler.postDelayed(这一点,1000);
            }
        };
        handler.postDelayed(可运行,1000);
 
android 自定义listview适配器怎么刷新

解决方案

ListView控件将回收的看法,所以你必须在getView设置数据。 我 F(行== NULL){意味着数据不会刷新,只使用旧数据。

你应该做的是这样的:

 类ViewHolder {
   TextView的称号;
   TextView的字幕;
   TextView的持续时间;
}

@覆盖
公共查看getView(INT位置,查看convertView,ViewGroup中父){
    查看排= convertView;
    ViewHolder支架=无效;
    如果(行== NULL){
        LayoutInflater充气=((活动)上下文).getLayoutInflater();
        行= inflater.inflate(layoutResourceId,父母,假);

        学生学生= data.get(位置);
        持有人=新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(保持器);
    } 其他 {
        支架= row.getTag();
    }
    holder.title.setText(student.getFirstname()++ stu​​dent.getLastname());
    holder.subTitle.setText(student.getStudentID());
    holder.duration.setText(student.getElapsedTime());
    返回行;
}
 

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

解决方案

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