adapter.add(event)抛出java.lang.UnsupportedOperationException

时间:2014-10-04 08:14:08

标签: java android android-listview android-asynctask android-arrayadapter

我正在申请。我想在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(事件) 我想问一下我的代码有什么问题? 任何人都可以帮我找出问题吗?

1 个答案:

答案 0 :(得分:3)

  

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

您的代码没有任何内在错误。简短的回答是,您正在遇到特定于Java的怪癖。忍受我:

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

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

不是最后一个参数,即你提供的数组会发生什么:它被转换为&#39;通过致电ArrayListArrays.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}}