我使用下面显示的 9Patch 可绘制对象作为按钮的背景。
绘制按钮时,默认情况下它们似乎没有使用 9Patch 中定义的填充。
我搜索并发现其他人也有同样的问题。建议问题是默认按钮样式覆盖了 9Patch 中定义的填充。一位用户通过设置他们的 XML解决了这个问题。android:padding="@null"
然而,我需要以编程方式而不是在 XML 中实现相同的目标。
在下面的测试应用程序中,我尝试了很多方法来让按钮反映 9Patch 中定义的填充:
- 将 LayoutParams 的所有边距设置为 0
- 手动将按钮的所有填充设置为 0。(参考按钮 A)
- 将按钮View的最小高度设置为小于文本高度的值。(参考按钮 B)
- 将按钮的TextView的最小高度设置为小于文本高度的值。(参考按钮 C)
- 将按钮视图和按钮的TextView的最小高度设置为小于文本高度的值(换句话说,结合测试 3 和 4)。(参考按钮 D)
- 根据 dandc87 的建议从 9Patch 手动传输填充。(参考按钮 E)
- 使用带有 ImageButton 而不是 Button 的 9Patch。(参考按钮 F)
正如您在下面看到的,只有 Button D(测试 5)和 ImageButton F(测试 7)实现了 9Patch 中定义的填充。为什么会这样?
将 View 和 TextView 的最小高度都设置为一个很小的值似乎是一个混乱的 hack。
我的问题的核心是: 获得以编程方式创建的按钮以正确反映 9Patch 中定义的填充的正确方法是什么。
下面我在检查层次结构视图中的每个测试按钮后列出了一些信息。
// 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
注意:
在测试 2中,我尝试调用setPaddingRelative()
android 参考文档指示的调用等同于 XML 属性android:padding
(我尝试将填充设置为 0 和 -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);
}
}