Android CalendarView замедляет макет

Это сводит меня с ума. У меня есть фрагмент в моем приложении для Android, который выложен с использованием RelativeLayout. Проблема в том, что по какой-то причине для рендеринга требуется много времени, около 5 секунд, чтобы загрузить около 4 элементов на экран.

Одним из элементов является CalendarView, и когда я удаляю его, он возвращается к правильной скорости (т.е. мгновенной). Я предполагаю, что проблема связана с тем, как я прошу Android выложить это, не должно иметь особого смысла, неэффективно или что-то в этом роде.

Вот файл XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">

<TextView
     android:id="@+id/title"
     android:layout_width="0dp"
     android:layout_height="wrap_content"
     android:textStyle="bold"
     android:text="TODAY"
     android:textAppearance="?android:attr/textAppearanceLarge" 

     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true"
     android:layout_toLeftOf="@+id/time" />

<TextView
     android:id="@id/time"
     android:gravity="right"
     android:textStyle="bold"
     android:layout_width="100dp"
     android:layout_height="wrap_content"
     android:text="11:32"
     android:textAppearance="?android:attr/textAppearanceLarge"

     android:layout_alignParentRight="true" />

<TextView
    android:id="@+id/date_info"
    android:layout_margin="20dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Wednesday, 15th August 2012"
    android:textAppearance="?android:attr/textAppearanceMedium"

    android:layout_below="@id/title"
    android:layout_alignParentLeft="true" />

<CalendarView        
    android:id="@+id/calendar_view"
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:background="@drawable/white_back_black_border"

    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true" />
</RelativeLayout>

Я пробовал множество разных вариантов макета, но удаление календаря, кажется, единственное, что имеет значение.

Мы будем очень признательны за любые идеи. Спасибо


person carlmango11    schedule 11.12.2012    source источник
comment
Вы делаете что-нибудь в коде с календарем? Например, установка дат и т. д.   -  person Warpzit    schedule 11.12.2012
comment
Даже когда я закомментирую весь код, который имеет дело с этим, он все равно будет медленным. Но как только я удаляю его из файла макета, он исправляется. Я считаю, что это должно быть связано с RelativeLayout, потому что, если я правильно помню, когда я использовал LinearLayout, он работал нормально...   -  person carlmango11    schedule 11.12.2012
comment
Хех обязательно так. Это просто не имеет никакого смысла. Я предполагаю, что это что-то другое.   -  person Warpzit    schedule 11.12.2012
comment
Я знаю, это странно. Просто чтобы убедиться, что я переключил его на LinearLayout. Работает нормально, загружается моментально. Я полагаю, что на данный момент я могу просто жить с LinearLayout, но это все еще меня раздражает.   -  person carlmango11    schedule 12.12.2012
comment
У этого парня была та же проблема: Как остановить сборку мусора в Android 2.3.3   -  person Salvatorelab    schedule 05.08.2013


Ответы (6)


У меня тоже была эта проблема, как с относительными макетами, так и с линейными макетами. Кажется, это не связано с макетом.

Вот пример, чтобы увидеть ошибку, просто с простым макетом, вообще без кода:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".FechaHoraActivity" >

    <TimePicker
        android:id="@+id/timePicker1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp" />

    <CalendarView
        android:id="@+id/calendarView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

А теперь просто измените линейную высоту макета на:

android:layout_height="match_parent"

С этим изменением проблема исчезла, по крайней мере, в моем Samsung Galaxy Tab 2.

Так что кажется, что это больше связано с «космосом», но я до сих пор не уверен, почему возникает эта проблема. И я не нашел никаких других интересных результатов в поиске google "calendarview slow"...

ИЗМЕНИТЬ Посмотрим, сможем ли мы найти ответ с небольшой наградой

person Salvatorelab    schedule 22.07.2013
comment
CalendarView layout_height также должно быть match_parent. - person faizal; 08.12.2014

Мне требуется несколько часов, чтобы найти ответ, но я не понимаю, почему. Вот что-то странное, может это поможет вам найти ответ.

потребление ресурсов процессора при медленной работе CalendarView введите здесь описание изображения

У getView в WeekAdapter есть родительский параметр, который никогда не использовался.

   public View getView(int position, View convertView, ViewGroup parent) {
       WeekView weekView = null;
        if (convertView != null) {
            weekView = (WeekView) convertView;
        } else {
            weekView = new WeekView(mContext);
            android.widget.AbsListView.LayoutParams params =
                new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
                        LayoutParams.WRAP_CONTENT);
            weekView.setLayoutParams(params);
            weekView.setClickable(true);
            weekView.setOnTouchListener(this);
        }

        int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
                Calendar.DAY_OF_WEEK) : -1;
        weekView.init(position, selectedWeekDay, mFocusedMonth);

        return weekView;
    }

