Androidで負のマージンを使用することは悪い習慣ですか?


114

負のマージンのデモ:

                         ここに画像の説明を入力してください

シナリオ

別のビューの境界ボックスに侵入するように、ビューの1つに負のマージンを設定してビューを重ねます。

考え

必要に応じて、レイアウトのオーバーラップで期待どおりに機能するようです。しかし、私が無意識のうちに正しく機能していないために、より大きな問題に遭遇したくありません。エミュレーター、物理デバイス、という名前を付けます。負のマージンを使用すると、すべてが正しく機能しているように見えます。あるビューが別のビューの境界ボックスに侵入し、レイアウトでの宣言方法に応じて、他のビューの上または下になります。

API 21以降、translationZおよびelevation 属性を設定してビューを他のビューの上または下に表示できることも知っていますが、私の懸念は基本的に、属性のドキュメントlayout_marginマージン値が正であることを明確に指定されているという事実から来ています。私の引用:

抜粋:
このビューの左側、上部、右側、下部に追加のスペースを指定します。このスペースは、このビューの境界外です。マージン値は正でなければなりません。「14.5sp」などの単位が追加された浮動小数点数であるディメンション値である必要があります。使用可能な単位は次のとおりです:px(ピクセル)、dp(密度非依存ピクセル)、sp(優先フォントサイズに基づいてスケーリングされたピクセル)、in(インチ)、mm(ミリメートル)...

最初にこの質問をして以来、私は負のマージンに関する問題を抱えていませんでしたが、可能な限りそれらを使用しないように努めましたが、問題発生しなかったため、ドキュメントには、私もそうではありませんそれについて心配しました。


1
エスプレッソテストでは、マージンの1つが負の値の場合、オブジェクトを表示できないことを知っています...そのため、それらを使用しない理由
Tim Boland

回答:


192

2010年、@ RomainGuy(コアAndroidエンジニア)は、 負のマージンには不特定の動作があった

2011年、@ RomainGuyは、 LinearLayoutおよびで負のマージンを使用できるRelativeLayout

2016年、@ RomainGuyは、 これらは公式にはサポートされたことはなく、今後もサポートされない予定ConstraintLayoutです。

ただし、この制限を回避するのは簡単です。

ベースビューの下部にヘルパービュー(高さ0 dp、幅は親に制限)を追加し、下部に必要なマージンを追加します。
次に、ビューをこのビューの下に配置し、サポートされていない負の値を使用せずに、「負の」マージンを効果的に許可します。


1
その場合、害のないものであるように見えます。誰か他の洞察がある場合に備えて、オープンのままに
フアンコルテス

1
@DrewLeSueur:私はその仮定をしません。私は負のパディングが何を意味するかさえわからない。
CommonsWare 2013年

1
?。。私は、呼び出しが値ではなく、負のヘルプを宣言したい@ DIMEN / anyvalue」 - @CommonsWareは、あなたはそれが`そのような可能性何かで、私に言うことができる
deadfish

2
@ 100kg:すみませんが、それはサポートされていません。
CommonsWare 2013

21
Android 4.4 KitKatでは、負のマージンに関して(4.3と比較して、少なくともAsus Nexus 7では)何かが変更されていることに気付きました。あなた判明が必要android:clipChildren="false"android:clipToPadding="false"あなたが以前になかった、またはどこ物事はこのように破ります
Jonik

18

これが誰かを助けることを願っています。ConstraintLayout@CommonsWareの回答に基づいて使用するサンプルコードを次に示します。

ベースビューの下部にヘルパービュー(高さ0 dp、幅は親に制限)を追加し、下部に必要なマージンを追加します。次に、ビューをこのビューの下に配置し、サポートされていない負の値を使用せずに、「負の」マージンを効果的に許可します。

サンプルコード:

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

出力:

ここに画像の説明を入力してください


16

負のマージンを使用する場合は、コンテナとそのclipToPaddingに十分なパディングをfalseに設定し、そのに負のマージンを設定して、子ビューをクリップしないようにします。


4

これまでは悪い習慣だったかもしれませんが、マテリアルデザインとそのフローティングアクションボタンを使用すると、避けられず、多くの場合に必要になるようです。基本的に、2つの個別のレイアウトがあり、1つのRelativeLayoutに入れることができない場合、それらは明確に別々の処理が必要なため(たとえば、ヘッダーとコンテンツを考える)、FABをオーバーラップする唯一の方法は、1つのレイアウトから突き出すことです負のマージンを使用したレイアウト。そして、これはクリック可能な領域に追加の問題を引き起こします。


3

私にとって、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にのみ影響するという2番目の奇妙なことなので、私の新しいルールは常に 4.0.3エミュレータでテストすることです。

私はandroid:lineSpacingExtra="-2dp"たまたま持っていても機能するTextViewを使用して、TextViewの下部マージンを減らすことに成功しましたandroid:singleLine="true"(したがって、行間隔が要因になるとは思っていませんでした)。


1
Nexus 4(xhdpi)と4.2.2でも同様の動作が見つかりました。親レイアウトにパディングがありましたが、パディングのないレイアウトがありました。内部に負のmarginTopを持つTextViewがありました。5.0では問題なく動作しました。デバイスとNexus 4のエミュレーターの両方で4.2.2に表示されなくなります。解決策は、TextViewを含むレイアウトにパディングを移動することでした。
louielouie 2014

3

いいえ、使用しないでくださいnegative margin。代わりに使用する必要がありますtranslate。負のマージンが機能する場合でも、プログラムでレイアウトを変更する場合は、翻訳が役立ちます。また、マージンを使用すると、ビューが画面からオーバーフローすることはありません。


0

私はそれがかなり短い期間で可能だったことを知っています。しかし、私はそれに問題がないと思います。画面のサイズなどに注意して、画面に重なって表示されるべきでないアイテムを誤って作成しないようにしてください。(つまり、テキストの上にテキストを置くことは、おそらく悪い考えです。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.