중첩 가중치가 성능에 나쁜 이유는 무엇입니까? 대안?


160

layout_weight속성을 사용하여 여러보기 사이의 비율을 만드는 몇 가지 레이아웃 파일 을 작성했습니다.

언젠가 중첩 가중치에 대한 보푸라기 경고가 표시되기 시작합니다.

따라서 중첩 가중치가 성능에 나쁜 이유와 다른 화면 크기에 사용할 수 있고 많은 치수 dpi 값을 지정할 필요가없는 뷰 크기간에 일정한 비율을 만드는보다 효율적인 방법이 있는지 궁금합니다. 여러 레이아웃 파일을 통해 (다른 화면 크기의 경우).

감사합니다!


2
레이아웃 최적화를위한 멋진 포스트 developer.android.com/training/improving-layouts/...
무하마드 바바에게

답변:


140

중첩 가중치는 다음과 같은 이유로 성능이 좋지 않습니다.

레이아웃 가중치는 위젯을 두 번 측정해야합니다. 가중치가 0이 아닌 LinearLayout이 0이 아닌 가중치가있는 다른 LinearLayout 내에 중첩되면 측정 수가 기하 급수적으로 증가합니다.

RelativeLayout 을 사용하고 특정 dpi 값을 사용하지 않고 다른 뷰의 위치에 따라 뷰를 조정 하는 것이 좋습니다 .


87
알아 두어야 할 것은 메시지의 목적입니다. 나는 관련 지수가 작은 경우 지수에 미치는 영향은 아직 작다 있습니다. 하는 중첩의 작은 깊이 들어 하지 CPU를 사용이 일주일 내내 애지중지 당신이하는 주력을 가진 만 일요일에 산책을 위해 밖으로 이끌어처럼 할 필요합니다. 그럼에도 불구하고, 중첩 깊이가 깊을 때는 잘 파악해야합니다.
Carl

14
RelativeLayout은 모든 하위 레이아웃이 올바르게 배치되도록 두 번 측정해야하므로 레이아웃 가중치가있는 LinearLayout을 RelativeLayout으로 변경하면 성능이 향상되지 않을 수 있습니다.
Piasy

상대적 레이아웃이 항상 작동하는 것은 아닙니다. 비례 위젯을 구성해야하는 경우
Abdurakhmon

67

업데이트 : 우리가 알고있는 것처럼 퍼센트 지원 라이브러리는 API 레벨 26에서 더 이상 사용되지 않습니다. ConstraintLayout동일한 플랫 XML 구조를 얻는 새로운 방법입니다.

업데이트 된 Github 프로젝트

업데이트 된 샘플 :

<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/fifty_thirty"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff8800"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        android:textSize="25sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffff5566"
        android:gravity="center"
        android:text="@string/fifty_fifty_text"
        android:textColor="@android:color/white"
        android:textSize="25sp"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toRightOf="@id/fifty_thirty"
        app:layout_constraintTop_toBottomOf="@id/fifty_thirty"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

</android.support.constraint.ConstraintLayout>

업데이트 : 좋은 소식 안드로이드 퍼센트 지원 라이브러리는 성능 문제와 중첩 된 지저분한 가중치를 해결합니다.LinearLayout

compile 'com.android.support:percent:23.0.0'

여기 데모

이 간단한 레이아웃을 고려하여 동일하게 설명하십시오.

지원 비율 libray 데모

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/fifty_huntv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ff7acfff"
        android:text="20% - 50%"
        android:textColor="@android:color/white"
        app:layout_heightPercent="20%"
        app:layout_widthPercent="50%" />
    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_toRightOf="@id/fifty_huntv"
        android:background="#ffff5566"
        android:text="80%-50%"
        app:layout_heightPercent="80%"
        app:layout_widthPercent="50%"
        />

</android.support.percent.PercentRelativeLayout>

가중치 LinearLayout와 중첩 된 성능 저하를 피했습니다 .


@dan 네, 가중치가있는 중첩 선형 레이아웃이 있다고 가정합니다.
nitesh

3
"이 클래스는 API 레벨 26.0.0-beta1에서 더 이상 사용되지 않습니다. 대신 ConstraintLayout 및 관련 레이아웃 사용을 고려하십시오." developer.android.com/reference/android/support/percent/…
saiyancoder

7
ConstraintLayout을 좋아하지 않습니다. 그것은 나를 위해 직관적으로 행동하지 않습니다
Carson Holzheimer

8
ConstraintLayout이 너무 어려워요
BertKing

1
autolayout 제약 조건 에 대해 사과가 제공 한 설명 이 더 명확하고 논리가 동일하므로 도움이 될 수 있습니다. 불행히도 나는 droid의 ConstraintLayout이 iOS의 AutoLayout보다 사용하기에 더 무겁고
자세하다는 것을 알았습니다.

