Android 自定义 ListView IndexOutOfBoundsException

Android Custom ListView IndexOutOfBoundsException

我需要你的帮助。

我有一个包含三个元素的自定义列表视图。当我按下加号按钮时,一个新项目将被添加到列表中。 ListView 应该更新。

但是我得到以下错误

    04-16 15:54:52.177: E/AndroidRuntime(32601): Process: de.schatner.sino.main, PID: 32601
04-16 15:54:52.177: E/AndroidRuntime(32601): java.lang.IndexOutOfBoundsException: Invalid index 8, size is 8
04-16 15:54:52.177: E/AndroidRuntime(32601):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at java.util.ArrayList.get(ArrayList.java:308)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at de.schatner.sino.main.MainActivity$ListAdapter.getView(MainActivity.java:201)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.obtainView(AbsListView.java:2823)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.ListView.makeAndAddView(ListView.java:1884)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.ListView.fillDown(ListView.java:713)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.ListView.fillGap(ListView.java:677)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:7040)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:4162)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.startScrollIfNeeded(AbsListView.java:4090)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.onTouchMove(AbsListView.java:5511)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.onTouchEvent(AbsListView.java:5366)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.View.dispatchTouchEvent(View.java:8981)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2698)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2410)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:5308)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2568)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1776)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.app.Activity.dispatchTouchEvent(Activity.java:2866)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2529)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.View.dispatchPointerEvent(View.java:9186)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4706)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4544)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4201)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4258)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6564)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6454)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6425)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6654)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6625)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:6677)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
04-16 15:54:52.177: E/AndroidRuntime(32601):    at android.view.Choreographer.doCallbacks(Chor

我在下面发布我的代码:

MainActivity.java

public class MainActivity extends ListActivity {

    private ArrayList<NoticeDTO> lists = null;
    private ListAdapter listAdapter;
    final Activity activity = this;
    public int i=1;
    private EditText et_search;
    private SQLiteHandler dbHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ActionBar bar = this.getActionBar();
        bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#48cfae")));
        bar.setDisplayShowHomeEnabled(false);

        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(getResources().getColor(R.color.flattygreendark));

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbHandler = new SQLiteHandler(this);
        LinkedList<NoticeDTO> notices= dbHandler.getAllNotes();
        lists = new ArrayList<NoticeDTO>();
        lists.addAll(notices);
        this.listAdapter = new ListAdapter(this, R.layout.listrow, lists);
        setListAdapter(this.listAdapter);
        this.getListView().setTextFilterEnabled(true);

        this.et_search=  (EditText) this.findViewById(R.id.et_search);
        this.et_search.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                MainActivity.this.listAdapter.getFilter().filter(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        final Button bt_delete= (Button) this.findViewById(R.id.bt_delete);
        bt_delete.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                et_search.setText("");
            }
        });

        final Button bt_set_event= (Button) this.findViewById(R.id.bt_new_event);
        bt_set_event.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {

                GregorianCalendar calendar = new GregorianCalendar();
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

                String date=""+calendar.get(Calendar.DAY_OF_MONTH)+"."+calendar.get(Calendar.MONTH)+"."+calendar.get(Calendar.YEAR);
                date+=" "+sdf.format(calendar.getTime());

                try{
                    long rowId= dbHandler.insertNewNotice("Testliste für den zzz Einkauf \n"
                            + "laoasd asdj asdjas ",date,date);
                }catch(Exception e){
                    e.printStackTrace();
                }
                LinkedList<NoticeDTO> notices = new LinkedList<NoticeDTO>();
                notices= dbHandler.getAllNotes();
                lists.clear();
                lists.addAll(notices);
                listAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id){
        NoticeDTO notice=(NoticeDTO) l.getItemAtPosition(position);
        Intent i= new Intent(MainActivity.this, NoticeActivity.class);
        i.putExtra("text", notice.getText());
        i.putExtra("noticeId", notice.getId());
        startActivity(i);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onResume(){
        super.onResume();
        this.onCreate(null);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    //private class
    private class ListAdapter extends ArrayAdapter<NoticeDTO> {

        private ArrayList<NoticeDTO> originalList;
        private ArrayList<NoticeDTO> noticeList;
        private NoticeFilter filter;

        public ListAdapter(Context context, int textViewResourceId,
                ArrayList<NoticeDTO> noticeList) {
            super(context, textViewResourceId, noticeList);

            this.noticeList = new ArrayList<NoticeDTO>();
            this.noticeList.addAll(noticeList);
            this.originalList = new ArrayList<NoticeDTO>();
            this.originalList.addAll(noticeList);
        }

        @Override
        public Filter getFilter() {
            if (filter == null) {
                filter = new NoticeFilter();
            }
            return filter;
        }

        private class ViewHolder {
            TextView toptext;
            TextView bottomtext;
            TextView footertext;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View v= convertView;
            ViewHolder holder = null;

            if (convertView == null) {
                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.listrow, null);

                holder = new ViewHolder();
                holder.toptext = (TextView) v.findViewById(R.id.toptext);
                holder.bottomtext = (TextView) v.findViewById(R.id.bottomtext);
                holder.footertext = (TextView) v.findViewById(R.id.footertext);
                v.setTag(holder);
            }else{
                holder = (ViewHolder) v.getTag();
            }

            NoticeDTO notice = noticeList.get(position);
            if (notice != null) {
                if(notice.getText().length()>20){
                    holder.toptext.setText(notice.getText().substring(0, 20)+"...");
                }else{
                    holder.toptext.setText(notice.getText());
                }
                holder.bottomtext.setText(notice.getCreate_date()+"(ID: "+notice.getId()+")");
                holder.footertext.setText("Zuletzt geändert am: "+notice.getEdit_date());
            }
            return v;
        }

        private class NoticeFilter extends Filter{

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                constraint = constraint.toString().toLowerCase(Locale.GERMANY);
                FilterResults result = new FilterResults();
                if(constraint != null && constraint.toString().length() > 0){
                    ArrayList<NoticeDTO> filteredItems = new ArrayList<NoticeDTO>();
                    for(int i = 0, l = originalList.size(); i < l; i++){
                        NoticeDTO notice = originalList.get(i);
                         if(notice.getText().toLowerCase(Locale.GERMANY).contains(constraint)){
                             filteredItems.add(notice);
                         }
                    }
                    result.count = filteredItems.size();
                    result.values = filteredItems;
                }else{
                     synchronized(this){
                     result.values = originalList;
                     result.count = originalList.size();
                    }
                }
                return result;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                noticeList = (ArrayList<NoticeDTO>) results.values;
                notifyDataSetChanged();
                clear();
                for(int i = 0, l = noticeList.size(); i < l; i++){
                    add(noticeList.get(i));
                }
                notifyDataSetInvalidated();
            }
        }
    }
}

ListView 的刷新不起作用。

请帮助别人!

问题是在您的代码的第 201 行发生了 IndexOutOfBoundsException(您的 ListAdapter 私有的 getView 方法 class)以后请在导致异常的行添加注释。 进一步分析,抛出异常的代码行是:

NoticeDTO notice = noticeList.get(position);

两件事。首先,您可以通过以下方式修复异常:

NoticeDTO notice = noticeList.get(position-1);

位置-1 的原因是您正在尝试使用 getView 的 "int position" 输入参数。这个位置变量不像数组那样从零开始索引。也就是说,你试图获取第8位的列表项;但是您的 arrayList 大小为 8(索引从 0 到 7)

其次,此代码在任何 if-else 逻辑之外。稍后,如果您决定添加删除功能(从列表中删除项目),如果您在尝试使用 position 之前检查列表是否为空,您就会省去一些麻烦。