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>

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

Любые идеи были бы очень признательны. Благодаря

Ответы

Ответ 1

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

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

<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"...

РЕДАКТИРОВАТЬ. Посмотрим, сможем ли мы найти ответ с небольшой наградой

Ответ 2

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

потребление процессора, когда CalendarView slow enter image description here

В 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;
    }

Ожидаем ответа.

Ответ 3

Кажется, что 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>

Ответ 4

Включение 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>

Ответ 5

Установлено, что для виджета 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>

Ответ 6

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

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

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

   <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 


     />