วิธีการบรรลุขอบทับซ้อน / ลบในเค้าโครงข้อ จำกัด ?


119

เป็นไปได้หรือไม่ที่จะบรรลุขอบเชิงลบในรูปแบบข้อ จำกัด เพื่อให้เกิดการทับซ้อนกัน? ฉันพยายามให้รูปภาพอยู่ตรงกลางเค้าโครงและมีมุมมองข้อความเพื่อให้ภาพซ้อนทับกัน a x dp ฉันลองตั้งค่ามาร์จิ้นติดลบ แต่โชคไม่ดี จะดีมากถ้ามีวิธีที่จะทำให้สำเร็จได้


แนวทางอาจช่วยได้ฉันยังไม่ได้ลอง
— Eugen Pechanec

คำตอบ:


215

คำชี้แจง:คำตอบด้านล่างยังคงใช้ได้ แต่ฉันต้องการชี้แจงสองสามสิ่ง โซลูชันดั้งเดิมจะวางมุมมองที่มีค่าชดเชยเชิงลบโดยพฤตินัยเทียบกับมุมมองอื่นตามที่ระบุไว้และจะปรากฏในเค้าโครงดังที่แสดง

ทางออกก็คือการใช้translationYคุณสมบัติตามที่แนะนำโดยอาเมียร์ Khorsandi ที่นี่ ฉันชอบวิธีการแก้ปัญหาที่ง่ายกว่าโดยมีข้อแม้เดียว: การแปลเกิดขึ้นหลังการจัดวางดังนั้นมุมมองที่ จำกัด อยู่ที่มุมมองที่ถูกแทนที่จะไม่เป็นไปตามคำแปล

ตัวอย่างเช่น XML ต่อไปนี้จะแสดงTextViewสองรายการที่ด้านล่างของรูปภาพ แต่ละมุมมองจะถูก จำกัด จากบนลงล่างโดยมุมมองที่ปรากฏอยู่ด้านบนทันที

ใส่คำอธิบายภาพที่นี่

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

ตอนนี้ขอแปลว่า "ฉันพูดชื่อ" TextViewขึ้น50dpโดยการระบุ

android:translationY="-50dp"

สิ่งนี้ก่อให้เกิดสิ่งต่อไปนี้:

ใส่คำอธิบายภาพที่นี่

TextView "พูดชื่อฉัน" ได้เลื่อนขึ้นตามที่คาดไว้ แต่TextView "พูดเลย" ไม่ได้เป็นไปตามที่เราคาดไว้ เพราะนี่คือการแปลเกิดขึ้นโพสต์รูปแบบ แม้ว่ามุมมองจะย้ายหลังการจัดวาง แต่ก็ยังสามารถคลิกได้ในตำแหน่งใหม่

ดังนั้น IMO ไปกับtranslationXและtranslationYสำหรับระยะขอบติดลบในConstraintLayoutหากข้อแม้ข้างต้นไม่ส่งผลต่อเลย์เอาต์ของคุณ มิฉะนั้นให้ใช้วิดเจ็ตพื้นที่ดังที่ระบุไว้ด้านล่าง


คำตอบเดิม

แม้ว่าจะไม่ได้รับการสนับสนุนขอบลบConstraintLayoutแต่ก็มีวิธีที่จะทำให้เอฟเฟกต์สำเร็จได้โดยใช้เครื่องมือที่พร้อมใช้งานและรองรับ นี่คือภาพที่ชื่อภาพซ้อนทับ22dpจากด้านล่างของภาพ - -22dpระยะขอบอย่างมีประสิทธิภาพ:

ใส่คำอธิบายภาพที่นี่

สิ่งนี้ทำได้โดยใช้Spaceวิดเจ็ตที่มีระยะขอบล่างเท่ากับออฟเซ็ตที่คุณต้องการ วิดเจ็ตนั้นมาได้ด้านล่างของมันบีบบังคับให้ด้านล่างของSpace ImageViewตอนนี้สิ่งที่คุณต้องทำคือ จำกัด ด้านบนของTextViewชื่อภาพที่ด้านล่างของSpaceวิดเจ็ต TextViewจะถูกวางตำแหน่งที่ด้านล่างของSpaceมุมมองละเลยอัตรากำไรขั้นต้นที่ตั้งไว้

ต่อไปนี้คือ XML ที่บรรลุผลนี้ ฉันจะสังเกตว่าฉันใช้Spaceเพราะมันมีน้ำหนักเบาและมีไว้สำหรับการใช้งานประเภทนี้ แต่ฉันสามารถใช้ประเภทอื่นViewและทำให้มองไม่เห็น (คุณอาจจะต้องทำการปรับเปลี่ยนแม้ว่า.) นอกจากนี้คุณยังสามารถกำหนดViewมีอัตรากำไรที่ศูนย์และความสูงของขอบภาพประกอบที่คุณต้องการและข้อ จำกัด ด้านบนของด้านบนของสิ่งที่ใส่เข้าไปที่TextViewView

