Programing

배경 Drawable을 설정할 때 패딩은 어디에 있습니까?

crosscheck 2020. 10. 8. 07:43
반응형

배경 Drawable을 설정할 때 패딩은 어디에 있습니까?


나는 내 EditTextButton에이 문제 가 있는데, 텍스트에서 멀리 떨어져있는 좋은 패딩이 있지만 배경을 변경 setBackgroundDrawable하거나 setBackgroundResource패딩이 영원히 손실됩니다.


내가 찾은 것은 배경 리소스로 9 패치를 추가하여 패딩을 재설정하는 것입니다. 흥미롭게도 색상이나 9가 아닌 패치 이미지를 추가하면 그렇지 않았습니다. 해결책은 배경이 추가되기 전에 패딩 값을 저장 한 다음 나중에 다시 설정하는 것입니다.

private EditText value = (EditText) findViewById(R.id.value);

int pL = value.getPaddingLeft();
int pT = value.getPaddingTop();
int pR = value.getPaddingRight();
int pB = value.getPaddingBottom();

value.setBackgroundResource(R.drawable.bkg);
value.setPadding(pL, pT, pR, pB);

다른 레이아웃,이 경우에는 FrameLayout. FrameLayout이를 통해 포함 된에있는 패딩을 파괴하지 않고 의 배경을 변경할 수 있었습니다 RelativeLayout.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/commentCell"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:background="@drawable/comment_cell_bg_single" >

    <RelativeLayout android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:padding="20dp" >

    <ImageView android:id="@+id/sourcePic"
               android:layout_height="75dp"
               android:layout_width="75dp"
               android:padding="5dp"
               android:background="@drawable/photoframe" 
     />
...

다른 옵션은 Drawable위에서 제안한대로 배경 설정 한 후 프로그래밍 방식으로 설정하는 것 입니다. 픽셀을 계산하여 장치의 해상도를 수정하십시오.


TextView에서이 문제가 발생했기 때문에 TextView를 서브 클래 싱하고 메서드의 Override 메서드를 만들었습니다 TextView.setBackgroundResource(int resid). 이렇게 :

@Override
public void setBackgroundResource(int resid) {
    int pl = getPaddingLeft();
    int pt = getPaddingTop();
    int pr = getPaddingRight();
    int pb = getPaddingBottom();

    super.setBackgroundResource(resid);

    this.setPadding(pl, pt, pr, pb);
}

이런 식으로 리소스를 설정하기 전에 항목의 패딩을 가져 오지만 패딩을 유지하는 것 외에는 메서드의 원래 기능을 실제로 엉망으로 만들지 않습니다.


이 슈퍼를 철저히 테스트하지는 않았지만이 방법이 유용 할 수 있습니다.

    /**
 * Sets the background for a view while preserving its current padding. If the background drawable
 * has its own padding, that padding will be added to the current padding.
 * 
 * @param view View to receive the new background.
 * @param backgroundDrawable Drawable to set as new background.
 */
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) {
    Rect drawablePadding = new Rect();
    backgroundDrawable.getPadding(drawablePadding);
    int top = view.getPaddingTop() + drawablePadding.top;
    int left = view.getPaddingLeft() + drawablePadding.left;
    int right = view.getPaddingRight() + drawablePadding.right;
    int bottom = view.getPaddingBottom() + drawablePadding.bottom;

    view.setBackgroundDrawable(backgroundDrawable);
    view.setPadding(left, top, right, bottom);
}

view.setBackgroundDrawable (Drawable) 대신 이것을 사용하십시오.


cottonBallPaws의 대답의 역 호환 버전

/** 
  * Sets the background for a view while preserving its current     padding. If the background drawable 
  * has its own padding, that padding will be added to the current padding. 
 *  
 * @param view View to receive the new background. 
 * @param backgroundDrawable Drawable to set as new background. 
 */ 
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressWarnings("deprecation")
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) {
    Rect drawablePadding = new Rect();
    backgroundDrawable.getPadding(drawablePadding);
    int top = view.getPaddingTop() + drawablePadding.top;
    int left = view.getPaddingLeft() + drawablePadding.left;
    int right = view.getPaddingRight() + drawablePadding.right;
    int bottom = view.getPaddingBottom() + drawablePadding.bottom;

    int sdk = android.os.Build.VERSION.SDK_INT;
    if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        view.setBackgroundDrawable(backgroundDrawable);
    } else {
        view.setBackground(backgroundDrawable);
    }
    view.setPadding(left, top, right, bottom);
}

일반 검색 자에게는

setBackgroudDrawable 다음에 setPadding을 추가하기 만하면됩니다. 드로어 블을 변경할 때 setPadding을 다시 호출해야합니다.

처럼:

view.setBackgroundDrawable(backgroundDrawable);
view.setPadding(x, x, x, x);

가장 깨끗한 방법은 drawable-image-file을 가리키는 xml-drawable 내부에 패딩을 정의하는 것입니다.

Greatings


내 솔루션은 뷰 (내 경우 EditText )와 재정의 setBackgroundDrawable()setBackgroundResource()메서드 를 확장하는 것이 었습니다 .

// Stores padding to avoid padding removed on background change issue
public void storePadding(){
    mPaddingLeft = getPaddingLeft();
    mPaddingBottom = getPaddingTop();
    mPaddingRight = getPaddingRight();
    mPaddingTop = getPaddingBottom();
}

