GridAdapter数组超出范围?

时间:2011-12-28 20:41:07

标签: android

我在使用GridAdapter for Andorid gridview时出现问题。错误是“12-28 21:35:44.893:E / AndroidRuntime(370):java.lang.RuntimeException:无法启动活动ComponentInfo {btn.grid / btn.grid.ButtonGridActivity}:java.lang.ArrayIndexOutOfBoundsException “

并且适配器是

 package btn.grid;



import android.content.Context;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

class MonthAdapter extends BaseAdapter {
        private GregorianCalendar mCalendar;
        private Calendar mCalendarToday;
        private Context mContext;
        private DisplayMetrics mDisplayMetrics;
        private List<String> mItems;
        private int mMonth;
        private int mYear;
        private int mDaysShown;
        private int mDaysLastMonth;
        private int mDaysNextMonth;
        private int mTitleHeight, mDayHeight;
        private final String[] mDays = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
        private final int[] mDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        public MonthAdapter(Context c, int month, int year ) {
                mContext = c;
                mMonth = month;
                mYear = year;
                mCalendar = new GregorianCalendar(mYear, mMonth, 1);
                mCalendarToday = Calendar.getInstance();

                populateMonth();
        }

        private void populateMonth() {
                mItems = new ArrayList<String>();              
                for (String day : mDays) {
                        mItems.add(day);
                        mDaysShown++;
                }

                int firstDay = getDay(mCalendar.get(Calendar.DAY_OF_WEEK));
                int prevDay;
                if (mMonth == 0)
                        prevDay = daysInMonth(11) - firstDay + 1;
                else
                        prevDay = daysInMonth(mMonth - 1) - firstDay + 1;
                for (int i = 0; i < firstDay; i++) {
                        mItems.add(String.valueOf(prevDay + i));
                        mDaysLastMonth++;
                        mDaysShown++;
                }

                int daysInMonth = daysInMonth(mMonth); 
                for (int i = 1; i <= daysInMonth; i++) {
                        mItems.add(String.valueOf(i));
                        mDaysShown++;
                }

                mDaysNextMonth = 1;
                while (mDaysShown % 7 != 0) {
                        mItems.add(String.valueOf(mDaysNextMonth));
                        mDaysShown++;
                        mDaysNextMonth++;
                }

                mTitleHeight = 30;
                int rows = (mDaysShown / 7);
                mDayHeight = (mDisplayMetrics.heightPixels - mTitleHeight
                                - (rows * 3) - getBarHeight())/ (rows - 1);
        }

        private int daysInMonth(int month) {
                int daysInMonth = mDaysInMonth[month];
                if (month == 1 && mCalendar.isLeapYear(mYear))
                        daysInMonth++;
                return daysInMonth;
        }

        private int getBarHeight() {
                switch (mDisplayMetrics.densityDpi) {
                case DisplayMetrics.DENSITY_HIGH:
                        return 48;
                case DisplayMetrics.DENSITY_MEDIUM:
                        return 32;
                case DisplayMetrics.DENSITY_LOW:
                        return 24;
                default:
                        return 48;
                }
        }

        /**
         * For week starting Monday
         * @param day from Calendar.DAY_OF_WEEK
         * @return day week starting Monday
         */
        private int getDay(int day) {
                switch (day) {
                case Calendar.MONDAY:
                        return 0;
                case Calendar.TUESDAY:
                        return 1;
                case Calendar.WEDNESDAY:
                        return 2;
                case Calendar.THURSDAY:
                        return 3;
                case Calendar.FRIDAY:
                        return 4;
                case Calendar.SATURDAY:
                        return 5;
                case Calendar.SUNDAY:
                        return 6;
                default:
                        return 0;
                }
        }

        private boolean isToday(int day, int month, int year) {
                if (mCalendarToday.get(Calendar.MONTH) == month
                                && mCalendarToday.get(Calendar.YEAR) == year
                                && mCalendarToday.get(Calendar.DAY_OF_MONTH) == day) {
                        return true;
                }
                return false;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                final TextView view = new TextView(mContext);
                view.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
                view.setText(mItems.get(position));
                view.setBackgroundColor(Color.rgb(244, 244, 244));
                view.setTextColor(Color.BLACK);

                if (position <= 6) {
                        // names
                        view.setBackgroundColor(Color.argb(100, 10, 80, 255));
                        view.setHeight(mTitleHeight);
                } else if (position <= mDaysLastMonth + 6) {
                        // previous month
                        view.setBackgroundColor(Color.rgb(234, 234, 245));
                        view.setHeight(mDayHeight);
                } else if (position <= mDaysShown - mDaysNextMonth  ) {
                        // current month
                        view.setHeight(mDayHeight);
                        int day = position - (mDaysLastMonth + 6);
                        if (isToday(day, mMonth, mYear)) {
                                view.setTextColor(Color.RED);
                        }
                        // check db and colour for shifts
                        // ...
                } else {
                        // next month
                        view.setHeight(mDayHeight);
                        view.setBackgroundColor(Color.rgb(234, 234, 245));
                }
                return view;
        }

        @Override
        public int getCount() {
                return mItems.size();
        }

        @Override
        public Object getItem(int position) {
                return mItems.get(position);
        }

        @Override
        public long getItemId(int position) {
                return position;
        }
}

* logcat的

    12-28 21:35:44.873: W/dalvikvm(370): threadid=1: thread exiting with uncaught exception (group=0x40015560)
12-28 21:35:44.893: E/AndroidRuntime(370): FATAL EXCEPTION: main
12-28 21:35:44.893: E/AndroidRuntime(370): java.lang.RuntimeException: Unable to start activity ComponentInfo{btn.grid/btn.grid.ButtonGridActivity}: java.lang.ArrayIndexOutOfBoundsException
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.os.Looper.loop(Looper.java:123)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.main(ActivityThread.java:3683)
12-28 21:35:44.893: E/AndroidRuntime(370):  at java.lang.reflect.Method.invokeNative(Native Method)
12-28 21:35:44.893: E/AndroidRuntime(370):  at java.lang.reflect.Method.invoke(Method.java:507)
12-28 21:35:44.893: E/AndroidRuntime(370):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-28 21:35:44.893: E/AndroidRuntime(370):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-28 21:35:44.893: E/AndroidRuntime(370):  at dalvik.system.NativeStart.main(Native Method)
12-28 21:35:44.893: E/AndroidRuntime(370): Caused by: java.lang.ArrayIndexOutOfBoundsException
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.daysInMonth(MonthAdapter.java:82)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.populateMonth(MonthAdapter.java:62)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.<init>(MonthAdapter.java:40)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.ButtonGridActivity.onCreate(ButtonGridActivity.java:16)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
12-28 21:35:44.893: E/AndroidRuntime(370):  ... 11 more

1 个答案:

答案 0 :(得分:0)

从你添加的stracktrace中,你可以看到ArrayIndexOutOfBoundsException来自第82行。这意味着以下结果是例外:

int daysInMonth = mDaysInMonth[month];

换句话说,mDaysInMonth中的查找使用了无效索引;可能month > 11虽然也可能是负面的。

month是您传递给的参数:

private int daysInMonth(int month)

对此方法的调用导致异常来自第62行:

int daysInMonth = daysInMonth(mMonth);

这意味着mMonth是最终数组查找的无效索引。由于mMonth是在适配器的构造函数中初始化的,因此您最好在创建MonthAdapter时检查传递它的值。

public MonthAdapter(Context c, int month, int year ) {
    (...)
    mMonth = month;
    (...)
}