adapter.add(event) throws java.lang.UnsupportedOperationExce



我正在制作一个应用程序。我想在异步任务中从服务器获得信息后添加更多项目,并用我定义的对象保存。这是我的密码。

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

适配器.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(event)我想问一下我的代码出了什么问题?有人能帮我找出问题吗?

我想问一下我的代码出了什么问题?

您的代码本身没有什么问题。简单的回答是,您遇到了一个Java特有的怪癖。请耐心等待:

您正在调用的ArrayAdapter构造函数的源代码如下所示:

public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {
    init(context, textViewResourceId, 0, Arrays.asList(objects));
}

而不是最后一个参数,即您提供的数组:它通过调用Arrays.asList(objects)"转换"为ArrayList

现在,可以通过查看这个方法调用的文档来找到答案:

返回指定数组中对象的列表不能修改列表的大小,即不支持添加和删除,但可以设置元素。设置元素会修改基础数组

基本上,您传入的数组被转换为固定大小的列表(如果您在运行时中断代码,您应该看到一个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;
    }
}

相关内容

最新更新