Android - 如何定义可配置的大小形状

时间:2014-11-14 14:11:22

标签: android xml android-layout

根据其他一些帖子中的建议,我实现了一个在应用程序中使用的循环按钮:

circular button

使用XML选择器实现:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!--  Non focused states
     -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" 
        android:drawable="@drawable/big_ring_button_unfocused" />
    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" 
        android:drawable="@drawable/big_ring_button_unfocused" />
    <!--  Focused states
     -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" 
        android:drawable="@drawable/big_ring_button_focused" />
    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" 
        android:drawable="@drawable/big_ring_button_focused" />
    <!--  Pressed
     -->
    <item android:state_pressed="true" android:drawable="@drawable/big_ring_button_pressed" />
</selector>

......未聚焦文件的内容(其他文件只改变颜色):

<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:innerRadius="@dimen/big_ring_button_inner_radius"
android:thickness="@dimen/big_ring_button_thickness"
android:useLevel="false">

<solid android:color="@color/white" />

</shape>

我想将此模板用于我的应用中的所有圆角按钮,但由于按钮内的文字发生变化,按钮本身的大小应该会改变。

我认为我可以通过编程方式完成此操作,因此我查看了GradientDrawable的文档 - 没有方法可以更改innerRadius属性。

目前,每个圆形按钮(选择器,未聚焦,聚焦和按下)都有4个XML文件,这些文件非常难看,并且会成为维持颈部的痛苦。

如何使此按钮的大小可配置(XML或以编程方式)?

由于

2 个答案:

答案 0 :(得分:3)

您无法以编程方式更改innerRadius属性,因为它仅在充气时从XML属性中读取(请参阅例如this answer)。

但是,通过使用自定义drawable绘制环,您可以以编程方式实现或多或少相同的效果。例如:

public class RoundBorderDrawable extends GradientDrawable
{
    private static final int RING_THICKNESS = 20;
    private static final int PADDING = 8;
    private static final int NORMAL_COLOR = Color.BLUE;
    private static final int PRESSED_COLOR = Color.RED;

    private Paint mPaint;

    public RoundBorderDrawable()
    {
        mPaint = new Paint();
        mPaint.setStyle(Style.STROKE);
        mPaint.setStrokeWidth(RING_THICKNESS);
        mPaint.setColor(NORMAL_COLOR);
    }

    @Override
    public boolean isStateful()
    {
        return true;
    }

    @Override
    protected boolean onStateChange(int[] stateSet)
    {
        boolean result = super.onStateChange(stateSet);

        int color = NORMAL_COLOR;
        for (int i = 0; i < stateSet.length; i++)
        {
            if (stateSet[i] == android.R.attr.state_pressed)
                color = PRESSED_COLOR;
        }

        if (color != mPaint.getColor())
        {
            mPaint.setColor(color);
            invalidateSelf();
            result = true;
        }

        return result;
    }

    @Override
    public void draw(Canvas canvas)
    {
        super.draw(canvas);
        int diameter = Math.min(canvas.getWidth(), canvas.getHeight()) - RING_THICKNESS - 2 * PADDING;
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, diameter / 2, mPaint);
    }
}

这将绘制一个适合Button维度的圆圈(我假设您想要绘制一个圆圈,即使是非方形按钮)。

然后只需设置一个新的RoundBorderDrawable实例作为按钮的背景(当然,本例中的常量属性可以通过构造函数或setter方法提供)。

答案 1 :(得分:0)

我有更好的方法来做到这一点。而不是Ring使用Oval并使用白色和宽度为@dimen/big_ring_button_thickness的笔划 但这并不能给你圆形的形状。要实现圆形,您的按钮应该是方形的,我的意思是按钮的宽度和高度应该相同。