Reputation: 5411
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:
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);
}
}
Upvotes: 2
Views: 717
Reputation: 1106
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()
Upvotes: 1