Можно ли добиться отрицательного запаса на макете ограничения для достижения перекрытия? Я пытаюсь иметь изображение, ориентированное на макет, и иметь вид Text таким образом, что он перекрывает x на x dp. Я попытался установить отрицательное значение маржи, но не повезло. Было бы здорово, если бы был способ достичь этого.
Как добиться перекрытия/отрицательной границы в макете ограничений?
Ответ 1
Хотя не представляется, что в ConstraintLayout
будут поддерживаться отрицательные поля, есть способ добиться эффекта, используя инструменты, которые доступны и поддерживаются. Вот изображение, где заголовок изображения перекрывается на 22dp
от нижней части изображения - фактически -22dp
:
Это было достигнуто с помощью виджета Space
с нижним полем, равным требуемому смещению. У виджета " Space
" нижний предел ограничен низом ImageView
. Теперь все, что вам нужно сделать, это ограничить верхнюю часть TextView
заголовком изображения до нижней части виджета Space
. TextView
будет расположен в нижней части TextView
Space
игнорируя установленное поле.
Ниже приведен XML, который выполняет этот эффект. Я отмечу, что я использую Space
потому что он легкий и предназначен для этого типа использования, но я мог бы использовать другой тип View
и сделать его невидимым. (Вы, возможно, потребуется внести коррективы, однако.) Кроме того, можно определить View
с нулевыми полями и высоты края вставки вы хотите, и ограничить верхнюю часть TextView
к началу вложенном View
.
Еще один подход заключается в наложении TextView
поверх ImageView
путем выравнивания tops/bottomoms/lefts/right и внесения соответствующих корректировок в поля/отступы. Преимущество подхода, продемонстрированного ниже, состоит в том, что отрицательный запас может быть создан без большого количества вычислений. Это все, чтобы сказать, что есть несколько способов приблизиться к этому.
Обновление. Краткое обсуждение и демонстрация этой техники см. В блоге Google Developers Medium.
Отрицательная маржа для ConstraintLayout
XML
<?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"
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>
Ответ 2
Другой способ - использовать 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"
Ответ 3
Отрицательные поля никогда официально не поддерживались в RelativeLayout. Отрицательные поля не будут поддерживаться в ConstraintLayout. [...]
- Ромен Гай 8 июня 2016 года
Выполните следующие две проблемы:
https://code.google.com/p/android/issues/detail?id=212499 https://code.google.com/p/android/issues/detail?id=234866
Ответ 4
Я нашел способ сделать это намного проще.
В основном есть ImageView, затем в текстовом представлении добавьте верхнее ограничение для соответствия верхнему ограничению изображения и просто добавьте верхнюю часть поля TextView, чтобы он соответствовал поведению типа -ve margin.
Ответ 5
Это то, что я понял после нескольких часов попыток найти решение.
Давайте рассмотрим два изображения, image1 и image2. Изображение 2 должно быть размещено поверх изображения 1, расположенного справа внизу.
Мы можем использовать виджет 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 слева и справа соответственно. Точно так же мы можем разместить image2 где угодно, изменив ограничения image2 с помощью виджета Space.
Ответ 6
Это поможет многим
В моем случае я хочу, чтобы мой дизайн был таким:
Означает, что я хочу, чтобы мое изображение отображало половину их ширины, поэтому в основном мне нужен отрицательный отступ в половине фактической ширины изображения, но весь мой макет в макете ограничения и макете ограничения не допускает отрицательного поля, поэтому я добился этого с помощью кода ниже
<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.
А также, если ширина вашего обзора не фиксирована и указана в процентах, так что вы можете разместить указатель в процентах и добиться желаемого эффекта
Удачного кодирования :)
Ответ 7
Простой путь
Я не уверен, лучший способ.
Просто оберните, используя 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>