Làm thế nào để đạt được chồng chéo / lề âm trên Bố cục Ràng buộc?


117

Có thể đạt được lợi nhuận âm trên bố cục ràng buộc để đạt được sự chồng chéo không? Tôi đang cố gắng để một hình ảnh được căn giữa vào bố cục và có dạng xem Văn bản sao cho nó chồng lên nhau a x dp. Tôi đã thử đặt giá trị ký quỹ âm nhưng không may mắn. Sẽ thật tuyệt nếu có một cách nào đó để đạt được điều này.


Hướng dẫn có thể hữu ích, tôi chưa thử.
Eugen Pechanec

Câu trả lời:


214

Làm rõ: Câu trả lời dưới đây vẫn hợp lệ, nhưng tôi muốn làm rõ một vài điều. Giải pháp ban đầu sẽ đặt một chế độ xem có độ lệch âm trên thực tế đối với một chế độ xem khác như đã nêu và sẽ xuất hiện trong bố cục như được hiển thị.

Một giải pháp khác là sử dụng translationY tài sản theo đề nghị của Amir Khorsandi đây . Tôi thích giải pháp đó đơn giản hơn với một lưu ý: Bản dịch xảy ra sau bố cục , vì vậy các chế độ xem bị giới hạn ở chế độ xem bị dịch chuyển sẽ không tuân theo bản dịch.

Ví dụ: XML sau đây hiển thị hai TextView ngay bên dưới hình ảnh. Mỗi chế độ xem được giới hạn từ trên xuống dưới với chế độ xem xuất hiện ngay phía trên nó.

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

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:tint="#388E3C"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_action_droid" />

    <TextView
        android:id="@+id/sayName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Say my name."
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="@+id/imageView" />

    <TextView
        android:id="@+id/sayIt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Say it."
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintEnd_toEndOf="@+id/sayName"
        app:layout_constraintStart_toStartOf="@+id/sayName"
        app:layout_constraintTop_toBottomOf="@id/sayName" />
</androidx.constraintlayout.widget.ConstraintLayout>

Bây giờ, hãy dịch TextView "Say my name" lên bằng 50dpcách chỉ định

android:translationY="-50dp"

Điều này tạo ra những điều sau:

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

TextView "Nói tên tôi" đã tăng lên như mong đợi, nhưng TextView "Hãy nói đi" đã không theo kịp như chúng ta mong đợi. Điều này là do bản dịch xảy ra sau bố cục . Mặc dù chế độ xem di chuyển sau bố cục, nó vẫn có thể nhấp được ở vị trí mới.

Vì vậy, IMO, hãy sử dụng dịchXdịchY cho các lề âm trong ConstraintLayout nếu cảnh báo ở trên không ảnh hưởng đến bố cục của bạn; nếu không, hãy sử dụng tiện ích không gian như được nêu bên dưới.


Câu trả lời ban đầu

Mặc dù có vẻ như không hỗ trợ lợi nhuận âm ConstraintLayout, nhưng có một cách để đạt được hiệu quả bằng cách sử dụng các công cụ có sẵn và được hỗ trợ. Đây là hình ảnh trong đó tiêu đề hình ảnh được chồng lên 22dptừ cuối hình ảnh - thực sự là một -22dplề:

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

Điều này đã được thực hiện bằng cách sử dụng Spacetiện ích con có lợi nhuận dưới cùng bằng với mức bù mà bạn muốn. Sau Spaceđó, tiện ích con có phần dưới của nó bị giới hạn ở phần dưới cùng của ImageView. Bây giờ, tất cả những gì bạn cần làm là hạn chế phần trên cùng của TextViewtiêu đề hình ảnh ở phần cuối của Spacetiện ích. Di TextViewchúc được đặt ở cuốiSpace cái nhìn phớt lờ bên lề đã đặt ra.

Sau đây là XML thực hiện hiệu ứng này. Tôi sẽ lưu ý rằng tôi sử dụng Spacevì nó nhẹ và dành cho loại sử dụng này, nhưng tôi có thể đã sử dụng một loại khác Viewvà làm cho nó vô hình. (Tuy nhiên, bạn có thể sẽ cần phải thực hiện các điều chỉnh.) Bạn cũng có thể xác định một Viewlề bằng 0 và chiều cao của lề lót mà bạn muốn, đồng thời giới hạn phần trên cùng của TextViewphần trên cùng của phần chèn View.

Tuy nhiên, một cách tiếp cận khác sẽ là phủ TextViewlên trên ImageViewbằng cách căn chỉnh các đỉnh / đáy / lề / phải và thực hiện các điều chỉnh phù hợp với lề / đệm. Lợi ích của phương pháp được trình bày dưới đây là có thể tạo ra một biên âm mà không cần tính toán nhiều. Đó là tất cả để nói rằng có một số cách để tiếp cận điều này.

Cập nhật: Để có một cuộc thảo luận nhanh và bản trình diễn về kỹ thuật này, hãy xem bài đăng trên blog của Google Developers Medium .

