在代码中设置形状资源 / GradientDrawable 的填充

Posted

技术标签:

【中文标题】在代码中设置形状资源 / GradientDrawable 的填充【英文标题】:Setting padding of a shape resource / GradientDrawable in code 【发布时间】:2012-01-19 15:38:29 【问题描述】:

我有一个 xml 文件,其中有一个选择器,它定义了按钮的不同状态:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/custom_green_button_selected_state" />
<item android:state_enabled="false" android:drawable="@drawable/custom_green_button_disabled_state" />  
<item android:drawable="@drawable/custom_green_button_normal_state"/>
</selector>

然后在我的每个可绘制 xml 中,我都有关于按钮外观的信息:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:type="linear" android:gradientRadius="180"
    android:startColor="#6b9f41" android:endColor="#598a3d" />

<corners android:bottomRightRadius="7dp"
    android:bottomLeftRadius="7dp" android:topLeftRadius="7dp"
    android:topRightRadius="7dp" />
<padding android:left="15dp" android:right="15dp" android:top="10dp"
    android:bottom="10dp" />
</shape>

对于我应用程序中的大多数按钮,我只是将第一个 xml 应用为背景,一切正常。对于特定按钮,我想使用相同的 xml,但通过更改可绘制对象的填充使按钮更窄。我想我会尝试在我的代码中创建一个新的 StateListDrawable 并添加每个单独状态的可绘制 xml 的变异,但是,这些可绘制对象显示为 GradientDrawables,这似乎无法让我访问它们的填充属性。有什么想法吗?

【问题讨论】:

【参考方案1】:

背景drawable的填充也是由View类中的setPadding设置的。

你可以在 setBackgroundDrawable 之后调用 setPadding 来设置 padding。

这里是core/java/android/view/View.java:

/**
 * Set the background to a given Drawable, or remove the background. If the
 * background has padding, this View's padding is set to the background's
 * padding. However, when a background is removed, this View's padding isn't
 * touched. If setting the padding is desired, please use
 * @link #setPadding(int, int, int, int).
 *
 * @param d The Drawable to use as the background, or null to remove the
 *        background
 */
public void setBackgroundDrawable(Drawable d) 
    boolean requestLayout = false;

    mBackgroundResource = 0;

    /*
     * Regardless of whether we're setting a new background or not, we want
     * to clear the previous drawable.
     */
    if (mBGDrawable != null) 
        mBGDrawable.setCallback(null);
        unscheduleDrawable(mBGDrawable);
    

    if (d != null) 
        Rect padding = sThreadLocal.get();
        if (padding == null) 
            padding = new Rect();
            sThreadLocal.set(padding);
        
        if (d.getPadding(padding)) 
            setPadding(padding.left, padding.top, padding.right, padding.bottom);
        

【讨论】:

【参考方案2】:

对于一个特定的按钮,我想使用相同的 xmls,但使 通过更改可绘制对象的填充使按钮更窄。

那是你的问题。您不应该使用填充来设置按钮大小。而是依赖layout_heightlayout_width 或以编程方式在onMeasure 中设置(在自定义按钮中)

【讨论】:

以上是关于在代码中设置形状资源 / GradientDrawable 的填充的主要内容,如果未能解决你的问题,请参考以下文章

如何在xml中设置形状的背景?

在android活动中设置片段的形状和透明度

使用 matplotlib 在网络中设置动态节点形状

无法在画布中设置背景图像

在 OSX 上的 C 代码中设置工作目录

在代码中设置 WPF 图像源