Можно ли добиться отрицательного запаса на макете ограничения для достижения перекрытия? Я пытаюсь центрировать изображение на макете и иметь текстовое представление, чтобы оно перекрывалось x dp. Я попытался установить отрицательное значение маржи, но безуспешно. Было бы здорово, если бы был способ добиться этого.
118
Ответы:
Уточнение: ответ ниже остается в силе, но я хочу прояснить пару вещей. Исходное решение поместит вид с фактическим отрицательным смещением по отношению к другому виду, как указано, и появится в макете, как показано.
Другое решение - использовать свойство translationY, предложенное здесь Амиром Хорсанди . Я предпочитаю это решение как более простое с одной оговоркой: перевод выполняется после макета , поэтому представления, ограниченные смещенным представлением, не будут следовать за переводом.
Например, следующий XML- код отображает два TextView непосредственно под изображением. Каждое представление ограничено сверху вниз с видом, который появляется непосредственно над ним.
Теперь давайте переведем TextView « Назови мое имя» вверх
50dp
, указавЭто дает следующее:
TextView «Say my name» сдвинулся вверх, как и ожидалось, но TextView «Say it» не последовал за ним, как мы могли ожидать. Это потому, что перевод происходит после верстки . Несмотря на то, что вид перемещается после макета, его все еще можно сделать кликабельным в новом месте.
Итак, IMO, используйте translationX и translationY для отрицательных полей в ConstraintLayout, если указанное выше предостережение не влияет на ваш макет; в противном случае используйте виджет пространства, как показано ниже.
Оригинальный ответ
Хотя не похоже, что отрицательные поля будут поддерживаться
ConstraintLayout
, есть способ добиться этого эффекта с помощью доступных и поддерживаемых инструментов. Вот изображение, на котором название изображения перекрывается22dp
снизу изображения - фактически-22dp
поле:Это было достигнуто с помощью
Space
виджета с нижним полем, равным желаемому смещению. ЗатемSpace
нижняя часть виджета ограничивается нижней частьюImageView
. Теперь все, что вам нужно сделать, это связать верхнюю частьTextView
с заголовком изображения с нижней частьюSpace
виджета. ЗначокTextView
будет расположен в нижней частиSpace
представления, игнорируя установленное поле.Ниже приводится XML, который реализует этот эффект. Замечу, что я использую,
Space
потому что он легкий и предназначен для этого типа использования, но я мог бы использовать другой типView
и сделать его невидимым. (Тем не менее, вам, вероятно, придется внести изменения.) Вы также можете определить aView
с нулевыми полями и высотой поля вставки, которое вы хотите, и ограничитьTextView
верхнюю часть вставки до верхней части вставкиView
.Еще один подход состоит в том, чтобы наложить
TextView
верхнюю часть изображения на верхнююImageView
/ нижнюю / левую / правую границы и внести соответствующие изменения в поля / отступы. Преимущество продемонстрированного ниже подхода заключается в том, что отрицательная маржа может быть создана без больших вычислений. Это все, что говорит о том, что есть несколько подходов к этому.Обновление: быстрое обсуждение и демонстрация этого метода см. В сообщении блога Google Developers Medium .
Отрицательная маржа для
ConstraintLayout
XMLисточник
ImageView
сосредоточено на родителе,TextView
перекрывается вышеImageView
. ЗатемSpace
делает ошибку, когда приложение возвращается из фона. Я думаю, что 0dp, 0dp создают проблемы. А как насчет просто использованияGuideline
.Другой способ - использовать
translationX
илиtranslationY
вот так:это будет работать как
android:layout_marginRight="-25dp"
источник
Следуйте этим двум вопросам:
https://code.google.com/p/android/issues/detail?id=212499 https://code.google.com/p/android/issues/detail?id=234866
источник
Это то, что я понял после нескольких часов попыток найти решение.
Давайте рассмотрим два изображения: image1 и image2. Изображение2 должно быть помещено поверх изображения1, расположенного в правом нижнем углу.
Пример перекрывающихся видов
Мы можем использовать виджет Space для перекрытия просмотров.
Ограничьте четыре стороны виджета Space четырьмя сторонами изображения1 соответственно. В этом примере ограничьте левую сторону image2 правой стороной виджета Space, а верхнюю сторону image2 - нижней стороной виджета Space. Это свяжет image2 с виджетом Space, и, поскольку виджет Space ограничен со всех сторон, мы можем определить необходимое горизонтальное или вертикальное смещение, которое будет перемещать image2 по мере необходимости.
Кроме того, чтобы расположить image2 в центре-низу изображения1, мы можем ограничить левую и правую стороны изображения2 с помощью левой и правой сторон виджета Space соответственно. Точно так же мы можем разместить image2 где угодно, изменив ограничения image2 с помощью виджета Space.
источник
Я нашел способ сделать это намного проще.
В основном есть ImageView, затем в текстовом представлении добавьте верхнее ограничение, чтобы оно соответствовало верхнему ограничению изображения, и просто добавьте верхний край TextView для соответствия, чтобы добиться поведения типа поля -ve.
источник
Это поможет многим
В моем случае мне нужен такой дизайн:
Означает, что я хочу, чтобы мое изображение отображало половину их ширины, поэтому в основном мне нужен отрицательный запас в половину фактической ширины изображения, но весь мой макет в макете ограничений и макет ограничения не допускает отрицательного поля, поэтому я достиг этого с помощью кода ниже
Так что ImageView будет заканчиваться в начале руководства. и эффект такой же, как и при отрицательном поле в начале 50dp.
А также, если ширина вашего представления не фиксирована, а в процентах, чтобы вы могли разместить направляющую с процентами и достичь любого эффекта, который вы хотите
Удачного кодирования :)
источник
Вам нужно только использовать виджет Space в вашем макете
источник
Это старый вопрос, но его очень часто задают, самый быстрый способ добиться этого - ограничить верх и низ стороны представления, к которому вы хотите привязаться, например:
Это будет центрировать его в нижней строке обзора по горизонтали.
источник
Простой способ.
Я не уверен, что лучше всего.
Просто оберните с помощью LinearLayout
источник