我正在申请。我想在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行是adapter.add(event)行
我想问我的代码有什么问题吗?
任何人都可以帮助我找出问题所在吗?
最佳答案
我想问我的代码有什么问题吗?
您的代码天生没有错。简短的答案是您遇到了特定于Java的怪癖。忍受我:
您要调用的ArrayAdapter
构造函数的源代码如下所示:
public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {
init(context, textViewResourceId, 0, Arrays.asList(objects));
}
最后一个参数(您提供的数组)不会发生什么:通过调用
ArrayList
将其“转换”为Arrays.asList(objects)
。现在,实际上可以通过查看the documentation for this method call找到答案:
返回指定数组中对象的列表。列表的大小无法修改,即不支持添加和删除,但是可以设置元素。设置元素会修改基础数组。
基本上发生的是将您传入的数组转换为固定大小的列表(如果在运行时对代码进行断点,则应该看到一个
UnmodifiableCollection
实例-注意:与不可变的实例不同)。您不能添加或删除任何项目,而只能设置项目(它不会更改列表大小,因为它会替换现有项目),尽管默认情况下ArrayAdapter
类不会公开后者的操作。最简单的解决方案是调用等效的
ArrayAdapter
构造函数,该构造函数自己使用ArrayList
而不是数组:public ArrayAdapter(Context context, int resource, List<T> objects)
这将需要对当前代码进行一些小的更改,但是数组和列表的使用非常相似。另外,请记住在您的适配器中实现ViewHolder / RowWrapper模式-那里有很多示例。最后,将标题和描述存储在单独的数组中并没有任何好处,这与面向对象的编程和封装的思想相矛盾。只需让对象“拥有”这些属性并使用getter方法访问它们即可。
//编辑:
这是一些示例代码,说明对
ArrayAdapter
的更改,包括有关如何使用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;
}
}
关于java - adapter.add(event)抛出java.lang.UnsupportedOperationException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26190960/