Tại sao trọng lượng lồng nhau xấu cho hiệu suất? Lựa chọn thay thế?


160

Tôi đã viết một vài tệp bố cục trong đó tôi đã sử dụng layout_weightthuộc tính để tạo tỷ lệ giữa các chế độ xem khác nhau.

Tại một số điểm, tôi bắt đầu nhận được cảnh báo lint về trọng lượng lồng nhau.

Vì vậy, tôi tự hỏi tại sao trọng lượng lồng nhau không tốt cho hiệu suất và liệu có cách nào hiệu quả hơn để tạo tỷ lệ không đổi giữa các kích thước chế độ xem có thể được sử dụng cho các kích thước màn hình khác nhau và không cần chỉ định nhiều giá trị dpi kích thước thông qua một số tập tin bố trí (đối với kích thước màn hình khác nhau, ý tôi là).

Cảm ơn bạn!


2
Một bài tuyệt vời cho Layout Tối ưu hóa developer.android.com/training/improving-layouts/...
Muhammad Babar

Câu trả lời:


140

Trọng lượng lồng nhau có hại cho hiệu suất vì:

Trọng lượng bố trí yêu cầu một widget phải được đo hai lần. Khi một linearLayout có trọng số khác không được lồng bên trong một linearLayout khác với các trọng số khác không, thì số lượng phép đo tăng theo cấp số nhân.

Tốt hơn là sử dụng RelativeLayout và điều chỉnh chế độ xem của bạn theo vị trí của các chế độ xem khác mà không sử dụng các giá trị dpi cụ thể.


87
Điều tốt để nhận thức được, mà tôi cho là mục đích của thông điệp. Tôi sẽ lưu ý rằng một tác động theo cấp số nhân vẫn còn rất nhỏ nếu số mũ liên quan là nhỏ. Đối với độ sâu nhỏ của việc lồng nhau, không sử dụng CPU cần thiết để làm điều này giống như có một công việc mà bạn nuông chiều cả tuần và chỉ dẫn ra ngoài đi dạo vào Chủ nhật. Tuy nhiên, đối với độ sâu lớn của việc làm tổ, đó là một điểm rất tốt.
Carl

14
RelativeLayout cũng cần đo hai lần để đảm bảo tất cả bố cục con của nó đúng cách, do đó, thay đổi linearLayout với trọng số bố cục thành RelativeLayout có thể không cải thiện hiệu suất.
Piasy

Bố trí tương đối không phải lúc nào cũng hoạt động. Trong trường hợp bạn cần xây dựng các vật dụng theo tỷ lệ
Abdurakhmon

67

Cập nhật: Như chúng ta đã biết thư viện hỗ trợ phần trăm không được dùng từ cấp API 26. ConstraintLayoutlà cách mới để đạt được cấu trúc xml phẳng tương tự.

Dự án Github cập nhật

Mẫu cập nhật:

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

Cập nhật: Thư viện hỗ trợ phần trăm tin tức tuyệt vời của Android giải quyết vấn đề về hiệu suất của chúng tôi và lồng lộn xộnLinearLayout

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

Demo TẠI ĐÂY

Hãy xem xét cách bố trí đơn giản này để chứng minh tương tự.

phần trăm hỗ trợ demo 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>

Tránh hiệu suất xuống cấp lồng nhau LinearLayoutvới trọng lượng. Thực sự tuyệt vời !!!.


@dan Có xem xét chúng tôi đã bố trí tuyến tính lồng nhau với trọng số.
nitesh

3
"Lớp này không được dùng ở cấp độ API 26.0.0-beta1. Hãy xem xét sử dụng ConstraintLayout và các bố cục liên quan thay thế." developer.android.com/reference/android/support/percent/ từ
saiyancoder

7
Tôi không thích ConstraintLayout. Nó không hành xử theo trực giác đối với tôi
Carson Holzheimer

8
ConstraintLayout rất khó đối với tôi
BertKing

1
có lẽ những lời giải thích được đưa ra bởi apple về các ràng buộc tự động thanh toán là rõ ràng hơn và vì logic là như nhau, nó có thể giúp ích. Thật không may, tôi thấy ConstraintLayout của droid sử dụng nhiều hơn / dài hơn so với AutoLayout của iOS
AdricoM

46

Tôi nghĩ (và tôi có thể sẽ bị kích động vì điều này), nhưng một lần nữa tôi nghĩ rằng điện thoại của tôi có bộ xử lý lõi tứ để cạnh tranh (nếu không phá hủy hoàn toàn) hầu hết các máy tính cá nhân tại nhà.

Tôi cũng nghĩ rằng loại khả năng phần cứng này là tương lai của điện thoại.

