0

カスタムカレンダーがあります。月表示には、グリッド表示を使用します。カレンダーの各日に、月の日数と各日のイベント数が表示されます。その目標を達成するために、getView で毎日のイベントを要求します。パフォーマンスを向上させるために、get ビュー内でホルダーを使用します。しかし残念なことに、私のアプリは頻繁にクラッシュし、ある月から次の月に切り替えると非常に遅くなります。ユーザーが翌月のボタンをクリックすると、setGridCellAdapterToDate が呼び出されます。

public void setGridCellAdapterToDate(int month, int year)
{
    adapter = new GridCellAdapter(getActivity().getApplicationContext(), calendarView,R.id.calendar_day_gridcell, month, year);
    _calendar.set(year, month - 1, _calendar.get(Calendar.DAY_OF_MONTH));
    currentMonth.setText(dateFormatter.format(dateTemplate, _calendar.getTime()));
    adapter.notifyDataSetChanged();
    calendarView.setAdapter(adapter);
    calendarView.setSelected(true);

}

カレンダーのパフォーマンスを向上させる方法はありますか?

public class GridCellAdapter extends BaseAdapter implements OnClickListener, OnLongClickListener
{
    private static final String tag = "GridCellAdapter";
    private final Context _context;

    private final List<String> list;
    private static final int DAY_OFFSET = 1;
    private final String[] weekdays = new String[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    private final String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    private final int[] daysOfMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    private final int month, year;
    private int daysInMonth, prevMonthDays;
    private int currentDayOfMonth;
    private int currentWeekDay;
    private Button gridcell;
    private TextView num_events_per_day;
    private final HashMap eventsPerMonthMap;
    SimpleDateFormat("dd-MMM-yyyy");
    public GridCellAdapter(Context context, GridView gv, int textViewResourceId, int month, int year)
        {
            super();
            this._context = context;
            this.list = new ArrayList<String>();
            this.month = month;
            this.year = year;
                                    this.mGv = gv;
            Log.d(tag, "==> Passed in Date FOR Month: " +                  month + " " + "Year: " + year);
            Calendar calendar = Calendar.getInstance();
            setCurrentDayOfMonth(calendar.get(Calendar.DAY_OF_MONTH));
            setCurrentWeekDay(calendar.get(Calendar.DAY_OF_WEEK));
            Log.d(tag, "New Calendar:= " + calendar.getTime().toString());
            Log.d(tag, "CurrentDayOfWeek :" + getCurrentWeekDay());
            Log.d(tag, "CurrentDayOfMonth :" + getCurrentDayOfMonth());

            // Print Month
            printMonth(month, year);

            // Find Number of Events
            eventsPerMonthMap = findNumberOfEventsPerMonth(year, month);
        }
    private String getMonthAsString(int i)
        {
            return months[i];
        }

    private String getWeekDayAsString(int i)
        {
            return weekdays[i];
        }

    private int getNumberOfDaysOfMonth(int i)
        {
            return daysOfMonth[i];
        }

    public String getItem(int position)
        {
            return list.get(position);
        }

    public int getCount()
        {
            return list.size();
        }

    /**
     * Prints Month
     * 
     * @param mm
     * @param yy
     */
    private void printMonth(int mm, int yy)
        {

            Log.d(tag, "==> printMonth: mm: " + mm + " " + "yy: " + yy);
            // The number of days to leave blank at
            // the start of this month.
            int trailingSpaces = 0;
            int leadSpaces = 0;
            int daysInPrevMonth = 0;
            int prevMonth = 0;
            int prevYear = 0;
            int nextMonth = 0;
            int nextYear = 0;

            int currentMonth = mm - 1;
            String currentMonthName = getMonthAsString(currentMonth);
            daysInMonth = getNumberOfDaysOfMonth(currentMonth);

            Log.d(tag, "Current Month: " + " " + currentMonthName + " having " + daysInMonth + " days.");

            // Gregorian Calendar : MINUS 1, set to FIRST OF MONTH
            GregorianCalendar cal = new GregorianCalendar(yy, currentMonth, 1);
            Log.d(tag, "Gregorian Calendar:= " + cal.getTime().toString());
            Calendar caltemp = Calendar.getInstance();
            Integer intMonat = caltemp.get(Calendar.MONTH);
            if (currentMonth == 11)
                {
                    prevMonth = currentMonth - 1;
                    daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
                    nextMonth = 0;
                    prevYear = yy;
                    nextYear = yy + 1;
                    Log.d(tag, "*->PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
                }
            else if (currentMonth == 0)
                {
                    prevMonth = 11;
                    prevYear = yy - 1;
                    nextYear = yy;
                    daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
                    nextMonth = 1;
                    Log.d(tag, "**--> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
                }
            else
                {
                    prevMonth = currentMonth - 1;
                    nextMonth = currentMonth + 1;
                    nextYear = yy;
                    prevYear = yy;
                    daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
                    Log.d(tag, "***---> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
                }

            // Compute how much to leave before before the first day of the
            // month.
            // getDay() returns 0 for Sunday.
            int currentWeekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
            trailingSpaces = currentWeekDay;

            Log.d(tag, "Week Day:" + currentWeekDay + " is " + getWeekDayAsString(currentWeekDay));
            Log.d(tag, "No. Trailing space to Add: " + trailingSpaces);
            Log.d(tag, "No. of Days in Previous Month: " + daysInPrevMonth);

            if (cal.isLeapYear(cal.get(Calendar.YEAR)) && mm == 1)
                {
                    ++daysInMonth;
                }

            // Trailing Month days
            for (int i = 0; i < trailingSpaces; i++)
                {
                    Log.d(tag, "PREV MONTH:= " + prevMonth + " => " + getMonthAsString(prevMonth) + " " + String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i));
                    list.add(String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i) + "-GREY" + "-" + getMonthAsString(prevMonth) + "-" + prevYear);
                }

            // Current Month Days
            for (int i = 1; i <= daysInMonth; i++)
                {
                    Log.d(currentMonthName, String.valueOf(i) + " " + getMonthAsString(currentMonth) + " " + yy);
                    if (i == getCurrentDayOfMonth() && mm  == intMonat+1)
                        {
                            list.add(String.valueOf(i) + "-BLUE" + "-" + getMonthAsString(currentMonth) + "-" + yy);
                        }
                    else
                        {
                            list.add(String.valueOf(i) + "-WHITE" + "-" + getMonthAsString(currentMonth) + "-" + yy);
                        }

                }

            // Leading Month days
            for (int i = 0; i < list.size() % 7; i++)
                {
                    Log.d(tag, "NEXT MONTH:= " + getMonthAsString(nextMonth));
                    list.add(String.valueOf(i + 1) + "-GREY" + "-" + getMonthAsString(nextMonth) + "-" + nextYear);
                }
        }

    /**
     * NOTE: YOU NEED TO IMPLEMENT THIS PART Given the YEAR, MONTH, retrieve
     * ALL entries from a SQLite database for that month. Iterate over the
     * List of All entries, and get the dateCreated, which is converted into
     * day.
     * 
     * @param year
     * @param month
     * @return
     */
    private HashMap findNumberOfEventsPerMonth(int year, int month)
        {
            HashMap map = new HashMap<String, Integer>();
            // DateFormat dateFormatter2 = new DateFormat();
            //                      
            // String day = dateFormatter2.format("dd", dateCreated).toString();
            //
            // if (map.containsKey(day))
            // {
            // Integer val = (Integer) map.get(day) + 1;
            // map.put(day, val);
            // }
            // else
            // {
            // map.put(day, 1);
            // }
            return map;
        }



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


    public View getView(int position, View convertView, ViewGroup parent)
        {
        ViewHolder holder;
        Integer intRowNumber = 5;
            View row = convertView;
            if (row == null)
                {
                    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
                    //convertView = inflater.inflate(R.layout.calendar_day_gridcell,parent,false);
                    holder = new ViewHolder();
                    holder.text = (TextView)row.findViewById(R.id.num_events_per_day);
                    holder.gridcell= (Button)row.findViewById(R.id.calendar_day_gridcell);
                    //holder.EventsofMonth = openCalendar.getEventsOfMonth(getActivity(), caltemp.getTimeInMillis(),strCalendarId);
                    row.setTag(holder);
                } else {
                    holder = (ViewHolder)row.getTag();
                }
            int intHeight = mGv.getHeight();
            intHeight = intHeight/intRowNumber;
            AbsListView.LayoutParams param = new AbsListView.LayoutParams(
                    android.view.ViewGroup.LayoutParams.FILL_PARENT,
                    mGv.getHeight()/intRowNumber);

            //row.setLayoutParams(param);
            row.setLayoutParams(param);
            // Get a reference to the Day gridcell
            //gridcell = (Button) row.findViewById(R.id.calendar_day_gridcell);
            //gridcell.setOnClickListener(new MyOnClickListener(position));  
            holder.gridcell.setOnClickListener(this);  
            holder.gridcell.setOnLongClickListener(this);  

            // ACCOUNT FOR SPACING

            Log.d(tag, "Current Day: " + getCurrentDayOfMonth());
            String[] day_color = list.get(position).split("-");
            String theday = day_color[0];
            String themonth = day_color[2];
            String theyear = day_color[3];
            String selection = "((" + CalendarContract.Events.DTSTART
                    + " >= ?) AND (" + CalendarContract.Events.DTEND + " <= ?) AND (" + CalendarContract.Events.DELETED + " = ?) AND (" + CalendarContract.Events.CALENDAR_ID + " = ?))";

            if ((!eventsPerMonthMap.isEmpty()) && (eventsPerMonthMap != null))
                {
                    if (eventsPerMonthMap.containsKey(theday))
                        {
                            //num_events_per_day = (TextView) row.findViewById(R.id.num_events_per_day);
                            Integer numEvents = (Integer) eventsPerMonthMap.get(theday);
                            //num_events_per_day.setText(numEvents.toString());


                        }
                }

            // Set the Day GridCell


            holder.gridcell.setText(theday);

            holder.gridcell.setTag(theday + "-" + themonth + "-" + theyear);
            Log.d(tag, "Setting GridCell " + theday + "-" + themonth + "-" + theyear);

            if (day_color[1].equals("GREY"))
                {
                    holder.gridcell.setTextColor(Color.LTGRAY);
                }
            if (day_color[1].equals("WHITE"))
                {
                    holder.gridcell.setTextColor(Color.WHITE);
                }
            if (day_color[1].equals("BLUE"))
                {
                    //gridcell.setTextColor(getResources().getColor(R.color.static_text_color));


                holder.gridcell.setTextColor(Color.BLUE);
                DisplayMetrics metrics;
                metrics = getActivity().getApplicationContext().getResources().getDisplayMetrics();
                float Textsize = 0;
                Textsize = holder.gridcell.getTextSize()/metrics.density;
                holder.gridcell.setTextSize(Textsize+4);                                    

                }

                //ermittle die Anzahl der Events an diesem Tag und schreibe sie in num_events_per_day
                Integer intAnzEventsonSelectedDay = 0;
                //num_events_per_day = (TextView) row.findViewById(R.id.num_events_per_day);
                String strCurrentDatum = theday + "-" + month + "-" + year;
                SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

                Date dateObj = null;
                try {
                    dateObj = sdf.parse(strCurrentDatum);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                String temp = dateObj.toString();

                caltemp.setTime(dateObj);
                Cursor curCalendar = openCalendar.getEventsOfDay(getActivity(), caltemp.getTimeInMillis(),strCalendarId);
                curCalendar.moveToFirst();
                intAnzEventsonSelectedDay = curCalendar.getCount();
                if (intAnzEventsonSelectedDay > 4){
                    holder.text.setTextColor(Color.RED);
                } else{
                    //
                }

                holder.text.setText(intAnzEventsonSelectedDay.toString());
             return row;
        }
4

1 に答える 1

0

パフォーマンスの問題の一部は、実際には、1 か月に到達するためにどれだけの作業を行っているかにあると思います。私が言える最善のことは、最初に using から using に切り替えることCalendarですMonthDisplayHelper。基本的に単一の月をレイアウトするのに役立つ組み込みの Android クラスです。これも優れた形式で、毎週 int 配列に分割されています。Calendar現在の日の情報を手元に置いておくための優れた方法として、まだあります。さらに重要なことは、1 日からすべてのイベントをロードする代わりに、最初に月をロードしてから、AsyncTaskUI スレッドから離れた後に個々のイベントをロードします。1 か月に数回のイベントがあると想像してください。1 か月のビューだけをユーザーに表示する前に、大量の計算が必要になります。これの良い例は、Google のデフォルト カレンダーです。十分な数のイベントがある場合は、月のビューが表示された後にロードが開始されることに気付くでしょう。使い勝手の面でも優れた機能です。

于 2013-10-27T18:47:40.090 に答える