programing

Android Design Library - 부동 동작 버튼 패딩/마진 이슈

jooyons 2023. 10. 2. 15:00
반응형

Android Design Library - 부동 동작 버튼 패딩/마진 이슈

Google 디자인 라이브러리의 새로운 FloatingActionButton을 사용하고 있는데 이상한 패딩/마진 문제가 발생하고 있습니다.(개발자 레이아웃 옵션이 켜져 있는) 이 이미지는 API 22에서 가져온 것입니다.

enter image description here

그리고 API 17에서.

enter image description here

이것은 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"이동 액션 버튼으로 이동합니다.이렇게 하면 서로 다른 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>

그리고 해당 스타일을 Floating Action Button에 적용합니다.

<android.support.design.widget.FloatingActionButton
...
style="@style/floating_action_button"
...
/>

다른 사람들이 언급한 바와 같이 API <20에서 버튼은 뷰의 전체 논리적 너비를 추가하는 자신의 그림자를 렌더링하는 반면 API >=20에서는 뷰 너비에 기여하지 않는 새로운 Elevation 매개변수를 사용합니다.

더 이상 만지작거리지 마.styles.xml아니면 같이.java파일. 간단하게 해드릴게요.

사용가능app:useCompatPadding="true"사용자 지정 마진을 제거하여 다양한 버전의 안드로이드에서 동일한 마진을 유지할 수 있습니다.

두 번째 사진에서 FAB에 표시된 추가 마진/패딩은 막대사탕 이전 장치의 이 호환성 패딩 때문입니다.이 속성을 설정하지 않으면 사전 롤팝 장치에서 적용되고 롤팝+ 장치에서는 적용되지 않습니다.

android studio code

개념증명

design view

몇 시간 동안 검색하고 솔루션을 테스트한 후 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가 상대 레이아웃 내에 있음

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

막대사탕

enter image description here

롤리팝 전

enter image description here

에.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 dimenses로 이름 변경:

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으로 업데이트하고 Import에 대해 약간의 수정을 한 후(최근 gradle plugin에서는 디자인 라이브러리의 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"

이제 활동에서 21보다 큰 API 레벨을 확인하고 필요한 경우 고도를 설정합니다.

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

반응형