The linear gradient which I am trying to create programatically:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="50%"
android:startColor="#FFFFFFFF"
android:centerColor="#99FF8A8A"
android:endColor="#FFF8F8F8"
android:angle="90"/>
</shape>
I wrote this code:But I didn't get the same result.
GradientDrawable _gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.BOTTOM_TOP, new int[]{
Color.parseColor("#FFFFFFFF"),
Color.parseColor("#99FF8A8A"),
Color.parseColor("#FF8F8F8")
});
myimage.setBackground(_gradientDrawable);
Where's my mistake?
To do this in code, you create a GradientDrawable.
The only chance to set the angle and color is in the constructor.
If you want to change the color or angle, just create a new GradientDrawable and set it as the background.
View layout = findViewById(R.id.mainlayout);
GradientDrawable gd = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[] {0xFF616261,0xFF131313});
gd.setCornerRadius(0f);
layout.setBackgroundDrawable(gd);
Related
What I'm trying to achieve is to use a Drawable with a couple of layers inside it, but control some values at runtime such as the startColor for the gradient. Here's what I have in 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>
And if I use mMyImageView.setBackgroundResource(R.drawable.my_layered_shape) it works.
I don't mind splitting the xml if I have to, or doing the whole thing programatically as long as there's a way to get at the various color values. The concept I'm going for programmatically (i.e. my best shot at doing the same in code as this xml) is:
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);
Thanks.
It seems that is does not work with ShapeDrawable, but take a look at my GradientDrawable example:
GradientDrawable gd = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]{Color.RED, Color.GREEN});
gd.setStroke(10, Color.BLUE);
You may also need following method:
gd.setGradientCenter(float x, float y);
gd.setGradientRadius(float gradientRadius);
Just gonna leave this here... Not tested yet
/**
* 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);
}
}
Edit: tested Now, had one mistake.
You actually have to describe every single state. If you group states they will only be triggered if all of them accure at once...
I have an image on which I'm putting a colored overlay, like this (the colors are taken from here):
layout/list_item_view.xml
<View
android:id="#+id/image_cover_gradient"
android:layout_width="fill_parent"
android:layout_height="80dip"
android:layout_alignParentTop="true"
android:layout_marginTop="70dp"
android:background="#drawable/gradient_blue"
/>
drawable/gradient_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="90"
android:startColor="#color/CornflowerBlue"
android:endColor="#color/Transparent"
android:type="linear" />
</shape>
</item>
</selector>
This always puts a blue overlay (CornflowerBlue) and it works as expected.
Now I'm trying to do this programatically and followed some stackoverflow answers (such as this), but still can't make it work. Here's my code:
private void setColor(int color){
View gradientCover = view.findViewById(R.id.image_cover_gradient);
// this FAILS because it's a StateListDrawable
//GradientDrawable coverGd = (GradientDrawable) gradientCover.getBackground();
//coverGd.setColor(color);
//this doesn't seem to work either (I don't see any effect on the image)
GradientDrawable drawable = new GradientDrawable(
Orientation.BOTTOM_TOP, new int[] { color, resources.getColor(R.color.Transparent)
});
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[] { android.R.attr.startColor, android.R.attr.endColor}, drawable);
gradientCover.setBackground(sld);
}
As #pskink suggested - removing the StateListDrawable solved it:
GradientDrawable drawable = new GradientDrawable(
Orientation.BOTTOM_TOP, new int[] { color, resources.getColor(R.color.Transparent)
});
gradientCover.setBackground(drawable);
i try to draw LinearGradient in a layout but the gradient is not fit into my view.
Instead of gradient i see only one color.
I think its because im not giving the right dimension of the view
Here is my code:
backGroundColorView = (LinearLayout) findViewById(R.id.backGroundColorView);
int[] tempColors = data.getAppBackgroundColor();
LinearGradient test = new LinearGradient(0.f, 0.f, backGroundColorView.getWidth(), backGroundColorView.getHeight(), tempColors, null, TileMode.CLAMP);
ShapeDrawable shape = new ShapeDrawable(new RectShape());
shape.getPaint().setShader(test);
backGroundColorView.setBackgroundDrawable(shape);
Thank for helping
just use GradientDrawable as a background http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html
You can use this site do create the gradient you want and then add a file in your res/drawable and put the code inside.
After that all you have to do is set the background of your layout to be the drawable file you just created.
If you have any questions just ask ;)
EDIT:
Change your code to this:
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,tempColors);
gd.setCornerRadius(0f);
backGroundColorView.setBackgroundDrawable(gd);
Try this
backGroundColorView = (LinearLayout) findViewById(R.id.backGroundColorView);
int[] tempColors = data.getAppBackgroundColor();
GradientDrawable gd = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,tempColors);
gd.setCornerRadius(0f);
backGroundColorView .setBackgroundDrawable(gd);
Instead of
backGroundColorView = (LinearLayout) findViewById(R.id.backGroundColorView);
int[] tempColors = data.getAppBackgroundColor();
LinearGradient test = new LinearGradient(0.f, 0.f, backGroundColorView.getWidth(), backGroundColorView.getHeight(), tempColors, null, TileMode.CLAMP);
ShapeDrawable shape = new ShapeDrawable(new RectShape());
shape.getPaint().setShader(test);
backGroundColorView.setBackgroundDrawable(shape);
GradientDrawable
you can create linear gradiant like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="50%"
android:startColor="#FF003333"
android:centerColor="#FF05C1FF"
android:endColor="#FF003333"
android:angle="270"/>
<!-- <gradient
android:centerColor="#FF05C1FF"
android:centerX="50%"
android:centerY="50%"
android:endColor="#FF003333"
android:gradientRadius="50"
android:startColor="#FF003333"
android:type="radial" /> -->
<corners
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
and use it as background of linear layout.
ihope it solves your problem.
see i have used this in my post: customToast
you can use this also:
GradientDrawable grad = new GradientDrawable(Orientation.LEFT_RIGHT,
new int[]{0xffffffff, 0xffff00ff, 0xffffff00,
0xff0000ff, 0xf0f0f0f0, 0xfefefefe});
grad.setBounds(0, 0, 320, 480);
I have a gradient drawable defined in xml that I use it as a background, like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:bottom="4dp">
<shape>
<gradient
android:startColor="#color/blue"
android:endColor="#color/dark_blue"
android:angle="270" />
</shape>
</item>
<item android:top="98dp">
<shape>
<gradient
android:startColor="#color/black"
android:endColor="#color/transparent_black"
android:angle="270" />
</shape>
</item>
</layer-list>
I need to implement this programmatically. I have tried to use a GradientDrawable as follows (this method is implemented on a custom view):
int[] colors1 = {getResources().getColor(R.color.black), getResources().getColor(R.color.trasparent_black)};
GradientDrawable shadow = new GradientDrawable(Orientation.TOP_BOTTOM, colors1);
shadow.setBounds(0,98, 0, 0);
int[] colors = new int[2];
colors[0] = getResources().getColor(R.color.blue);
colors[1] = getResources().getColor(R.color.dark_blue);
GradientDrawable backColor = new GradientDrawable(Orientation.TOP_BOTTOM, colors);
backColor.setBounds(0, 0,0, 4);
//finally create a layer list and set them as background.
Drawable[] layers = new Drawable[2];
layers[0] = backColor;
layers[1] = shadow;
LayerDrawable layerList = new LayerDrawable(layers);
setBackgroundDrawable(layerList);
The problem is that it seems that setting the bounds is useless or doesn't work the same way as (android:top, android:bottom xml parameters). The resulting background is each layer painted from top to bottom, one above the other.
I want to generate something like this:
Found the answer!. Possible duplicate Multi-gradient shapes.
Replaced:
backColor.setBounds(0, 0,0, 4);
shadow.setBounds(0,98, 0, 0);
for
layerList.setLayerInset(0, 0, 0, 0, 4);
layerList.setLayerInset(1, 0, 98, 0, 0);
What I'm trying to achieve is to use a Drawable with a couple of layers inside it, but control some values at runtime such as the startColor for the gradient. Here's what I have in 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>
And if I use mMyImageView.setBackgroundResource(R.drawable.my_layered_shape) it works.
I don't mind splitting the xml if I have to, or doing the whole thing programatically as long as there's a way to get at the various color values. The concept I'm going for programmatically (i.e. my best shot at doing the same in code as this xml) is:
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);
Thanks.
It seems that is does not work with ShapeDrawable, but take a look at my GradientDrawable example:
GradientDrawable gd = new GradientDrawable(Orientation.BOTTOM_TOP, new int[]{Color.RED, Color.GREEN});
gd.setStroke(10, Color.BLUE);
You may also need following method:
gd.setGradientCenter(float x, float y);
gd.setGradientRadius(float gradientRadius);
Just gonna leave this here... Not tested yet
/**
* 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);
}
}
Edit: tested Now, had one mistake.
You actually have to describe every single state. If you group states they will only be triggered if all of them accure at once...