อีกวิธีหนึ่งคือการวางซ้อนทับTextViewด้านบนImageViewโดยจัดแนวท็อปส์ / ก้น / ซ้าย / ขวาและทำการปรับเปลี่ยนระยะขอบ / ช่องว่างภายในให้เหมาะสม ประโยชน์ของแนวทางที่แสดงด้านล่างนี้คือสามารถสร้างขอบลบได้โดยไม่ต้องคำนวณมากนัก กล่าวคือมีหลายวิธีในการเข้าถึงสิ่งนี้

ปรับปรุง:สำหรับการอภิปรายอย่างรวดเร็วและการสาธิตของเทคนิคนี้ให้ดูที่ Google Developers กลางบล็อกโพสต์

ขอบลบสำหรับ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>

ไม่ได้ทำงานในกรณีของฉันImageViewเป็นศูนย์กลางในการปกครองการทับซ้อนดังกล่าวข้างต้นTextView ImageViewจากนั้นSpaceทำให้เกิดข้อผิดพลาดเมื่อแอปกลับจากพื้นหลัง ฉันคิดว่า 0dp, 0dp ทำให้เกิดปัญหา Guidelineสิ่งที่เกี่ยวกับการใช้งานเพียงแค่
— illusionJJ

วิธีนี้ใช้ไม่ได้กับมุมมองที่มีข้อ จำกัด กับผู้ปกครอง
— R4j

ทำไมฉันต้องมี Space? ฉันลองโดยไม่มีช่องว่างและก็ได้ผลลัพธ์แบบเดียวกัน
— kuzdu

@kuzdu ประเด็นตรงนี้คือด้านล่างของช่องว่างถูก จำกัด ที่ด้านล่างของ imageView ระยะขอบจะเลื่อนช่องว่างขึ้นจากนั้นด้านบนของมุมมองข้อความจะถูก จำกัด ที่ด้านล่างของช่องว่างซึ่งจะสร้าง "การซ้อนทับครึ่งหนึ่งนี้ "ผลที่เราพยายามทำให้สำเร็จ โปรดโพสต์คำตอบที่นี่หากคุณได้รับมันโดยไม่มีช่องว่างเพื่อให้เราเห็นข้อ จำกัด ที่คุณใช้กับสองมุมมองของคุณ
— Lucas P.

62

อีกวิธีหนึ่งคือการใช้translationXหรือtranslationYเช่นนี้:

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

มันจะทำงานเหมือน android:layout_marginRight="-25dp"


29
โปรดทราบเรื่องนี้เนื่องจากตำแหน่งจริงของมุมมองยังคงอยู่ที่ตำแหน่งเดิม (ก่อนการแปล) จึงจะแปลด้วยภาพเท่านั้น ดังนั้นเหตุการณ์ onClick จะถูกทริกเกอร์จากในตำแหน่งเดิมเท่านั้น
— goemic

คำกล่าวของ @ goemic ดูเหมือนจะผิดเนื่องจากนี่ไม่ใช่แอนิเมชั่นทวีต แต่เป็นแอนิเมชั่นคุณสมบัติ (โปรดแก้ไขฉันถ้าฉันผิด)
— Henry

การปฏิบัติที่ไม่ดีเนื่องจากไม่รองรับรูปแบบ RTL
— Salam El-Banna

27

อัตรากำไรเชิงลบไม่เคยได้รับการสนับสนุนอย่างเป็นทางการใน RelativeLayout ไม่รองรับระยะขอบเชิงลบใน ConstraintLayout [... ]

- Romain Guy เมื่อวันที่ 8 มิ.ย. 2559

ปฏิบัติตามสองประเด็นนี้:

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


แนวคิดของพวกเขาอาจเป็นไปได้ว่าด้วยรูปแบบที่ จำกัด คุณไม่จำเป็นต้องมีขอบลบ ซึ่งอาจเป็นจริงหากคุณมีองค์ประกอบทั้งหมดในเค้าโครงเดียว บางครั้งแม้ว่าคุณต้องการจัดกลุ่มองค์ประกอบเชิงตรรกะเช่นในแถบคำสั่งที่ทำจากปุ่มซึ่งมีข้อดีในตัวเองสำหรับการใช้ซ้ำและความชัดเจนและการห่อหุ้ม เมื่อถึงจุดนั้นกลุ่มจะมีรูปร่างเป็นสี่เหลี่ยมผืนผ้าและข้อ จำกัด ของรูปร่างนั้นทำให้ระยะขอบเชิงลบมีประโยชน์และจำเป็นอีกครั้ง
— AndrewBloom

ระยะขอบเชิงลบเลียนแบบแนวคิดเดียวกันกับพื้นฐานของข้อความโดยเป็นข้อความที่มีรูปร่างซับซ้อนภายในภาชนะสี่เหลี่ยม
— AndrewBloom

15

นี่คือสิ่งที่ฉันคิดได้หลังจากพยายามหาวิธีแก้ปัญหามาหลายชั่วโมง

ให้เราพิจารณาสองภาพ image1 และ image2 Image2 จะถูกวางไว้ที่ด้านบนของ image1 ในตำแหน่งทางด้านขวาล่าง

ตัวอย่างมุมมองที่ทับซ้อนกัน ภาพ

