Это плохая практика использовать отрицательные поля в Android?

Demo of negative margin:

& # XA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0; & # xA0;enter image description here

The scenario

Перекрывающиеся виды путем установки отрицательного поля для одного из них, чтобы оно охватывало ограничивающую рамку другого вида.

Thoughts

Кажется, это работает так, как вы ожидаете, с перекрытием макетов, если они должны. Но я не хочу сталкиваться с более серьезной проблемой из-за того, что по незнанию не делает все правильно. Эмуляторы, физические устройства, вы называете это, когда вы используете отрицательные поля, кажется, что все работает правильно, одно представление пересекает границу другого представления, и в зависимости от того, как оно объявлено в макете, оно будет выше или ниже другого представления.

Я также знаю, что с API 21 мы можем установитьtranslationZ а такжеelevation  атрибуты для отображения вид выше или ниже других видов, ноmy concern в основном исходит из того, чтов документации дляlayout_margin атрибуты четко определены, чтоmargin values should be positiveПозвольте мне процитировать:

Excerpt:
Specifies extra space on the left, top, right and bottom sides of this view. This space is outside this view's bounds. Margin values should be positive. Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters)...

За годы, прошедшие с тех пор, как я изначально задавал этот вопрос, у меня не было проблем с отрицательной маржой, я старался избегать их максимально возможного использования, но сделалnot возникнут какие-либо проблемы, поэтому, хотя в документации указано, что я не слишком беспокоюсь об этом.

Ответы на вопрос(7)

negative margin, вместо этого вы должны использоватьtranslate, Даже если отрицательное поле сработает когда-нибудь, когда вы изменяете макет программно, перевод поможет. И представление не может переполнять экран, если вы используете поле.

если вы хотите использовать отрицательное поле, установите достаточно заполнения для контейнера и егоclipToPadding в false и установите отрицательное поле для его дочерних элементов, чтобы оно не ограничивало дочерний вид!

но с Material Design и его плавающими кнопками действий, это кажется неизбежным и требуется во многих случаях сейчас. По сути, когда у вас есть два отдельных макета, которые вы не можете поместить в один RelativeLayout, потому что они нуждаются в отчетливо отдельной обработке (например, в заголовке и содержимом), единственный способ перекрыть FAB - это заставить его выделиться из одного из них. макеты с использованием отрицательных полей. И это создает дополнительные проблемы с интерактивными областями.

 17 дек. 2014 г., 21:55
Я обнаружил похожее поведение на Nexus 4 (то есть xhdpi) и 4.2.2. Был макет без отступов, хотя родительский макет имел отступы. Внутри был TextView с отрицательным значением marginTop. На 5.0 все работало нормально. На 4.2.2 как на устройстве, так и в эмуляторе для Nexus 4 он исчезает. Решением было перенести отступ в макет, содержащий TextView.
Решение Вопроса

отрицательные поля имели неопределенное поведение.

В 2011 году @RomainGuy заявил, чтоВы можете использовать отрицательные поля наLinearLayout and RelativeLayout.

В 2016 году @RomainGuy заявил, чтоони никогда не были официально поддержаны и не будут поддерживатьсяConstraintLayout.

Однако обойти это ограничение легко.

Добавьте вспомогательный вид (высота 0dp, ширина ограничена родителем) внизу базового вида, внизу добавьте желаемое поле.
Затем поместите ваше представление под этим, чтобы оно имело «отрицательный» результат. маржа, но без необходимости использовать любое неподдерживаемое отрицательное значение.

 06 дек. 2013 г., 17:09
Я заметил, что вAndroid 4.4 KitKat, кое-что изменилось в отношении отрицательных полей (по сравнению с 4.3; по крайней мере, на Asus Nexus 7). Оказывается, вам нужноandroid:clipChildren="false" а такжеandroid:clipToPadding="false" где вы ранее не делали илиthings break like this.
 21 янв. 2013 г., 22:59
@DrewLeSueur: я бы не сделал этого предположения. Я понятия не имею, что будет означать отрицательный отступ.
 08 апр. 2013 г., 16:48
@ 100 кг: извините, но это не поддерживается.
 Juan Cortés20 мая 2012 г., 15:17
Кажется, что это безопасная вещь, оставляя открытым, если у кого-то есть другие идеи
 08 апр. 2013 г., 16:45
@CommonsWare вы можете сказать мне, возможно ли сделать что-то подобное `- @ измерения / anyvalue & quot; ? Я хочу назвать объявленное значение, но отрицательное. Помогите.

это кому-нибудь поможет. Вот рабочий пример кода с использованиемConstraintLayout на основе ответа @ CommonsWare:

Add an helper view (height 0dp, width constrained to parent) at the bottom of your base view, at the bottom add the margin you want. Then position your view below this one, effectively allowing it to have a "negative" margin but without having to use any unsupported negative value.

Sample code:

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

Output:

enter image description here

что это было возможно в течение довольно короткого периода времени. Но я не вижу проблем с этим. Просто помните о размерах экрана и тому подобном, чтобы вы случайно не попали к элементам, которые не должны отображаться на экране. (т.е. текст поверх текста, скорее всего, плохая идея.)

что касается установки отрицательного поля в TextView (я понимаю, что OP относится к ViewGroup, но я искал проблемы с установкой отрицательных полей, и я приземлился здесь) ... Я нашел проблему с 4.0.3 ( API 15) ТОЛЬКО и настройкаandroid:layout_marginTop или жеandroid:layout_marginBottom к отрицательному значению, такому как -2dp.

По какой-то причине TextView не отображается, лежит вообще. Похоже, что "ушел" с точки зрения (не просто невидимый).

Когда я попробовал это с другими 3 версиями layout_margin, я не увидел проблему.

Обратите внимание, что я не пробовал это на реальном устройстве, это использует эмулятор 4.0.3. Это вторая странная вещь, которую я обнаружил, которая затрагивает только 4.0.3, поэтому мое новое правило заключается вalways тест с эмулятором 4.0.3 :)

У меня есть успех с уменьшением нижнего поля TextView с помощьюandroid:lineSpacingExtra="-2dp" который работает, хотя у меня случаетсяandroid:singleLine="true" (и поэтому я бы не подумал, что межстрочный интервал будет фактором).

 17 дек. 2014 г., 21:55
Я обнаружил похожее поведение на Nexus 4 (то есть xhdpi) и 4.2.2. Был макет без отступов, хотя родительский макет имел отступы. Внутри был TextView с отрицательным значением marginTop. На 5.0 все работало нормально. На 4.2.2 как на устройстве, так и в эмуляторе для Nexus 4 он исчезает. Решением было перенести отступ в макет, содержащий TextView.

Ваш ответ на вопрос