我正在申请。我想在asynctask中从服务器获取信息后添加更多项目,并使用我定义的对象保存。 这是我的代码。
EventCheck.java
private void put(final Event event){
if(event!=null){
events = push(events,event);
Log.d("no after= ",Integer.toString(event.getNo()));
if(!firsttime){
context.runOnUiThread(new Runnable() {
@Override
public void run() {
adapter = new Eventlist(context,getEvents());
adapter.setNotifyOnChange(true);
list.setAdapter(adapter);
}
});
firsttime=true;
}else{
context.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("no = ",Integer.toString(event.getNo()));
Log.d("title = ",event.getTitle());
Log.d("description = ",event.getDescription());
adapter.add(event);
adapter.notifyDataSetChanged();
}
});
}
}
}
adapter.java
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class Eventlist extends ArrayAdapter<Event>{
private final Activity context;
private final Event[] events;
private final String[] title;
private final String[] description;
public Eventlist(Activity context,Event[] events) {
super(context, R.layout.list_event, events);
this.context = context;
this.events = events;
this.title = new String[events.length];
this.description = new String[events.length];
for(int i=0;i<events.length;i++){
title[i]=events[i].getTitle();
description[i] = events[i].getDescription();
}
};
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_event, null, true);
TextView txtContent = (TextView) rowView.findViewById(R.id.belisttitle);
String line = new StringBuilder().append(position+1).append(" .").append(" ").append(title[position]).append(System.getProperty ("line.separator")).toString();
line = new StringBuilder().append(line).append(description[position]).toString();
txtContent.setText(line);
return rowView;
}
}
抛出以下异常:
10-04 16:07:56.855: E/AndroidRuntime(14835): java.lang.UnsupportedOperationException
10-04 16:07:56.855: E/AndroidRuntime(14835): at java.util.AbstractList.add(AbstractList.java:404)
10-04 16:07:56.855: E/AndroidRuntime(14835): at java.util.AbstractList.add(AbstractList.java:425)
10-04 16:07:56.855: E/AndroidRuntime(14835): at android.widget.ArrayAdapter.add(ArrayAdapter.java:179)
10-04 16:07:56.855: E/AndroidRuntime(14835): at com.xxx.xxx.Eventcheck$2.run(Eventcheck.java:257)
10-04 16:07:56.855: E/AndroidRuntime(14835): at android.os.Handler.handleCallback(Handler.java:733)
10-04 16:07:56.855: E/AndroidRuntime(14835): at android.os.Handler.dispatchMessage(Handler.java:95)
10-04 16:07:56.855: E/AndroidRuntime(14835): at android.os.Looper.loop(Looper.java:136)
10-04 16:07:56.855: E/AndroidRuntime(14835): at android.app.ActivityThread.main(ActivityThread.java:5140)
10-04 16:07:56.855: E/AndroidRuntime(14835): at java.lang.reflect.Method.invokeNative(Native Method)
10-04 16:07:56.855: E/AndroidRuntime(14835): at java.lang.reflect.Method.invoke(Method.java:515)
10-04 16:07:56.855: E/AndroidRuntime(14835): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
10-04 16:07:56.855: E/AndroidRuntime(14835): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
10-04 16:07:56.855: E/AndroidRuntime(14835): at dalvik.system.NativeStart.main(Native Method)
第257行是适配器行.add(事件) 我想问一下我的代码有什么问题? 任何人都可以帮我找出问题吗?
答案 0 :(得分:3)
我想问一下我的代码有什么问题?
您的代码没有任何内在错误。简短的回答是,您正在遇到特定于Java的怪癖。忍受我:
您调用的ArrayAdapter
构造函数的源代码如下所示:
public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {
init(context, textViewResourceId, 0, Arrays.asList(objects));
}
不是最后一个参数,即你提供的数组会发生什么:它被转换为&#39;通过致电ArrayList
将Arrays.asList(objects)
改为UnmodifiableCollection
。
现在,通过查看the documentation for this method call:
,实际上可以找到答案返回指定数组中对象的List。 无法修改List的大小,即不支持添加和删除,但可以设置元素。设置元素会修改基础数组。
基本上会发生的事情是您传入的数组被转换为固定大小列表(如果您在运行时断开代码,则应该看到ArrayAdapter
实例 - 注意:与 immutable 不同。您无法添加或删除任何项目,但只能设置项目(在替换现有项目时不会更改列表大小),尽管ArrayAdapter
类不会公开后一项操作默认情况下。
最简单的解决方案是调用等效的ArrayList
构造函数,而不是自己使用public ArrayAdapter(Context context, int resource, List<T> objects)
而不是数组:
ArrayAdapter
这需要对您当前的代码进行一些小的更改,但数组和列表与使用非常相似。另外,请记住在适配器中实现ViewHolder / RowWrapper模式 - 有很多例子。最后,存储标题并没有任何好处。描述成单独的数组,它与面向对象编程和封装的概念相矛盾。只要让对象拥有&#39;这些属性并使用getter方法来访问它们。
<强> //编辑:强>
以下是一些示例代码,用于说明ViewHolder
的更改,包括如何使用put()
模式。我直接在浏览器中输入了这个,所以请注意任何类型/语法错误。
您仍然需要稍微更改您的public class Eventlist extends ArrayAdapter<Event>{
private static final String LINE_SEPARATOR = System.getProperty ("line.separator");
public Eventlist(Context context, List<Event> events) {
super(context, R.layout.list_event, events);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
View rowView = view;
ViewHolder holder;
if (rowView == null) {
holder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
rowView = inflater.inflate(R.layout.list_event, null, true);
holder.txtContent = (TextView) rowView.findViewById(R.id.belisttitle);
rowView.setTag(holder);
} else {
holder = (ViewHolder) rowView.getTag();
}
Event event = getItem(position);
StringBuilder line = new StringBuilder(position+1)
.append(" . ")
.append(event.getTitle())
.append(LINE_SEPARATOR)
.append(event.getDescription());
holder.txtContent.setText(line);
return rowView;
}
static class ViewHolder {
private TextView txtContent;
}
}
方法,以便它可以使用事件列表而不是数组,但我会留下您的答案。网上有很多可以帮助你的例子。
{{1}}