बैकग्राउंड ड्रॉबल सेट करते समय, पेडिंग कहां जाएगी?


86

मेरे पास मेरे EditTextऔर Buttonविचारों पर यह मुद्दा है , जहां मेरे पास पाठ से दूर जाने के लिए उनके लिए एक अच्छी गद्दी है, लेकिन जब मैं पृष्ठभूमि को बदल देता हूं setBackgroundDrawableया setBackgroundResourceउस गद्दी को हमेशा के लिए खो दिया जाता है।


2
यह मुद्दा एंड्रॉइड 4.4 किटकैट
— व्लादिमीर

2
4.4.3 के साथ मेरे Nexus 5 पर यह मुद्दा अभी भी चल रहा है।
— बजे बियांका दानिशुक

1
मेरा मानना ​​है कि यह केवल लॉलीपॉप (5.0)
— अवीव बेन शाबट

मुझे उसी तरह की समस्या हो रही थी TextViewऔर नीचे दिए गए समाधान ने भी उस प्रकार के दृश्य के लिए काम किया।
— Stonz2

एक पर समस्या हो रही TextViewहै और साथ ही एपीआई 28 पर (एंड्रॉयड 9)। लगता है, यह कभी तय नहीं था।
— षड्गेशमी

जवाबों:


97

जो मैंने पाया वह एक 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);

इस दृष्टिकोण का उपयोग करते हुए कुछ समस्याओं में भाग लेने वालों के लिए, गेटपैडिंग को कॉल करना सुनिश्चित करें ... पहले से सेटबैकग्राउंडResource () पर कॉल करें।
— क्रिस .Zou

ऐसा लगता है कि इस तरह से ड्रॉइंग पैडिंग नहीं रहेगी?
— थुय त्रिनह

4
मैं यह उल्लेख करना चाहूंगा कि आपने एपीआई 19 (किटकैट) से ऊपर ऐसा नहीं किया है क्योंकि Google ने इस बग को हल कर दिया है।
— ywwynm

@ywynm ऊपर या किटकैट के बराबर है?
— हेंड्रीडब्ल्यूडी

ठीक है, मैंने इसे स्वयं आज़माया है, हमें एपीआई 19 (किटकैट) या उच्चतर (> = किटकैट) के लिए इसका उपयोग करने की आवश्यकता नहीं है
— HendraWD

14

मैं तत्व को दूसरे लेआउट के अंदर लपेटने में सक्षम था, इस मामले में, ए 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रूप से सेट करना है जैसा कि ऊपर बताया गया है। डिवाइस के रिज़ॉल्यूशन के लिए सही करने के लिए बस पिक्सल की गणना करना सुनिश्चित करें।


12

मुझे TextView में यह समस्या थी, इसलिए मैंने TextView को उप-वर्गित किया और विधि का ओवरराइड विधि बना दिया 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);
}

इस तरह, यह संसाधन सेट करने से पहले आइटम की गद्दी प्राप्त कर लेता है, लेकिन वास्तव में विधि की मूल कार्यक्षमता के साथ खिलवाड़ करने के अलावा अन्य कोई गड़बड़ नहीं करता है।


9