Ký quỹ âm cho ConstraintLayoutXML

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher" />

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

    <TextView
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Say my name"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/marginSpacer" />
</android.support.constraint.ConstraintLayout>

Không hoạt động trong trường hợp của tôi, ImageViewđược tập trung vào phụ huynh, TextViewchồng chéo ở trên ImageView. Sau đó, Spacetạo ra lỗi khi ứng dụng trở lại từ nền. Tôi nghĩ 0dp, 0dp gây ra một số rắc rối. Chỉ sử dụng thì sao Guideline.
ảo

Cách này không thể hoạt động đối với chế độ xem có ràng buộc với cha mẹ.
R4j

Tại sao tôi cần Dấu cách? Tôi đã thử mà không có khoảng trống và tôi có kết quả tương tự.
kuzdu

@kuzdu vấn đề ở đây là phần dưới cùng của không gian bị hạn chế ở dưới cùng của imageView, lề di chuyển không gian lên trên và sau đó phần trên cùng của chế độ xem văn bản bị hạn chế ở cuối khoảng trống, tạo ra "lớp phủ một nửa "mà chúng tôi đang cố gắng đạt được. Vui lòng đăng câu trả lời ở đây nếu bạn đã quản lý để lấy nó mà không có khoảng trống để chúng tôi có thể thấy những ràng buộc bạn đã sử dụng trên hai chế độ xem của mình.
Lucas P.

Bạn là Heisenberg ...
Nahro

62

Một cách khác đang sử dụng translationXhoặc translationYnhư thế này:

  <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" 
                android:translationX="25dp"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"/>

nó sẽ hoạt động như thế nào android:layout_marginRight="-25dp"


29
Hãy lưu ý điều này, vì vị trí thực của chế độ xem vẫn ở vị trí ban đầu (trước khi dịch), nó sẽ chỉ được dịch trực quan. Do đó, các sự kiện onClick sẽ chỉ được kích hoạt từ bên trong vị trí cũ.
goemic

Tuyên bố của @ goemic có vẻ sai, vì đây không phải là hoạt ảnh tween mà là hoạt ảnh thuộc tính. (vui lòng sửa cho tôi nếu tôi sai)
Henry

thực tiễn không tốt vì nó không hỗ trợ bố cục RTL
Salam El-Banna

27

Lợi nhuận âm chưa bao giờ được hỗ trợ chính thức trong RelativeLayout. Lợi nhuận âm sẽ không được hỗ trợ trong ConstraintLayout. [...]

- Romain Guy vào ngày 8 tháng 6 năm 2016

Theo dõi hai vấn đề sau:

https://code.google.com/p/android/issues/detail?id=212499 https://code.google.com/p/android/issues/detail?id=234866


ý tưởng của họ có thể là với sự ràng buộc, bạn không cần lợi nhuận âm. Điều đó có thể đúng nếu bạn có tất cả các yếu tố trên một bố cục. Đôi khi, mặc dù bạn muốn nhóm các phần tử một cách hợp lý như trong một dải lệnh làm bằng các nút, điều này có lợi thế riêng về khả năng tái sử dụng cũng như rõ ràng và đóng gói. Tại thời điểm đó, nhóm sẽ có hình dạng hình chữ nhật, và chính hạn chế này trên hình dạng đó làm cho lợi nhuận âm trở lại hữu ích và cần thiết.
AndrewBloom

Lề âm mô phỏng chính xác cùng một khái niệm về đường cơ sở trên văn bản, là văn bản có hình dạng phức tạp trong một hộp chứa hình chữ nhật
AndrewBloom

14

Đây là những gì tôi đã tìm ra sau nhiều giờ cố gắng tìm ra giải pháp.

Chúng ta hãy xem xét hai hình ảnh, image1 và image2. Image2 sẽ được đặt ở trên cùng của image1, ở phía dưới bên phải.

Ví dụ về chế độ xem chồng chéo hình ảnh

Chúng ta có thể sử dụng tiện ích Space cho các khung nhìn chồng chéo.

Ràng buộc bốn cạnh của tiện ích Không gian với bốn cạnh của hình ảnh1 tương ứng. Đối với ví dụ này, hãy ràng buộc mặt trái của image2 với mặt phải của tiện ích Space và mặt trên của image2 với mặt dưới của tiện ích Space. Điều này sẽ liên kết image2 với tiện ích Không gian và vì tiện ích Không gian bị hạn chế từ tất cả các bên, chúng tôi có thể xác định xu hướng ngang hoặc dọc được yêu cầu sẽ di chuyển image2 theo yêu cầu.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Player">
 <ImageView
     android:id="@+id/image1"
     android:layout_width="250dp"
     android:layout_height="167dp"
     android:src="@android:color/holo_green_dark"
     app:layout_constraintEnd_toEndOf="parent"
     app:layout_constraintStart_toStartOf="parent"
     app:layout_constraintTop_toTopOf="parent" />
 <Space
     android:id="@+id/space"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     app:layout_constraintBottom_toBottomOf="@+id/image1"
     app:layout_constraintEnd_toEndOf="@+id/image1"
     app:layout_constraintHorizontal_bias="0.82"
     app:layout_constraintStart_toStartOf="@+id/image1"
     app:layout_constraintTop_toTopOf="@+id/image1"
     app:layout_constraintVertical_bias="0.62" />
 <ImageView
     android:id="@+id/image2"
     android:layout_width="82dp"
     android:layout_height="108dp"
     android:src="@android:color/holo_green_light"
     app:layout_constraintStart_toEndOf="@+id/space"
     app:layout_constraintTop_toBottomOf="@+id/space" />
 </android.support.constraint.ConstraintLayout>

