Подтвердить что ты не робот

Почему 0dp считается улучшением производительности?

В конце этого вопроса был заполнен ответ , который объединяет замечания и решения.

Вопрос

Я искал, но не нашел ничего, что действительно объясняет, почему Android Lint, а также некоторые подсказки Eclipse предлагают заменить некоторые значения layout_height и layout_width на 0dp.

Например, у меня есть ListView, который предлагается изменить

До

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
</ListView>

После

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
</ListView>

Аналогично, он предложил изменения в элементе ListView. Все они выглядят одинаково до и после изменений, но мне интересно понять, почему это ускорители производительности.

У кого-нибудь есть объяснение почему? Если это помогает, вот общий макет с ListView.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ImageView
        android:id="@+id/logo_splash"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ImageView>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:background="@color/background"
        android:layout_below="@id/logo_splash">

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
        </ListView>

        <TextView
            android:id="@android:id/empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/no_upcoming" />

    </LinearLayout>        
</RelativeLayout>

Ответ

Я отвечаю здесь, потому что это действительно комбинация ответов и ссылок, приведенных ниже. Если я что-то не так, дайте мне знать.

Из Каков трюк с 0dip layout_height или layouth_width?

Существует 3 общих атрибута макета, которые работают с шириной и высотой

  • android:layout_height
  • android:layout_width
  • android:layout_weight

Когда a LinearLayout является вертикальным, тогда layout_weight будет влиять на высоту дочернего элемента View (ListView). Установка layout_height в 0dp приведет к игнорированию этого атрибута.

Пример

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </ListView>
</LinearLayout>

Когда a LinearLayout является горизонтальным, тогда layout_weight будет влиять на ширину дочернего элемента View (ListView). Установка layout_width в 0dp приведет к игнорированию этого атрибута.

Пример

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <ListView
        android:id="@android:id/list"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">
    </ListView>
</LinearLayout>

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

Кроме того, это предотвращает путаницу в отношении того, как выглядит макет при использовании комбинации трех атрибутов. Это подчеркивается разработчиком @android в ответе ниже.

Кроме того, Android Lint и Eclipse говорят, что используют 0dip. Из этого ниже ответа вы можете использовать 0dip, 0dp, 0px и т.д., Так как нулевой размер одинаковый в любом из блоков.

Избегайте wrap_content в ListView

Из Layout_width в ListView

Если вы когда-нибудь задавались вопросом, почему getView(...) вызывается так много раз, как я, он оказывается связанным с wrap_content.

Использование wrap_content, как я использовал выше, приведет к измерению всего дочернего View, что приведет к дальнейшему времени процессора. Это измерение вызовет вызов getView(...). Теперь я проверил это, и количество раз, когда вызывается getView(...), резко сокращается.

Когда я использовал wrap_content на двух ListView s, getView(...) был вызван 3 раза для каждой строки на одном ListView и 4 раза для каждой строки на другом.

Изменение этого параметра до рекомендуемого 0dp, getView(...) вызывалось только один раз для каждой строки. Это довольно улучшилось, но больше связано с тем, чтобы избежать wrap_content на ListView, чем на 0dp.

Однако из-за этого предложение 0dp существенно улучшает производительность.

4b9b3361

Ответ 1

Прежде всего, у вас есть это,

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
</ListView>

Никогда не используйте высоту ListView как wrap_content, которая приведет к проблемам. Here является причиной этого и this answer.

Далее,

Я искал вокруг, но не нашел ничего, что действительно объясняет, почему Android Lint, а также некоторые подсказки Eclipse предлагают заменить некоторые layout_height и layout_width с 0dp.

Это потому, что вы используете layout_weight = "1", что означает, что ListView имеет высоту, максимально доступную для нее. Таким образом, в этом случае нет необходимости использовать layout_height = "wrap_content", просто измените его на android:layout_height="0dp", а высота ListView будет управляться layout_weight = "1".

Ответ 2

Итак, когда android: layout_weight используется для просмотра X и LinearLayout является горизонтальным, тогда X android: layout_width просто игнорируется.

Аналогично, когда android: layout_weight используется в View X, а LinearLayout - вертикально, тогда X android: layout_height игнорируется.

Это на самом деле означает, что вы можете поместить что-нибудь в те игнорируемые поля: 0dp или fill_parent или wrap_content. Это не имеет значения. Но рекомендуется использовать 0dp, поэтому View не делает дополнительного вычисления их высоты или ширины (которые затем игнорируются). Этот небольшой трюк просто экономит циклы процессора.

from:

Каков трюк с 0dip layout_height или layouth_width?

Ответ 3

насколько я знаю, существует разница между использованием 0dp (или 0px btw, это то же самое, поскольку 0 равно 0, независимо от того, что здесь находится), а wrap_content или fill_parent (или match_parent, это то же самое).

это зависит от веса, который вы используете. если вы используете только вес 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="match_parent" android:orientation="vertical">

  <TextView android:id="@+id/textView1" android:layout_width="match_parent"
    android:layout_height="0px" android:text="1" android:background="#ffff0000"
    android:layout_weight="1" android:gravity="center"
    android:textColor="#ffffffff" android:textSize="20sp" />

  <TextView android:id="@+id/textView2" android:layout_width="match_parent"
    android:layout_height="0px" android:text="2" android:background="#ff00ff00"
    android:layout_weight="2" android:gravity="center"
    android:textColor="#ffffffff" android:textSize="20sp" />

  <TextView android:id="@+id/textView3" android:layout_width="match_parent"
    android:layout_height="0px" android:text="3" android:background="#ff0000ff"
    android:layout_weight="3" android:gravity="center"
    android:textColor="#ffffffff" android:textSize="20sp" />

</LinearLayout>

а затем попытайтесь заменить 0px на match_parent. вы увидите, что результат совсем другой.

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

Ответ 4

LinearLayout измеряет все дети в соответствии с значениями layout_width/layout_height, затем делит оставшееся пространство (которое может быть отрицательным) в соответствии со значениями layout_weight.

0dp более эффективен, чем wrap_content в этом случае, потому что более эффективно просто использовать ноль для исходной высоты, а затем разделить родительскую полную высоту на основе веса, чем сначала измерить ребенка, а затем разделить остаток основанный на весе.

Таким образом, эффективность исходит не от измерения ребенка. 0dp должен быть точно таким же эффективным (и получить точно такой же результат) как match_parent, или 42px, или любое другое фиксированное число.

Ответ 5

Внимание! Использование android: layout_height = "0dp"

Я обнаружил, что в ListView (с рекомендуемой View recycling с использованием convertView, см., например, http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/), set android: layout_height = "0dp" для строки TextView может привести к усечению текста для многострочного текстового содержимого.

Всякий раз, когда объект TextView, который ранее использовался для отображения текста, который был установлен в одной строке, перерабатывается для отображения более длинного текста, который требует более одной строки, этот текст усекается в одну строку.

Проблема устранена с помощью android: layout_height = "wrap_content"