Sử dụng lợi nhuận âm trong Android có phải là một thói quen xấu?


114

Demo của lợi nhuận âm:

                         nhập mô tả hình ảnh ở đây

Kịch bản

Chồng chéo các chế độ xem bằng cách đặt lề âm cho một trong số chúng để nó xâm nhập hộp giới hạn của một chế độ xem khác.

Suy nghĩ

Nó dường như hoạt động theo cách bạn mong đợi với việc chồng chéo các bố cục nếu chúng nên. Nhưng tôi không muốn gặp phải một vấn đề lớn hơn vì vô tình làm không đúng. Trình giả lập, thiết bị vật lý, bạn đặt tên cho nó, khi bạn sử dụng lề âm, mọi thứ dường như hoạt động chính xác, một chế độ xem xâm nhập vào hộp giới hạn chế độ xem của người khác và tùy thuộc vào cách nó được khai báo trong bố cục, nó sẽ ở trên hoặc dưới chế độ xem kia.

Tôi cũng biết rằng vì API 21, chúng tôi có thể đặt các thuộc tính translationZelevationđể làm cho chế độ xem xuất hiện bên trên hoặc bên dưới các chế độ xem khác nhưng mối quan tâm của tôi về cơ bản xuất phát từ thực tế là trong tài liệu cho các layout_marginthuộc tính, nó đã chỉ định rõ ràng rằng giá trị ký quỹ phải là số dương , hãy tôi trích dẫn:

Đoạn trích:
Chỉ định không gian thừa ở các bên trái, trên, phải và dưới cùng của dạng xem này. Không gian này nằm ngoài giới hạn của chế độ xem này.Giá trị ký quỹ phải là số dương . Phải là một giá trị thứ nguyên, là một số dấu phẩy động được nối với một đơn vị chẳng hạn như "14,5sp". Các đơn vị khả dụng là: px (pixel), dp (pixel không phụ thuộc vào mật độ), sp (pixel được chia tỷ lệ dựa trên kích thước phông chữ ưa thích), in (inch), mm (milimét) ...

Trong những năm kể từ khi đặt câu hỏi này lần đầu tiên, tôi không gặp bất kỳ vấn đề nào với lợi nhuận âm, đã cố gắng tránh sử dụng chúng nhiều nhất có thể, nhưng không gặp phải bất kỳ vấn đề nào, vì vậy mặc dù tài liệu nói rằng, tôi cũng không lo lắng về nó.


1
Tôi biết các bài kiểm tra cà phê espresso sẽ không thể nhìn thấy đối tượng nếu một trong các lợi nhuận của nó là âm ... vì vậy đó là lý do để không sử dụng chúng
Tim Boland

Câu trả lời:


192

Năm 2010, @RomainGuy (kỹ sư cốt lõi của Android) tuyên bố rằng lợi nhuận âm có hành vi không xác định .

Vào năm 2011, @RomainGuy tuyên bố rằng bạn có thể sử dụng lợi nhuận âm trên LinearLayoutRelativeLayout .

Vào năm 2016, @RomainGuy tuyên bố rằng họ chưa bao giờ được hỗ trợ chính thức và sẽ không được hỗ trợ bởiConstraintLayout .

Tuy nhiên, rất dễ để khắc phục hạn chế này.

Thêm chế độ xem trợ giúp (chiều cao 0dp, chiều rộng được giới hạn cho phụ huynh) ở dưới cùng của chế độ xem cơ sở của bạn, ở dưới cùng hãy thêm lề bạn muốn.
Sau đó, đặt chế độ xem của bạn bên dưới chế độ xem này, cho phép chế độ xem có lợi nhuận "âm" một cách hiệu quả nhưng không cần phải sử dụng bất kỳ giá trị âm không được hỗ trợ nào.


1
Có vẻ là một điều vô hại sau đó, để lại mở trong trường hợp bất cứ ai có một số cái nhìn sâu sắc khác
Juan Cortés

1
@DrewLeSueur: Tôi sẽ không đưa ra giả định đó. Tôi không biết đệm phủ định có nghĩa là gì.
CommonsWare