เราสามารถใช้วิดเจ็ตSpaceสำหรับมุมมองที่ทับซ้อนกัน

จำกัด ทั้งสี่ด้านของวิดเจ็ต Space กับด้านทั้งสี่ของรูปภาพ 1 ตามลำดับ สำหรับตัวอย่างนี้ จำกัด ด้านซ้ายของ image2 ด้วยด้านขวาของวิดเจ็ต Space และด้านบนของ image2 กับด้านล่างของวิดเจ็ต Space สิ่งนี้จะผูก image2 กับวิดเจ็ต Space และเนื่องจากวิดเจ็ต Space ถูก จำกัด จากทุกด้านเราจึงสามารถกำหนดอคติแนวนอนหรือแนวตั้งที่ต้องการซึ่งจะย้าย image2 ตามต้องการ

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

นอกจากนี้ในการวางตำแหน่ง image2 ที่กึ่งกลางด้านล่างของ image1 เราสามารถ จำกัด ด้านซ้ายและขวาของ image2 ด้วย Space widget ด้านซ้ายและขวาตามลำดับ ในทำนองเดียวกันเราสามารถวาง image2 ได้ทุกที่โดยเปลี่ยนข้อ จำกัด ของ image2 ด้วยวิดเจ็ต Space


ขอบคุณสำหรับคำตอบ!
— user3193413

11

ฉันพบวิธีที่ง่ายกว่านี้มาก

โดยทั่วไปจะมี ImageView จากนั้นในมุมมองข้อความให้เพิ่มข้อ จำกัด ด้านบนเพื่อให้ตรงกับข้อ จำกัด ด้านบนของรูปภาพและเพิ่มระยะขอบด้านบนของ TextView เพื่อจับคู่เพื่อให้ได้ลักษณะการทำงานของประเภทระยะขอบ -ve


9
เว้นแต่ความสูงของภาพจะแปรผัน
— Stas Shusha

มันจะยังคงทำงาน คุณเพียงแค่ต้องระวังว่าคุณต้องการให้วิดเจ็ตส่วนบนของคุณวางซ้อนภาพที่ใดการตั้งค่าระยะขอบจากด้านขวาหรือด้านล่างอาจเป็นตัวเลือกที่ดีกว่าหรือคุณอาจใช้อคติซึ่งทั้งหมดนี้ตอบคำถามได้ .
— Gabriel Vasconcelos

4

ซึ่งจะช่วยหลาย ๆ

ในกรณีของฉันฉันต้องการการออกแบบของฉันเช่นนี้:

หลังจาก

หมายความว่าฉันต้องการให้รูปภาพของฉันแสดงผลครึ่งหนึ่งของความกว้างดังนั้นโดยพื้นฐานแล้วฉันต้องการระยะขอบเชิงลบของครึ่งหนึ่งของความกว้างของภาพจริง แต่เลย์เอาต์ทั้งหมดของฉันในเลย์เอาต์ที่ จำกัด และเลย์เอาต์ข้อ จำกัด ไม่อนุญาตให้มีขอบติดลบดังนั้นฉันจึงทำได้ด้วยโค้ดด้านล่าง

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

ดังนั้น ImageView จะสิ้นสุดที่จุดเริ่มต้นของแนวทาง และผลกระทบจะเหมือนกับระยะขอบติดลบที่จุดเริ่มต้น 50dp

และหากความกว้างของมุมมองของคุณไม่ได้รับการแก้ไขและเป็นเปอร์เซ็นต์เพื่อให้คุณสามารถวางแนวทางด้วยเปอร์เซ็นต์และบรรลุผลตามที่คุณต้องการ

Happy Coding :)


0

คุณต้องใช้วิดเจ็ต Space ในเลย์เอาต์ของคุณเท่านั้น

<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

นี่เป็นคำถามเก่าที่ยังถูกถามกันมากวิธีที่เร็วที่สุดในการบรรลุเป้าหมายนี้คือการ จำกัด ด้านบนและด้านล่างไว้ที่ด้านข้างของมุมมองที่คุณต้องการยึดไว้ดังนี้:

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

ซึ่งจะจัดกึ่งกลางไว้ที่บรรทัดล่างสุดของมุมมองโดยจัดกึ่งกลางในแนวนอน


-1

วิธีง่ายๆ

ฉันไม่แน่ใจว่าวิธีที่ดีที่สุด

เพียงห่อโดยใช้ 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>

สิ่งนี้เพิ่มการซ้อนกันเล็กน้อย แต่ใช้ได้กับการสร้างภาพเคลื่อนไหวจากมุมมองด้านบนซึ่งแตกต่างจากโซลูชันอื่น ๆ ที่นี่ซึ่งสมมติว่ามุมมองจะแสดงอย่างสมบูรณ์ ขอบคุณ!
— Leo สนับสนุน Monica Cellio

2
คำตอบนี้ต้องการข้อมูลเพิ่มเติมจำนวนมาก ไม่ชัดเจนว่าการวางบางสิ่งใน LinearLayout สามารถใช้เพื่อทำให้เกิดการทับซ้อนกันได้อย่างไร
— Robert Liberatore
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.