问题描述:

I am using the 9Patch drawable shown below as the background for buttons.

When the buttons are drawn they do not appear to be using the padding as defined in the 9Patch by default.

I have searched and found others have had the same problem. It is suggested that the issue is that the default button style overrides the padding defined in the 9Patch. One user solved the issue by setting android:padding="@null" in their XML.

I however, need to achieve the same programmatically instead of in XML.

In my test app below I have tried numerous things to get the buttons to reflect the padding as defined in the 9Patch:

  1. Setting all margins to 0 for the LayoutParams
  2. Manually setting all padding for the button to 0. (Ref. Button A)
  3. Setting the minimum height of the button View to a value smaller than the height of the text. (Ref. Button B)
  4. Setting the minimum height of the button's TextView to a value smaller than the height of the text. (Ref. Button C)
  5. Setting both the minimum height of the button View & the button's TextView to a value smaller than the height of the text (in other words, combining tests 3 & 4). (Ref. Button D)
  6. Manually transferring the padding from the 9Patch as per dandc87's suggestion. (Ref. Button E)
  7. Using the 9Patch with an ImageButton instead of a Button. (Ref. Button F)

As you can see below, only Button D (Test 5) and ImageButton F (Test 7) implement the padding as defined in the 9Patch. Why is this so?

Setting both the View and TextView minimum height to a small value seems like a messy hack.

The core of my question is: What is the correct way to get a programmatically created button to correctly reflect the padding defined in a 9Patch.


Below I've tabulated some of the info after inspecting each test button in Hierarchy View.

// Measurement info from Hierarchy View

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Button A B C D E F

// ------------------------------------------

// mMeasuredHeight 64 64 64 44 64 54

// mMeasuredWidth 85 85 85 85 85 57

// mMinHeight 64 1 64 1 64 0

// mMinWidth 85 85 85 85 85 0

// Padding info from Hierarchy View

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Button A B C D E F

// ------------------------------------------------------------------------------------------

// mPaddingBottom 4 4 4 4 4 4

// mPaddingLeft 7 7 7 7 7 7

// mPaddingRight 7 7 7 7 7 7

// mPaddingTop 7 7 7 7 7 7

// mUserPaddingBottom 4 4 4 4 4 4

// mUserPaddingEnd 0 -2147483648 -2147483648 -2147483648 -2147483648 -2147483648

// mUserPaddingLeft 7 7 7 7 7 7

// mUserPaddingRight 7 7 7 7 7 7

// mUserPaddingStart 0 -2147483648 -2147483648 -2147483648 -2147483648 -2147483648

NOTE:

In Test 2 I have tried calling setPaddingRelative() which the android Reference documentation indicates is equivalent to the XML attribute android:padding (I tried setting the padding to 0 and also to -1).

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

RelativeLayout mainLayout = (RelativeLayout)findViewById(R.id.main_layout);

LinearLayout testLayout = new LinearLayout(this);

mainLayout.addView(testLayout);

// Test (1): Setting all margins to 0 for the LayoutParams

// Result: No Effect

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

params.setMargins(0, 0, 0, 0);

// Test (2): Setting all padding to 0 for btnA

// Result: No Effect

Button btnA = new Button(this);

btnA.setText("Btn A");

btnA.setPaddingRelative(0, 0, 0, 0);

btnA.setBackground(getResources().getDrawable(R.drawable.test_background));

testLayout.addView(btnA, params);

// Test (3): Setting minimum height of the View btnB to a value smaller than the height of the text

// Result: No Effect

Button btnB = new Button(this);

btnB.setText("Btn B");

btnB.setMinimumHeight(1);

btnB.setBackground(getResources().getDrawable(R.drawable.test_background));

testLayout.addView(btnB, params);

// Test (4): Setting minimum height of the TextView for btnC to a value smaller than the height of the text

// Result: No Effect

Button btnC = new Button(this);

btnC.setText("Btn C");

btnC.setMinHeight(1);

btnC.setBackground(getResources().getDrawable(R.drawable.test_background));

testLayout.addView(btnC, params);

// Test (5): Setting minimum height of both the View & the TextView for btnD

// to a value smaller than the height of the text

// Result: Button appears to implement padding as defined in the 9Patch

Button btnD = new Button(this);

btnD.setText("Btn D");

btnD.setMinimumHeight(1);

btnD.setMinHeight(1);

btnD.setBackground(getResources().getDrawable(R.drawable.test_background));

testLayout.addView(btnD, params);

// Test (6): Manually setting the padding for btnE from the 9Patch as per dandc87's suggestion.

// Result: No Effect

Button btnE = new Button(this);

btnE.setText("Btn E");

btnE.setBackground(getResources().getDrawable(R.drawable.test_background));

NinePatchDrawable img = (NinePatchDrawable) getResources().getDrawable(R.drawable.test_background);

Rect padding = new Rect();

img.getPadding(padding);

btnE.setPadding(padding.left, padding.top, padding.right, padding.bottom);

testLayout.addView(btnE, params);

// Test (7): Using the 9Patch with an ImageButton instead of a Button

// Result: Button appears to implement padding as defined in the 9Patch

ImageButton btnF = new ImageButton(this);

btnF.setImageResource(android.R.drawable.ic_menu_add);

btnF.setBackground(getResources().getDrawable(R.drawable.test_background));

testLayout.addView(btnF, params);

}

}

网友答案:

To get the padding from the 9patch, you could try:

NinePatchDrawable img = (NinePatchDrawable) getResources().getDrawable(R.drawable.my_9p);
Rect padding = new Rect();
img.getPadding(padding);
//padding now contains the padding

You can then use padding to set the padding of the Button with setPaddingRelative()

相关阅读:
Top