С нетерпением жду ответа.

person Everett    schedule 05.08.2013
comment
Как вы оцениваете потребление процессора? Это в Эклипсе? - person Nick; 05.08.2013
comment
Посмотрите на это, оно было интегрировано в ДДМС. - person Everett; 06.08.2013
comment
интересно, теперь мы ближе. Я использовал ваш подход для сравнения двух макетов (см. мой ответ). Первый (тот, который зависает): wrap_content И тот, что работает нормально: match_parent Как видите, разница начинается с номера 4 с помощьюgetView. Внутри этого мы видим: внутриgetView Да, WeekAdapter.getView явно проблема, вы правы, теперь мы должны найти, почему. - person Salvatorelab; 06.08.2013
comment
мы до сих пор не знаем, почему это происходит, но вы провели отличное расследование, и я не хочу оставлять награду без победителя, так что наслаждайтесь =) - person Salvatorelab; 11.08.2013
comment
Спасибо TheBronx, эта тайна все еще открыта, любой, кто поймет это, получит награду. - person Everett; 12.08.2013
comment
получил ту же проблему. SDK 4.2 - person drdrej; 23.04.2014

Кажется, что CalendarView непосредственно внутри RelativeLayout действительно не работает так хорошо. Следующее решение с использованием FrameLayout загружается в эмуляторе намного быстрее:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp" >

    <TextView
        android:id="@+id/title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/time"
        android:text="TODAY"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

    <TextView
        android:id="@id/time"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:gravity="right"
        android:text="11:32"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/date_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/title"
        android:layout_margin="20dp"
        android:text="Wednesday, 15th August 2012"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <FrameLayout
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true" >

        <CalendarView
            android:id="@+id/calendar_view"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:background="@drawable/white_back_black_border" />
    </FrameLayout>
</RelativeLayout>
person Mirco Widmer    schedule 05.08.2013
comment
Не FrameLayout решает проблему, а фиксированная высота. Кажется, андроиду нужна высота, чтобы плавно строить недели... - person Salvatorelab; 06.08.2013
comment
Я проверил это снова и использовал RelativeLayout вместо FrameLayout, и для загрузки приложения потребовалось + 10 секунд. Я изменил окружающий макет календаря обратно на FrameLayout, и он сразу же снова загрузился. Поэтому я склонен сказать, что это определенно связано с тем, как RelativeLayout обрабатывает CalendarViews. - person Mirco Widmer; 06.08.2013
comment
Да, правда, не надо, почему относительный макет отстой при рендеринге кал. используйте linearlayout... Спасибо братан за помощь +1 с моей стороны - person Naruto; 27.04.2014

Обнаружено, что для виджета CalendarView высота должна быть установлена ​​​​на match_parent, тогда вы можете поместить его в любой макет. Например, относительно с высотой 200. Это отлично работает на эмуляторе 4.0.3 и на Samsung Galaxy Tab с 4.2.2.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true" >

        <CalendarView
            android:id="@+id/cv_dialog_filter_date"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/relativeLayout2"
        android:layout_centerHorizontal="true"
        android:text="05.12.2013" />

</RelativeLayout>
person MainActivity    schedule 05.12.2013

Помещение CalendarView в FrameLayout решит проблему. Вот пример кода XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cc00b1cc">

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="102dp"
        android:layout_alignParentBottom="true">

        <CalendarView
            android:layout_width="425dp"
            android:layout_height="374dp"
            android:id="@+id/calendarView"
            android:layout_gravity="left|top" />
    </FrameLayout>
</RelativeLayout>
person Malek Boubakri    schedule 12.04.2015

Приведенные выше ответы были правильными, но до сих пор не разгадали одну загадку.

То есть, когда я хочу включить представление календаря внутри макета с другим макетом. Он просто исчезает или я вижу только буквы недели. Я попробовал указанный выше родительский матч и все такое, и все же я не смог его решить.

Если кто-то борется, как я Вот ответ.

   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">


<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <CalendarView
        android:id="@+id/calendarService"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/linearLayout"></CalendarView>

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical"> 


     ///Your views 


     />
person EngineSense    schedule 20.09.2015