2

我使用下面显示的 9Patch 可绘制对象作为按钮的背景。
绘制按钮时,默认情况下它们似乎没有使用 9Patch 中定义的填充。

test_background.9.png

我搜索并发现其他人也有同样的问题。建议问题是默认按钮样式覆盖了 9Patch 中定义的填充。一位用户通过设置他们的 XML解决了这个问题。android:padding="@null"

然而,我需要以编程方式而不是在 XML 中实现相同的目标。
在下面的测试应用程序中,我尝试了很多方法来让按钮反映 9Patch 中定义的填充:

  1. 将 LayoutParams 的所有边距设置为 0
  2. 手动将按钮的所有填充设置为 0。(参考按钮 A)
  3. 将按钮View的最小高度设置为小于文本高度的值。(参考按钮 B)
  4. 将按钮的TextView的最小高度设置为小于文本高度的值。(参考按钮 C)
  5. 将按钮视图和按钮的TextView最小高度设置为小于文本高度的值(换句话说,结合测试 3 和 4)。(参考按钮 D)
  6. 根据 dandc87 的建议从 9Patch 手动传输填充。(参考按钮 E)
  7. 使用带有 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);

    }
}
4

1 回答 1

1

要从 9patch 获取填充,您可以尝试:

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

然后,您可以使用padding设置 Button 的填充setPaddingRelative()

于 2013-11-06T02:41:25.430 回答