// Restores padding to avoid padding removed on background change issue
private void restorePadding() {
    this.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
}

@Override
public void setBackgroundResource(@DrawableRes int resId) {
    storePadding();
    super.setBackgroundResource(resId);
    restorePadding();
}

@Override
public void setBackgroundDrawable(Drawable background) {
    storePadding();
    super.setBackgroundDrawable(background);
    restorePadding();
}

9 패치 이미지를 사용하고 드로어 블에서 콘텐츠 영역을 정의하여 약간의 패딩을 제공 할 수 있습니다. 이것을 확인하십시오

xml 또는 프로그래밍 방식으로 레이아웃의 패딩을 설정할 수도 있습니다.

xml 패딩 태그

android:padding
android:paddingLeft
android:paddingRight
android:paddingTop
android:paddingBottom

EditText 또는 Button 뷰에서 setPadding을 호출하여 setBackgroundDrawable을 호출 한 후 코드에서 수동으로 패딩을 설정할 수 있습니다.


이 컴파일 'com.android.support:appcompat-v7:22.1.0'과 같이 android studio에서 lib를 v7 : 22.1.0으로 변경하십시오.


대부분의 답변은 정확하지만 배경 설정을 올바르게 처리해야합니다.

먼저 뷰의 패딩을 가져옵니다.

//Here my view has the same padding in all directions so I need to get just 1 padding
int padding = myView.getPaddingTop();

Then set the background

//If your are supporting lower OS versions make sure to verify the version
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
    //getDrawable was deprecated so use ContextCompat                            
    myView.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.bg_accent_underlined_white));
} else {
    myView.setBackground(ContextCompat.getDrawable(context, R.drawable.bg_accent_underlined_white));
}

Then set the padding the view had before the background change

myView.setPadding(padding, padding, padding, padding);

I found another solution. I was facing the similar problem with Buttons. Eventually, i added:

android:scaleX= "0.85"
android:scaleY= "0.85"

it worked for me. The default padding is almost the same.


Combining the solutions of all, I wrote one in Kotlin:

fun View.setViewBackgroundWithoutResettingPadding(@DrawableRes backgroundResId: Int) {
    val paddingBottom = this.paddingBottom
    val paddingStart = ViewCompat.getPaddingStart(this)
    val paddingEnd = ViewCompat.getPaddingEnd(this)
    val paddingTop = this.paddingTop
    setBackgroundResource(backgroundResId)
    ViewCompat.setPaddingRelative(this, paddingStart, paddingTop, paddingEnd, paddingBottom)
}

fun View.setViewBackgroundWithoutResettingPadding(background: Drawable?) {
    val paddingBottom = this.paddingBottom
    val paddingStart = ViewCompat.getPaddingStart(this)
    val paddingEnd = ViewCompat.getPaddingEnd(this)
    val paddingTop = this.paddingTop
    ViewCompat.setBackground(this, background)
    ViewCompat.setPaddingRelative(this, paddingStart, paddingTop, paddingEnd, paddingBottom)
}

Here an improved version of cottonBallPaws' setBackgroundAndKeepPadding. This maintains the padding even if you call the method multiple times:

/**
 * Sets the background for a view while preserving its current padding. If the background drawable
 * has its own padding, that padding will be added to the current padding.
 */
public static void setBackgroundAndKeepPadding(View view, Drawable backgroundDrawable) {

    Rect drawablePadding = new Rect();
    backgroundDrawable.getPadding(drawablePadding);

    // Add background padding to view padding and subtract any previous background padding
    Rect prevBackgroundPadding = (Rect) view.getTag(R.id.prev_background_padding);
    int left = view.getPaddingLeft() + drawablePadding.left -
            (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.left);
    int top = view.getPaddingTop() + drawablePadding.top -
            (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.top);
    int right = view.getPaddingRight() + drawablePadding.right -
            (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.right);
    int bottom = view.getPaddingBottom() + drawablePadding.bottom -
            (prevBackgroundPadding == null ? 0 : prevBackgroundPadding.bottom);
    view.setTag(R.id.prev_background_padding, drawablePadding);

    view.setBackgroundDrawable(backgroundDrawable);
    view.setPadding(left, top, right, bottom);
}

You need to define a resource id via values/ids.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="prev_background_padding" type="id"/>
</resources>

I use this pretty easy workaround I define a accentColor in my style.xml like below

<item name="colorAccent">#0288D1</item>

and then I use the either of following styles in my Button tags

style="@style/Base.Widget.AppCompat.Button.Colored"
style="@style/Base.Widget.AppCompat.Button.Small"

for Example :

<Button
    android:id="@+id/btnLink"
    style="@style/Base.Widget.AppCompat.Button.Colored"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tvDescription"
    android:textColor="@color/textColorPrimary"
    android:text="Visit Website" />

<Button
    android:id="@+id/btnSave"
    style="@style/Base.Widget.AppCompat.Button.Small"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tvDescription"
    android:layout_toRightOf="@id/btnLink"
    android:textColor="@color/textColorPrimaryInverse"
    android:text="Save" />

참고URL : https://stackoverflow.com/questions/10095196/whered-padding-go-when-setting-background-drawable

반응형