【问题标题】:Android - how to define ShapeDrawables programmatically?Android - 如何以编程方式定义 ShapeDrawables?
【发布时间】:2011-08-22 16:35:05
【问题描述】:

我想要实现的是使用其中包含几个图层的 Drawable,但在运行时控制一些值,例如渐变的 startColor。这是我在 my_layered_shape.xml 中的内容:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
    <shape android:shape="rectangle">
      <stroke android:width="1dp" android:color="#FF000000" />
      <solid android:color="#FFFFFFFF" />
    </shape>
  </item>
  <item android:top="1dp" android:bottom="1dp"> 
    <shape android:shape="rectangle">
    <stroke android:width="1dp" android:color="#FF000000" />
    <gradient
      android:startColor="#FFFFFFFF"
      android:centerColor="#FFFFFF88"
      android:endColor="#FFFFFFFF"
      android:gradientRadius="250"
      android:centerX="1"
      android:centerY="0"
      android:angle="315"
    />            
    </shape>
  </item>
</layer-list>

如果我使用 mMyImageView.setBackgroundResource(R.drawable.my_layered_shape) 它可以工作。 如果必须,我不介意拆分 xml,或者只要有办法获得各种颜色值,就可以通过编程方式完成整个工作。我要以编程方式提出的概念(即我在代码中与此 xml 相同的最佳方法)是:

Drawable[] layers = new Drawable[2];

ShapeDrawable sd1 = new ShapeDrawable(new RectShape());
sd1.getPaint().setColor(0xFFFFFFFF);
sd1.getPaint().setStyle(Style.STROKE);
sd1.getPaint().setStrokeWidth(1);
// sd1.getPaint().somehow_set_stroke_color?

ShapeDrawable sd2 = new ShapeDrawable(new RectShape());
sd2.getPaint().setColor(0xFF000000);
sd2.getPaint().setStyle(Style.STROKE);
// sd2.getPaint().somehow_set_stroke_color?
// sd2.getPaint().somehow_set_gradient_params?

layers[0] = sd1;
layers[1] = sd2;
LayerDrawable composite = new LayerDrawable(layers);
mMyImageView.setBackgroundDrawable(composite);

谢谢。

【问题讨论】:

    标签: android shape


    【解决方案1】:

    这似乎不适用于 ShapeDrawable,但看看我的 GradientDrawable 示例:

    GradientDrawable gd = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]{Color.RED, Color.GREEN});
    gd.setStroke(10, Color.BLUE);
    

    您可能还需要以下方法:

    gd.setGradientCenter(float x, float y);
    gd.setGradientRadius(float gradientRadius);
    

    【讨论】:

    • 奇怪的是,GradientDrawable 类没有 'setPadding' 方法,有什么解决办法吗?
    【解决方案2】:

    只是把它留在这里......尚未测试

     /**
     * Created by Nedo on 09.04.2015.
     */
    public class ShapeBuilder {
    
        public static Drawable generateSelectorFromDrawables(Drawable pressed, Drawable normal) {
            StateListDrawable states = new StateListDrawable();
            states.addState(new int[]{ -android.R.attr.state_focused, -android.R.attr.state_pressed, -android.R.attr.state_selected}, normal);
            states.addState(new int[]{ android.R.attr.state_pressed}, pressed);
            states.addState(new int[]{ android.R.attr.state_focused}, pressed);
            states.addState(new int[]{ android.R.attr.state_selected}, pressed);
    
            return states;
        }
    
        public static Drawable generateShape(String colorTop, String colorBot, String colorStroke, int stokeSize, float strokeRadius) {
            int top, bot, stroke;
            top = Color.parseColor(colorTop);
            bot = Color.parseColor(colorBot);
            stroke = Color.parseColor(colorStroke);
    
            GradientDrawable drawable = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[]{top, bot});
            drawable.setStroke(stokeSize, stroke);
            drawable.setCornerRadius(strokeRadius);
    
            return drawable;
        }
    
        public static Drawable buildSelectorShapeFromColors(String colorNormalStroke, String colorNormalBackTop, String colorNormalBackBot,
                                                            String colorPressedStroke, String colorPressedBackTop, String colorPressedBackBot,
                                                            int strokeSize, float strokeRadius) {
    
            Drawable pressed = generateShape(colorPressedBackTop, colorPressedBackBot, colorPressedStroke, strokeSize, strokeRadius);
            Drawable normal = generateShape(colorNormalBackTop, colorNormalBackBot, colorNormalStroke, strokeSize, strokeRadius);
            return generateSelectorFromDrawables(pressed, normal);
        }
    }
    

    编辑:测试现在,有一个错误。 你实际上必须描述每一个状态。如果您对状态进行分组,则只有在所有状态同时发生时才会触发它们...

    【讨论】:

      猜你喜欢
      • 2011-05-25
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 2021-06-09
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      相关资源
      最近更新 更多