Android - как программно определить ShapeDrawables?
То, что я пытаюсь достичь, - использовать 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);
Спасибо.
Ответы
Ответ 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);
Ответ 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);
}
}
Изменить: проверено Теперь была одна ошибка.
Вы действительно должны описывать каждое отдельное государство. Если вы группируете состояния, они будут срабатывать только в том случае, если все они будут немедленно очищаться...