Googleデザインライブラリの新しいFloatingActionButtonを使用していますが、奇妙なパディング/マージンの問題が発生しています。この画像(開発者レイアウトオプションがオン)は、API 22のものです。
API 17から。
これはXMLです
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentEnd="true"
Android:layout_gravity="bottom|right"
Android:layout_marginLeft="16dp"
Android:layout_marginRight="20dp"
Android:layout_marginTop="-32dp"
Android:src="@drawable/ic_action_add"
app:fabSize="normal"
app:elevation="4dp"
app:borderWidth="0dp"
Android:layout_below="@+id/header"/>
API 17のFABのパディング/マージンが非常に大きいのはなぜですか?
更新(2016年10月):
正しい解決策は、app:useCompatPadding="true"
をFloatingActionButtonに入れることです。これにより、異なるAPIバージョン間でパディングの一貫性が保たれます。ただし、これはまだデフォルトのマージンを少しオフにするようですので、それらを調整する必要があるかもしれません。ただし、少なくともAPI固有のスタイルは必要ありません。
前の回答:
これは、API固有のスタイルを使用して簡単に実現できます。通常のvalues/styles.xml
に、次のようなものを入れます。
<style name="floating_action_button">
<item name="Android:layout_marginLeft">0dp</item>
<item name="Android:layout_marginTop">0dp</item>
<item name="Android:layout_marginRight">8dp</item>
<item name="Android:layout_marginBottom">0dp</item>
</style>
そして、values-v21/styles.xmlの下で、これを使用します:
<style name="floating_action_button">
<item name="Android:layout_margin">16dp</item>
</style>
そして、FloatingActionButtonにスタイルを適用します。
<Android.support.design.widget.FloatingActionButton
...
style="@style/floating_action_button"
...
/>
他の人が指摘したように、API <20では、ボタンは独自の影をレンダリングし、ビューの全体的な論理幅を追加しますが、API> = 20では、ビューの幅に寄与しない新しいElevationパラメーターを使用します。
数回の検索とテストソリューションの後、私はこの行を私のXMLレイアウトにのみ追加することで私の問題を修正します:
app:elevation="0dp"
app:pressedTranslationZ="0dp"
これはフロートボタンの全体レイアウトです
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentBottom="true"
Android:layout_alignParentRight="true"
Android:layout_marginRight="16dp"
Android:layout_marginBottom="16dp"
Android:src="@drawable/ic_add"
app:elevation="0dp"
app:pressedTranslationZ="0dp"
app:fabSize="normal" />
Design Support Library内に問題があります。以下の方法を使用して、ライブラリが更新されるまでこの問題を修正します。このコードをアクティビティまたはフラグメントに追加して、問題を解決してください。 xmlを同じにしてください。 Lollipop以上ではマージンはありませんが、下では16dpのマージンがあります。
作業例の更新
XML-FABはRelativeLayout内にあります
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentBottom="true"
Android:layout_alignParentRight="true"
Android:layout_marginBottom="16dp"
Android:layout_marginRight="16dp"
Android:src="@mipmap/ic_add"
app:backgroundTint="@color/accent"
app:borderWidth="0dp"
app:elevation="4sp"/>
Java
FloatingActionButton mFab = (FloatingActionButton) v.findViewById(R.id.fab);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) mFab.getLayoutParams();
p.setMargins(0, 0, dpToPx(getActivity(), 8), 0); // get rid of margins since shadow area is now the margin
mFab.setLayoutParams(p);
}
Dpからpxへの変換
public static int dpToPx(Context context, float dp) {
// Reference http://stackoverflow.com/questions/8309354/formula-px-to-dp-dp-to-px-Android
float scale = context.getResources().getDisplayMetrics().density;
return (int) ((dp * scale) + 0.5f);
}
ロリポップ
Pre Lollipop
事前にLollipop FloatingActionButton
は独自の影を描画します。したがって、影用のスペースを確保するには、ビューを少し大きくする必要があります。一貫した動作を実現するために、高さと幅の違いを考慮してマージンを設定できます。現在、次の class を使用しています。
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.support.design.widget.FloatingActionButton;
import Android.util.AttributeSet;
import Android.view.ViewGroup.MarginLayoutParams;
import static Android.os.Build.VERSION.SDK_INT;
import static Android.os.Build.VERSION_CODES.Lollipop;
import static Android.support.design.R.styleable.FloatingActionButton;
import static Android.support.design.R.styleable.FloatingActionButton_fabSize;
import static Android.support.design.R.style.Widget_Design_FloatingActionButton;
import static Android.support.design.R.dimen.fab_size_normal;
import static Android.support.design.R.dimen.fab_size_mini;
public class CustomFloatingActionButton extends FloatingActionButton {
private int mSize;
public CustomFloatingActionButton(Context context) {
this(context, null);
}
public CustomFloatingActionButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, FloatingActionButton, defStyleAttr,
Widget_Design_FloatingActionButton);
this.mSize = a.getInt(FloatingActionButton_fabSize, 0);
a.recycle();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (SDK_INT < Lollipop) {
int size = this.getSizeDimension();
int offsetVertical = (h - size) / 2;
int offsetHorizontal = (w - size) / 2;
MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
params.leftMargin = params.leftMargin - offsetHorizontal;
params.rightMargin = params.rightMargin - offsetHorizontal;
params.topMargin = params.topMargin - offsetVertical;
params.bottomMargin = params.bottomMargin - offsetVertical;
setLayoutParams(params);
}
}
private final int getSizeDimension() {
switch (this.mSize) {
case 0: default: return this.getResources().getDimensionPixelSize(fab_size_normal);
case 1: return this.getResources().getDimensionPixelSize(fab_size_mini);
}
}
}
更新:Android Support Libraries v23はfab_size dimensの名前を次のように変更しました:
import static Android.support.design.R.dimen.design_fab_size_normal;
import static Android.support.design.R.dimen.design_fab_size_mini;
Markusの答え v23.1.0に更新し、インポートを調整した後(デザインライブラリのRではなくアプリRを使用する最近のgradleプラグインを使用)、私にとってはうまくいきました。 v23.1.0のコードは次のとおりです。
// Based on this answer: https://stackoverflow.com/a/30845164/1317564
public class CustomFloatingActionButton extends FloatingActionButton {
private int mSize;
public CustomFloatingActionButton(Context context) {
this(context, null);
}
public CustomFloatingActionButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@SuppressLint("PrivateResource")
public CustomFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.FloatingActionButton, defStyleAttr,
R.style.Widget_Design_FloatingActionButton);
mSize = a.getInt(R.styleable.FloatingActionButton_fabSize, 0);
a.recycle();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
int size = this.getSizeDimension();
int offsetVertical = (h - size) / 2;
int offsetHorizontal = (w - size) / 2;
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
params.leftMargin = params.leftMargin - offsetHorizontal;
params.rightMargin = params.rightMargin - offsetHorizontal;
params.topMargin = params.topMargin - offsetVertical;
params.bottomMargin = params.bottomMargin - offsetVertical;
setLayoutParams(params);
}
}
@SuppressLint("PrivateResource")
private int getSizeDimension() {
switch (mSize) {
case 1:
return getResources().getDimensionPixelSize(R.dimen.design_fab_size_mini);
case 0:
default:
return getResources().getDimensionPixelSize(R.dimen.design_fab_size_normal);
}
}
}
レイアウトファイルでは、属性の標高を0に設定します。デフォルトの標高を使用するためです。
app:elevation="0dp"
アクティビティで21を超えるapiレベルをチェックし、必要に応じて高度を設定します。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
fabBtn.setElevation(10.0f);
}