46

나는 (그리고 아마 이것에 대해 화를 낼 것이다) 생각하지만, 내 전화는 대부분의 사람들의 가정용 PC와 경쟁 할 수있는 쿼드 코어 프로세서를 가지고 있다고 생각합니다.

또한 이런 종류의 하드웨어 기능은 전화의 미래라고 생각합니다.

그래서 결론을 내 렸습니다. 네가 중첩되지 않는 한 (MHO에서 레이아웃은 4 레벨 이상이어야하며, 잘못하는 경우) 휴대 전화는 덜 신경 쓸 수 있습니다. 무게를 갖는 것에 대해.

성능에 훨씬 더 많은 영향을 미치고 프로세서가 추가 수학을하는 것에 대해 걱정할 수있는 많은 일들이 있습니다.

(저는 약간 유머러스 하므로이 게시물에서 너무 심각하게 생각하지 않아야합니다. 다른 것보다 먼저 최적화 해야하는 다른 것들이 있으며 2-3 레벨의 깊은 무게에 대해 걱정하는 것이 도움이되지 않는다는 생각 당신의 건강)


2
1 년에 평균 미국 가정용 냉장고와 동일한 양의 에너지를 사용하는 평균 아이폰 사용 (웹 서비스 /이를 지원하는 사이트 포함)을 들었습니다. 따라서 이러한 종류의 환경 영향을 고려해야하는 것은 개발자의 책임입니다. 분명히 시간, 비용, 성능, 안정성 등의 균형 잡힌 행동이며 일반적으로 귀하의 관점에 동의합니다. 그러나 우리는 이러한 종류의 영향도 고려해야한다고 생각합니다. 분명히 유지 관리 / 확장 성도 여기에옵니다. 어쨌든-포인트와 감사합니다.
MemeDeveloper 2016 년

문제의 특정 요점은 웹이 아닌 장치에서의 처리에 관한 것이지만 OP의 세부 사항보다 개발자의 우선 순위에 대한 일반적인 요점으로 내 의견을 의미합니다.
MemeDeveloper 2016 년

11

중첩 된 가중치가 나쁜 주된 이유는 레이아웃에 가중치가있는 자식이있을 때 레이아웃을 두 번 측정해야하기 때문입니다 (보풀이 경고에 언급되어 있다고 생각합니다). 즉, 가중 레이아웃도 포함하는 가중 레이아웃은 4 번 측정해야하며 추가하는 각 '레이어'레이어는 2의 거듭 제곱으로 측정 값을 증가시킵니다.

ICS (API 레벨 14) GridLayout에 추가되어 이전에 가중치가 필요한 많은 레이아웃에 대해 단순하고 '평평한'솔루션을 허용합니다. 이전 버전의 Android를 위해 개발하는 경우 가중치를 제거하는 데 약간의 시간이 걸리지 만 RelativeLayout해당 택시에 레이아웃을 최대한 많이 사용하면 일반적으로 중첩 된 가중치가 많이 제거됩니다.


9
GridLayout 또는로 동일한 결과를 얻을 수 있다고 생각하지 않습니다 RelativeLayout. 예 GridLayout: "GridLayout은 무게로 정의 된 무게의 원리에 대한 지원을 제공하지 않습니다. 따라서 일반적으로 여러 구성 요소간에 여분의 공간을 분배하도록 GridLayout을 구성 할 수 없습니다."
Timmmm

API 21부터 가중치 개념이 GridLayout에 추가되었습니다. 구형 Android 장치를 지원하기 위해 v7 지원 라이브러리에서 GridLayout을 사용할 수 있습니다. android.support.v7.widget.GridLayout
Эвансгелист Evansgelist

2

가중치가있는 중첩 된 LinearLayouts를 피하는 쉬운 솔루션이 있습니다. weightSum과 함께 Tablelayout을 사용하고 weightSum과 함께 중첩 된 LinearLayout을 사용하십시오-Tablelayout은 LinearLayout (동향, weightSum, layout_weight 등)과 동일한 속성을 가지며 메시지를 표시하지 않습니다- "중첩 된 가중치 성능이 나쁘다 "

예:

 <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="1">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.8"/>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.2"
            android:orientation="horizontal"
            android:weightSum="1">


            <ImageView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.4"/>

            <TextView
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="0.6"/>


            </LinearLayout>

    </TableLayout>

1

유일한 대안은 onResume이라는 함수를 만들고 모든 크기와 위치를 설정하는 것입니다. 어쨌든, 무게로만 크기를 설정할 수 있지만 패딩 (레이아웃이 더 복잡 해짐), textSize (어떻게 보정 할 수는 없음), 줄 수와 같은 것을 제외하고는 설정할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.