获取以编程方式创建的按钮,以便从9Patch正确实现填充

时间:2013-11-06 02:32:24

标签: android

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

test_background.9.png

我搜索过,发现其他人也有同样的问题。建议问题是默认按钮样式会覆盖9Patch中定义的填充。一位用户solved the issue通过在其XML中设置android:padding="@null"

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

  1. 为LayoutParams
  2. 设置所有边距为0
  3. 手动将按钮的所有填充设置为0.(参考按钮A)
  4. 将按钮查看的最小高度设置为小于文本高度的值。 (参考按钮B)
  5. 将按钮的 TextView 的最小高度设置为小于文本高度的值。 (参考按钮C)
  6. 设置 两者 按钮的最小高度查看&按钮的 TextView 的值小于文本的高度(换句话说,组合测试3和4)。 (参考按钮D)
  7. 根据dandc87的建议,手动从9Patch转移填充。 (参考按钮E)
  8. 将9Patch与ImageButton一起使用而不是使用Button。 (参考按钮F)
  9. 如下所示,只有Button D(Test 5)和ImageButton F(Test 7)实现了9Patch中定义的填充。为什么会这样?

    将View和TextView最小高度设置为较小的值似乎是一个混乱的黑客 我的问题的核心是: 获取以编程方式创建的按钮正确反映9Patch中定义的填充的正确方法是什么。
    enter image description here
    下面我在检查层次结构视图中的每个测试按钮后列出了一些信息。

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

    注意:
    Test 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);
    
        }
    }
    

1 个答案:

答案 0 :(得分:1)

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

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

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