Programing

Android 디자인 라이브러리-부동 작업 버튼 패딩 / 여백 문제

crosscheck 2020. 8. 5. 07:49
반응형

Android 디자인 라이브러리-부동 작업 버튼 패딩 / 여백 문제


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에서는 뷰 폭에 영향을 미치지 않는 새로운 고도 매개 변수를 사용합니다.


더 이상 파일을 다루styles.xml 거나 다루지 않아도 됩니다 .java. 간단하게하겠습니다.

다양한 버전의 Android에서 동일한 여백app:useCompatPadding="true" 을 유지하기 위해 사용자 정의 여백을 사용 하고 제거 할 수 있습니다

당신이 당신의 두 번째 그림에 FAB에서 본 여분의 여백 / 패딩으로 인해이이다 compatPadding사전 롤리팝 장치. 이 속성을 설정하지 않으면 롤리팝 사전 장치에는 적용 되고 롤리팝 + 장치에는 적용 되지 않습니다 .

안드로이드 스튜디오 코드

개념의 증거

디자인 뷰


몇 시간 동안 검색 및 테스트 솔루션 후이 줄을 내 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" />

디자인 지원 라이브러리에 문제가 있습니다. 라이브러리가 업데이트 될 때까지 아래 방법을 사용하여이 문제를 해결하십시오. 이 코드를 활동 또는 조각에 추가하여 문제를 해결하십시오. XML을 동일하게 유지하십시오. 롤리팝 이상에서는 여백이 없지만 아래에는 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"/>

자바

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);
}

사탕 과자

여기에 이미지 설명을 입력하십시오

프리 롤리팝

여기에 이미지 설명을 입력하십시오


Lollipop 이전 FloatingActionButton에는 자체 그림자를 그립니다. 따라서 그림자를위한 공간을 확보하려면보기가 약간 커야합니다. 일관된 동작을 얻으려면 높이와 너비의 차이를 고려하여 여백을 설정할 수 있습니다. 현재 다음 클래스를 사용하고 있습니다 .

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으로 업데이트하고 가져 오기를 조정 한 후 나에게 잘 작동했습니다 (최근 gradle 플러그인을 사용하면 디자인 라이브러리의 R 대신 앱 R을 사용합니다). 다음은 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"

이제 활동에서 API 레벨이 21보다 큰지 확인하고 필요한 경우 고도를 설정하십시오.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    fabBtn.setElevation(10.0f);
}

참고 URL : https://stackoverflow.com/questions/30687888/android-design-library-floating-action-button-padding-margin-issues

반응형