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);
}
'Programing' 카테고리의 다른 글
Java에서 동일한 catch 블록에서 두 가지 예외를 잡을 수 있습니까? (0) | 2020.08.05 |
---|---|
C #의 System.Threading.Timer가 작동하지 않는 것 같습니다. (0) | 2020.08.05 |
리눅스 쉘 스크립트에서 메일 보내기 (0) | 2020.08.05 |
sklearn에서 가져 오기에서 ImportError : 이름 check_build를 가져올 수 없습니다 (0) | 2020.08.05 |
printf ()를 사용하여 인쇄 할 문자열의 문자 수를 지정하는 방법이 있습니까? (0) | 2020.08.05 |