1
@CommonsWare bạn có thể cho tôi biết, là nó có thể một cái gì đó làm như thế `- @ dimen / anyvalue" Tôi muốn gọi tuyên bố giá trị nhưng âm Trợ giúp?..
deadfish

2
@ 100kg: Xin lỗi, nhưng cái đó không được hỗ trợ.
CommonsWare

21
Tôi nhận thấy rằng trong Android 4.4 KitKat, có điều gì đó đã thay đổi liên quan đến lợi nhuận âm (so với 4.3; ít nhất là trên Asus Nexus 7). Hóa ra bạn cần android:clipChildren="false"android:clipToPadding="false"nơi bạn trước đây không, hoặc mọi thứ vỡ ra như thế này .
Jonik

18

Hy vọng điều này sẽ giúp một ai đó. Đây là mã mẫu đang hoạt động ConstraintLayoutdựa trên câu trả lời của @ CommonsWare:

Thêm chế độ xem trợ giúp (chiều cao 0dp, chiều rộng được giới hạn cho phụ huynh) ở dưới cùng của chế độ xem cơ sở của bạn, ở dưới cùng, hãy thêm lề bạn muốn. Sau đó, đặt chế độ xem của bạn bên dưới chế độ xem này, cho phép chế độ xem có lợi nhuận "âm" một cách hiệu quả nhưng không cần phải sử dụng bất kỳ giá trị âm nào không được hỗ trợ.

Mã mẫu:

<TextView
    android:id="@+id/below"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F1B36D"
    android:padding="30dp"
    android:text="I'm below"
    android:textColor="#ffffff"
    android:textSize="48sp"
    android:textAlignment="center"
    tools:layout_editor_absoluteX="129dp"
    tools:layout_editor_absoluteY="0dp" />

<android.support.v4.widget.Space
    android:id="@+id/space"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="32dp"
    app:layout_constraintBottom_toBottomOf="@+id/below"
    app:layout_constraintLeft_toLeftOf="@id/below"
    app:layout_constraintRight_toRightOf="@id/below" />

<TextView
    android:id="@+id/top"
    android:layout_width="100dp"
    android:layout_height="60dp"
    android:textAlignment="center"
    android:textColor="#ffffff"
    android:text="I'M ON TOP!"
    android:background="#676563"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/space" />

Đầu ra:

nhập mô tả hình ảnh ở đây


16

Trong trường hợp bạn muốn sử dụng lề âm, hãy đặt đủ đệm cho vùng chứa và clipToPadding của nó thành false và đặt lề âm cho nó là trẻ em để nó không cắt chế độ xem trẻ em!


4

Trước đây, nó có thể là một hoạt động không tốt nhưng với Material Design và các nút hành động nổi của nó, nó dường như là điều không thể tránh khỏi và bắt buộc trong nhiều trường hợp. Về cơ bản, khi bạn có hai bố cục riêng biệt mà bạn không thể đưa vào một RelativeLayout duy nhất vì chúng cần xử lý riêng biệt rõ ràng (ví dụ: tiêu đề và nội dung), cách duy nhất để chồng chéo FAB là làm cho nó dính ra khỏi một bố cục sử dụng lề âm. Và điều này tạo ra các vấn đề bổ sung với các khu vực có thể nhấp.


3

Đối với tôi, và liên quan đến việc đặt lợi nhuận âm trên TextView (tôi nhận ra OP đang đề cập đến một ViewGroup, nhưng tôi đang tìm kiếm các vấn đề với việc đặt lợi nhuận âm và tôi đã hạ cánh ở đây) ... Tôi đã tìm thấy sự cố với 4.0.3 ( API 15) CHỈ và cài đặt android:layout_marginTophoặc android:layout_marginBottomthành giá trị âm, chẳng hạn như -2dp.

Vì một số lý do mà TextView không hiển thị. Nó dường như đã "biến mất" khỏi chế độ xem (không chỉ là vô hình).

Khi tôi thử điều này với 3 phiên bản layout_margin khác, tôi không thấy vấn đề.

Lưu ý rằng tôi chưa thử điều này trên thiết bị thực, điều này đang sử dụng trình giả lập 4.0.3. Đây là điều kỳ lạ thứ 2 mà tôi thấy rằng chỉ ảnh hưởng đến 4.0.3, vì vậy quy tắc mới của tôi là luôn kiểm tra với trình giả lập 4.0.3 :)

Tôi đã thành công với việc giảm lề dưới cùng của TextView bằng cách sử dụng android:lineSpacingExtra="-2dp"nó hoạt động mặc dù tôi tình cờ có android:singleLine="true"(và vì vậy tôi không nghĩ rằng khoảng cách dòng sẽ là một yếu tố).


1
Tôi đã tìm thấy hành vi tương tự trên Nexus 4 (là xhdpi) và 4.2.2. Có một bố cục không có phần đệm, mặc dù một bố cục mẹ có phần đệm. Có một TextView bên trong với marginTop âm. Trên 5.0, nó hoạt động tốt. Vào ngày 4.2.2 trên cả thiết bị và trong trình giả lập cho Nexus 4, nó sẽ biến mất. Giải pháp là di chuyển phần đệm đến bố cục chứa TextView.
louielouie

3

Không, bạn không nên sử dụng negative margin. thay vào đó bạn nên sử dụng translate. Ngay cả khi lợi nhuận âm đôi khi hoạt động, khi bạn thay đổi bố cục theo chương trình, dịch sẽ hữu ích. Và chế độ xem không thể tràn màn hình nếu bạn sử dụng lề.


0

Tôi chỉ biết rằng điều đó có thể xảy ra trong một khoảng thời gian khá ngắn. Nhưng tôi thấy không có vấn đề gì với nó. Chỉ cần lưu ý về kích thước màn hình và những thứ đó để bạn chắc chắn không vô tình làm cho các mục không được xuất hiện chồng lên nhau trên màn hình. (nghĩa là văn bản trên đầu văn bản có thể là một ý tưởng tồi.)

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.