इस सुपर का पूरी तरह से परीक्षण नहीं किया गया है, लेकिन यह विधि उपयोग की हो सकती है:

    /**
 * 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) के बजाय इसका उपयोग करें।


3
यदि दृश्य में पहले से ही कुछ ओर पैडिंग है, तो इस फ़ंक्शन को कई बार कॉल करने के बाद, पृष्ठभूमि छवि पक्ष में आ जाती है, क्योंकि आप पिछले मूल्य के साथ पैडिंग देखें
— iBog

हाँ अगर पैडिंग को कई बार बदला जा रहा है तो आप एक अलग तरीका अपनाना चाहेंगे। संभवतः ड्रॉबल पैडिंग बनाम मूल पैडिंग का ट्रैक रखें।
— कपासबैलपॉज

2

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

1

आप 9-पैच छवियों का उपयोग करके और ड्रॉबल में सामग्री क्षेत्र को परिभाषित करके कुछ पैडिंग दे सकते हैं। इसे देखो

आप अपने लेआउट में xml या प्रोग्राम से पैडिंग भी सेट कर सकते हैं

xml पैडिंग टैग

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

आप कोड को मैन्युअल रूप से सेट करने की कोशिश कर सकते हैं कोड से कॉल करने के बाद आप अपने एडिट टेक्स्ट या बटन व्यू पर सेटपैडिंग को कॉल करके बैकग्राउंडड्राएबल को कॉल कर सकते हैं।


मेरे पास XML में EditText और Button के लिए पैडिंग परिभाषित है, और यह बहुत अच्छा दिखाता है, जब तक कि मैं ड्राबल को नहीं बदलता, तब तक मैं पैडिंग खो देता हूं।
— डांड्रे एलीसन

यह आपके पिछले और नए ड्राॅब के बीच सामग्री क्षेत्रों में परिवर्तन के आधार पर बदल सकता है। क्या आपने पैडिंग बढ़ाने की कोशिश की और देखा कि यह कोई पैडिंग दे रहा है या नहीं।
— एची

1
ओके सॉरी मुझे आपका सवाल पूरी तरह से पढ़ना चाहिए था। चूँकि आप पृष्ठभूमि को बदल रहे हैं, इसलिए यह गद्दी को हटा सकता है। मुझे यकीन नहीं है कि यह मामला है। लेकिन अगर ऐसा है तो आप कोड से मैन्युअल रूप से पैडिंग सेट करने की कोशिश कर सकते हैं, क्योंकि आपके एडिट टेक्स्ट या बटन व्यू पर सेटपैडिंग करके सेटबैकग्राउंडड्राएबल को कॉल करें
— achie

1

सामान्य खोजकर्ता के लिए,

बस सेटपैकिंग जोड़ें के बाद setBackgroudDrawable। जब आप अपने ड्रॉबल को बदलते हैं, तो आपको फिर से सेटपैडिंग को कॉल करना होगा।

पसंद:

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

सबसे साफ तरीका एक xml-drawable के अंदर आपकी पैडिंग को परिभाषित करता है जो कि drawable-image-file की ओर इशारा करता है

Greatings


1

मेरा समाधान दृश्य का विस्तार करना था (मेरे मामले में एक 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();
}

1

सभी के समाधानों को मिलाकर, मैंने कोटलिन में एक लिखा:

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

1

बस समझाने के लिए कि क्या हो रहा है:

यह वास्तव में एक विशेषता है। लेआउट ड्रॉबल्स जिसका आप पृष्ठभूमि के रूप में उपयोग कर सकते हैं, एक पैडिंग को इस तरह परिभाषित कर सकते हैं:

<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:paddingRight="8dp"
    >
    ...
</layer-list>

यह पैडिंग नई ड्रॉबल बैकग्राउंड के साथ सेट की जाएगी। जब कोई पैडिंग नहीं होती है, तो डिफ़ॉल्ट मान 0 होता है।

रोमेन गाइ द्वारा लिखे गए ईमेल से अधिक जानकारी: https://www.mail-archive.com/android-developers@googlegroups.com/msg09595.html


0

v7: 22.1.0 को एंड्रॉइड स्टूडियो में इस संकलन की तरह बदलें। com.android.support:appcompat-v7:22.1.0


0

अधिकांश उत्तर सही हैं लेकिन पृष्ठभूमि सेटिंग को सही ढंग से संभालना चाहिए।

पहले अपने विचार की पैडिंग प्राप्त करें

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

फिर बैकग्राउंड सेट करें

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

फिर पृष्ठभूमि बदलने से पहले दृश्य को पैडिंग सेट करें

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

0

मुझे एक और उपाय मिला। मैं बटन के साथ इसी तरह की समस्या का सामना कर रहा था। आखिरकार, मैंने जोड़ा:

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

यह मेरे लिए काम किया। डिफ़ॉल्ट पैडिंग लगभग समान है।


0

मेरे मामले में मेरे पास एक ड्रॉबल था और इतना बेवकूफ था कि मैंने नहीं देखा कि पैडिंग्स xml में 0 पर सेट थे।


-1

यहां कॉटनबेलपॉव के सेटबेकग्राउंडएंडकेपपैडिंग का एक उन्नत संस्करण है। यदि आप विधि को कई बार कॉल करते हैं तो भी यह पैडिंग बनाए रखता है:

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

आपको मान / ids.xml के माध्यम से संसाधन आईडी को परिभाषित करने की आवश्यकता है:

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

-1

मैं इस बहुत आसान वर्कअराउंड का उपयोग करता हूं जिसे मैं नीचे accentColorअपनी style.xmlतरह से परिभाषित करता हूं

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

और फिर मैं अपने Buttonटैग में निम्नलिखित शैलियों का उपयोग करता हूं

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

उदाहरण के लिए :

<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" />

यह सवाल से संबंधित नहीं है।
— Miha_x64
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.