Ngoài ra, để định vị image2 ở giữa dưới cùng của image1, chúng ta có thể ràng buộc các bên trái và phải của image2 với các bên trái và phải của tiện ích Space tương ứng. Tương tự, chúng ta có thể đặt image2 ở bất cứ đâu bằng cách thay đổi các ràng buộc của image2 với tiện ích Space.


Cảm ơn bạn đã trả lời!
user3193413

11

Tôi đã tìm thấy một cách để làm điều đó đơn giản hơn nhiều.

Về cơ bản có ImageView, sau đó trên Text View, thêm ràng buộc trên cùng để khớp với ràng buộc trên cùng của hình ảnh và chỉ cần thêm phần đầu lề của TextView để phù hợp để đạt được hành vi kiểu lề -ve.


9
trừ khi chiều cao hình ảnh có thể thay đổi
Stas Shusha

Nó sẽ vẫn hoạt động. Bạn chỉ cần cẩn thận về nơi bạn muốn tiện ích phía trên của mình phủ lên hình ảnh, đặt lề từ bên phải hoặc từ phía dưới có thể là một lựa chọn tốt hơn hoặc bạn có thể sử dụng thiên vị, tất cả đều trả lời câu hỏi .
Gabriel Vasconcelos

4

Điều này sẽ giúp nhiều

Trong trường hợp của tôi, tôi muốn thiết kế của mình như thế này:

sau

Có nghĩa là tôi muốn hình ảnh của mình hiển thị một nửa chiều rộng của chúng, vì vậy về cơ bản tôi cần lề âm bằng một nửa chiều rộng hình ảnh thực tế nhưng toàn bộ bố cục của tôi trong bố cục ràng buộc và bố cục ràng buộc không cho phép lề âm vì vậy tôi đã đạt được điều này với mã dưới đây

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_launcher_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="50dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

Vì vậy, ImageView đó sẽ kết thúc khi bắt đầu hướng dẫn. và hiệu ứng giống như biên âm khi bắt đầu 50dp.

Và cũng như nếu chiều rộng của chế độ xem của bạn không cố định và nó theo tỷ lệ phần trăm để bạn có thể đặt đường dẫn với tỷ lệ phần trăm và đạt được bất kỳ hiệu ứng nào bạn muốn

Mã hóa vui vẻ :)


0

Bạn chỉ cần sử dụng tiện ích Space trong bố cục của mình

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

<Space
    android:id="@+id/negative_margin"
    android:layout_width="16dp"
    android:layout_height="16dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintRight_toLeftOf="parent"/>

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Widget who needs negative margin"
    app:layout_constraintTop_toBottomOf="@+id/negative_margin"
    app:layout_constraintLeft_toLeftOf="@+id/negative_margin" />


0

Đây là một câu hỏi cũ nhưng được hỏi rất nhiều, cách nhanh nhất để đạt được điều này là giới hạn phần trên và phần dưới ở bên của chế độ xem mà bạn muốn neo vào, như sau:

        <androidx.appcompat.widget.AppCompatImageView
        android:layout_width="55dp"
        android:layout_height="55dp"
        app:layout_constraintBottom_toBottomOf="@+id/parent_view_id"
        app:layout_constraintTop_toBottomOf="@+id/parent_view_id"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

Điều này sẽ căn giữa nó ở dòng dưới cùng của chế độ xem, căn giữa theo chiều ngang.


-1

Một cách đơn giản.

Tôi không chắc cách tốt nhất.

Chỉ cần bọc bằng LinearLayout

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
 <View
 android:layout_width="wrap_content"
 android:layout_marginLeft="-20dp"
 android:layout_height="wrap_content"/>
</LinearLayout>

Điều này bổ sung thêm một chút lồng ghép, NHƯNG nó hoạt động để tạo hoạt ảnh cho các chế độ xem từ trên xuống, không giống như các giải pháp khác ở đây, giả định rằng Chế độ xem sẽ được hiển thị hoàn toàn. Cảm ơn!
Leo ủng hộ Monica Cellio

2
Câu trả lời này cần thêm rất nhiều thông tin. Không rõ cách đưa thứ gì đó vào LinearLayout có thể được sử dụng để thực hiện chồng chéo.
Robert Liberatore
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.