Vì vậy, tôi đi đến một kết luận, miễn là bạn không bị cuốn theo lồng (trong MHO, bố cục không bao giờ sâu hơn 4 cấp và nếu bạn có thể làm sai), điện thoại của bạn có thể quan tâm ít hơn về việc có trọng lượng.

Có rất nhiều điều bạn có thể làm sẽ có ảnh hưởng sâu rộng hơn nhiều đến hiệu suất, sau đó lo lắng về bộ xử lý của bạn làm thêm một số phép toán.

(xin lưu ý rằng tôi hơi hài hước, và vì vậy đừng quá coi trọng bài đăng này, ngoài ra ý kiến ​​cho rằng có những thứ khác bạn nên tối ưu hóa trước, và việc lo lắng về trọng lượng sâu 2-3 cấp không giúp ích gì sức khỏe của bạn)


2
được thực hiện, và về cơ bản là đồng ý, nhưng đã nghe nói về việc sử dụng iphone trung bình (bao gồm cả các dịch vụ / trang web hỗ trợ sử dụng) xung quanh cùng một lượng năng lượng một năm như tủ lạnh gia đình trung bình của Hoa Kỳ. Do đó, trách nhiệm của chúng tôi là các nhà phát triển phải cân nhắc loại tác động môi trường này. Rõ ràng đó luôn là một hành động cân bằng: thời gian, chi phí, hiệu suất, sự ổn định và nói chung tôi đồng ý với quan điểm của bạn - nhưng chỉ nghĩ rằng chúng ta cũng nên xem xét loại tác động này. Rõ ràng bảo trì / mở rộng cũng đến ở đây. Dù sao đi nữa - điểm được thực hiện và cảm ơn.
MemeDeveloper

Nhận ra điểm cụ thể trong câu hỏi là về việc xử lý trên thiết bị không phải trên web, nhưng có nghĩa là nhận xét của tôi như một điểm chung về các ưu tiên vì các nhà phát triển hơn các chi tiết cụ thể của OP.
MemeDeveloper

11

Lý do chính tại sao trọng lượng lồng nhau là xấu là khi một bố cục có trẻ em với trọng lượng, nó phải được đo hai lần (tôi nghĩ rằng điều này được đề cập trong cảnh báo lint). Điều này có nghĩa là bố cục có trọng số cũng chứa bố cục có trọng số phải đo bốn lần và mỗi "lớp" trọng lượng bạn thêm vào sẽ tăng các số đo với sức mạnh gấp đôi.

Trong ICS (API cấp 14), GridLayoutđã được thêm vào, cho phép các giải pháp đơn giản và 'phẳng' cho nhiều bố cục mà trước đây yêu cầu trọng số. Nếu bạn đang phát triển cho các phiên bản Android trước đó, bạn sẽ gặp khó khăn hơn trong việc loại bỏ trọng lượng, nhưng sử dụng RelativeLayoutvà làm phẳng càng nhiều càng tốt bố cục của bạn vào chiếc taxi đó thường loại bỏ rất nhiều trọng lượng lồng nhau.


9
Tôi không nghĩ bạn có thể đạt được kết quả tương tự với GridLayout hoặc RelativeLayout . Ví dụ GridLayout: "GridLayout không cung cấp hỗ trợ cho nguyên tắc trọng lượng, như được xác định theo trọng lượng. Nói chung, do đó, không thể định cấu hình GridLayout để phân phối không gian dư thừa giữa nhiều thành phần."
Timmmm

Bắt đầu trong API 21, khái niệm về trọng lượng đã được thêm vào GridLayout. Để hỗ trợ các thiết bị Android cũ hơn, bạn có thể sử dụng GridLayout từ thư viện hỗ trợ v7. android.support.v7.widget.GridLayout
Эвансгелист Evansgelist

2

Có một giải pháp dễ dàng để tránh linearLayout lồng nhau với trọng số - chỉ cần sử dụng Tablelayout với weightSum và linearLayout lồng nhau với weightSum - Tablelayout có các thuộc tính tương tự như linearLayout (định hướng, weightSum, layout_ weight, v.v.) và không hiển thị thông báo - "lồng nhau có hại cho hiệu suất "

Thí dụ:

 <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

Tôi nghĩ, sự thay thế duy nhất là tạo một hàm sẽ được gọi là onResume và sẽ đặt tất cả các kích cỡ và vị trí. Dù sao, theo trọng lượng, bạn chỉ có thể đặt kích thước nhưng không có phần đệm (vì vậy bố cục thậm chí còn phức tạp hơn), không có textSize (không thể bù phần này bằng cách nào đó), chứ đừng nói đến những thứ như số dòng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.