我有很多的麻烦刷新列表视图自定义适配器。我一直在网上寻找过去一小时,我似乎无法找到任何解决方案,这将使我的列表视图刷新。
我已经试过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()++ student.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);
解决方案
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()++ student.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;
}