how to convert shape to ShapDrawable in android - android

I have a number of shapes, and I have one view. I need to dynamically (i.e. programmatically) select a shape to set as the background of my view based on user inputs. So my question: who do I programmatically turn a shape into a ShapeDrawable or such?
I already look at How to change shape color dynamically?. Those posts assume the shape is already attached to a view. But me all my shapes are free agents.

It seems that is does not work with ShapeDrawable, but take a look at my GradientDrawable example:
you can create gradient drawable dynamically.. use below class
import android.graphics.drawable.GradientDrawable;
public class SomeDrawable extends GradientDrawable {
public SomeDrawable(int pStartColor, int pCenterColor, int pEndColor, int pStrokeWidth, int pStrokeColor, float cornerRadius) {
super(Orientation.BOTTOM_TOP,new int[]{pStartColor,pCenterColor,pEndColor});
setStroke(pStrokeWidth,pStrokeColor);
setShape(GradientDrawable.RECTANGLE);
setCornerRadius(cornerRadius);
}
}
and use this class as below
SomeDrawable drawable = new SomeDrawable(Color.parseColor("Start Color Code"),Color.parseColor("Center Color Code"),Color.parseColor("End Color Code"),1,Color.BLACK,00);
yourLayout.setBackgroundDrawable(drawable);

I just found that I can do
myview.setBackgroundResource(R.drawable.my_shape)

Related

CustomSeekBar with fading alpha color gradient, black thin border, and tiled background

The goal
I'm trying to replicate this Dialog.
The current state
But I've only gotten to this point (showing only the relevant part):
What is missing
A way to add a thin black border surrounding my custom Seekbar's "progress area", and a tiled background restricted to that "progress area".
My code
As it is, my CustomSeekBar (which extends AppCompatSeekBar) works fine for setting a starting and ending color in the code. Here is the function:
public void setGradientColor(#ColorInt int leftColor, #ColorInt int rightcolor) {
grad = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
new int[] {leftColor, rightcolor});
setProgressDrawable(grad);
}
But trying to set the background's image ends up looking like my very last seekbar in the The current state image (the background extends outside of the progress area and fills all of the view's area):
aSeekBar.setBackground(context.getDrawable(R.drawable.checker));
aSeekBar.setGradientColor(Color.parseColor("#00000000"), Color.parseColor("#FF000000"));
My checker.xml file in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/checkerstile"
android:tileMode="repeat"
/>
For the "Border" part of your question, you just have to add a Stroke to your GradientDrawable :
public void setGradientColor(#ColorInt int leftColor, #ColorInt int rightcolor) {
grad = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
new int[] {leftColor, rightcolor});
grad.setStroke(/* stroke width*/, /* int color*/);
setProgressDrawable(grad);
}
For that, it that easy, sorry i can't help for the background.
I've found a viable solution:
int padding = aSeekBar.getPaddingStart();
InsetDrawable bgImg = new InsetDrawable(context.getDrawable(R.drawable.checker), padding);
aSeekBar.setBackground(bgImg);
Combine this with the solution from Olivier for the border and you get this result:

How to change color of a sprite randomly

I wrote the following code:
int color = Color.argb8888(255, rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
stage.getBatch().setColor(color);
With this code I want to change the color of a sprite randomly. Unfortunately, the color of all sprites on the stage get changed but I want to declare which sprite I want to tint. How can I improve my code?
To change tint of a single sprite, use below code
Sprite mysprite;
Texture mytexture;
mytexture = new Texture("texture.png");
mysprite = new Sprite(mytexture);
mysprite.setColor(Color.WHITE.cpy().lerp(Color.BLACK, .5f));
this code changes white tint of sprite to black tint
Color color = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), 1f);
'rand.nextFloat()' is gives you a float between 0 and 1, so you can create random color like this.
I prefer to use in this way :
final Image image=new Image(new Texture("badlogic.jpg"));
final Color colors[]=new Color[]{Color.YELLOW,Color.RED,Color.CYAN};
image.addAction(Actions.forever(Actions.sequence(Actions.delay(.2f),Actions.run(new Runnable() {
#Override
public void run() {
image.setColor(colors[MathUtils.random(colors.length-1)]);
}
}))));
stage.addActor(image);
In my experience, you could just set your color attribute that used as vertex attributes in shader back to normal color masking like this:
stage.getBatch().setColor(your_random_color);
stage.getBatch().draw(your_texture);
stage.getBatch().setColor(1.0f,1.0f,1.0f,1.0f);
Please be noticed that I tried this way for drawing TextureRegion, but I think this would not be different with drawing Sprite.

Setting widget background to programmatically generated gradient

I'm struggling with making my widget to look pretty, but the widget fights back ;(
I have a problem with setting widget layout background to generated linear gradient.
For now, I have found how to generate linear gradient with custom "weigth" of colors for that gradient:
public static PaintDrawable createLinearGradient(final int left, final int top, final int right, final int bottom,
final int[] colors, final float[] positions)
{
ShapeDrawable.ShaderFactory shaderFactory = new ShapeDrawable.ShaderFactory()
{
#Override
public Shader resize(int width, int height)
{
LinearGradient lg = new LinearGradient(left, top, right, bottom, colors, positions, Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable gradient = new PaintDrawable();
gradient.setShape(new RectShape());
gradient.setShaderFactory(shaderFactory);
return gradient;
}
And here is a way to set widget background to drawable from drawable folder:
int backgroundId = getDrawableByName(context, "round_transparrent_background");
remoteViews.setInt(R.id.mainLayout, "setBackgroundResource", backgroundId);
I need a way to write this command as following:
Drawable background = createLinearGradient(params ... );
remoteViews.setInt(R.id.mainLayout, "setBackgroundResource", background);
RemoteViews are inherently limited to certain functions. This makes some sense when you consider that any information you pass to your RemoteViews needs to travel across processes, and not all classes/data types are supported.
There is no way to pass an arbitrary Drawable object to RemoteViews -- none of the methods support it, and Drawable in general is not a class whose data can be marshalled across processes. The reason it works for drawable resources is that the resource ID is just an integer, and Android knows how to inflate them into Bitmaps (for pngs) or their respective Drawable implementations (for anything declared with XML).
As I see it, the only strategy that might work would be to actually draw the gradient into a Bitmap using the Canvas APIs and to use an ImageView in your AppWidget to act as the background. Then you would call remoteViews.setImageViewBitmap() to set the content of the ImageView.

LibGDX - ImageButton - Setting Image With Background

From my understanding, the ImageButton within LibGDX is a frame containing an image. Is it possible to set the background of the frame?
For example, I would like to use a Button background, and apply an Icon on top of that image.
Current Code
Skin with the background:
"com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle": {
"default": {
"imageDown": "button-down",
"imageUp": "button-up"
}
}
Creating the ImageButton:
// Getting imageButtonStyle with "default" style, as it just has the background.
ImageButton.ImageButtonStyle imageButtonStyle = skin.get( "default", ImageButton.ImageButtonStyle.class );
ImageButton button = new ImageButton( imageButtonStyle );
// Set the image on the button to something.
Background image.
Background image with icon overlayed.
Thank you for your help.
The trick is using the 2 different Styles available. ImageButtonStyle to set the icon attributes, but since ImageButtonStyle extends ButtonStyle, the background attributes are set in ButtonStyle. Something like:
ImageButtonStyle style = new ImageButtonStyle();
style.up = background;
style.down = background;
style.checked = background;
style.imageUp = icon_up;
style.imageDown = icon_down;
style.imageChecked = icon_checked;
style.unpressedOffsetY = -20; // to "not" center the icon
style.unpressedOffsetX = -30; // to "not" center the icon
ImageButton heartButton = new ImageButton(style);
ImageButton envelopeButton = new ImageButton(envelopeStyle);
Something like that (for me, backround, icon_* are Drawable). But that's the basics and worked like a charm for me.
You could implement your own button class that extends ImageButton.
Then, if you overload the constructor, you can pass either Drawables or Textures for imageUp, imageDown and background to it:
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
public class myButton extends ImageButton
{
public myButton(Texture texture_up, Texture texture_down, Texture background)
{
super(new SpriteDrawable(new Sprite(texture_up)),
new SpriteDrawable(new Sprite(texture_down)));
this.setBackground(new SpriteDrawable(new Sprite(background));
}
}
Now, you can use your own Button class and instantiate it as follows:
Texture textureUp = new Texture(Gdx.files.internal("data/image_up.png"));
Texture textureDown = new Texture(Gdx.files.internal("data/image_down.png"));
Texture background = new Texture(Gdx.files.internal("data/background.png"));
MyButton myButton = new MyButton(textureUp, textureDown, background);
Maybe play around with it a little and you'll find out what else you can do with it. Just make sure that you have the images in the correct resolution. Background doesn't have to be an image.
A button by definition will have three states:
imageDown - When the mouse is clicked on the button
imageUp - When the mouse is released on the button
imageChecked - When the mouse is hovering on the button
In the scene2d api there isn't a way yet of manually setting the imageButton's background image but if you do want something like that its best to have an array of images and an index as to what image you want, and render using a sprite batch e.g:
Texture[] images;
int currentImage;

How to modify color of a drawable programatically

Hi I have a shape drawable in xml and it is used as background of a view. Its color needs to be changed in the code depending on conditions.
So I am doing
ShapeDrawable d = (ShapeDrawable) getResources().getDrawable(R.drawable.shape1);
d.getPaint().setShader(sd1);
but the getDrawable returns a gradient drawable, casting it to ShapeDrawable generates error.
So how can I get shapeDrawable in code and modify its attributes.
I was able to fix this by casting as a GradientDrawable instead of ShapeDrawable.
GradientDrawable shape = (GradientDrawable) getResources().getDrawable(R.drawable.shape1);
shape.setColor(Color);
I used this when I created an activity with a custom style based on the Holo.Dialog theme.
This code snippet worked for me:
PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(getResources().getColor(R.color.your_color),PorterDuff.Mode.MULTIPLY);
imgView.getDrawable().setColorFilter(porterDuffColorFilter);
imgView.setBackgroundColor(Color.TRANSPARENT)
Here is how you can set the color:
d.getPaint().setColor(Color.BLACK);
I have wrote a generic function in which you can pass context, icon is id drawable/mipmap image icon and new color which you need for that icon.
This function returns a drawable.
public static Drawable changeDrawableColor(Context context,int icon, int newColor) {
Drawable mDrawable = ContextCompat.getDrawable(context, icon).mutate();
mDrawable.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_IN));
return mDrawable;
}
changeDrawableColor(getContext(),R.mipmap.ic_action_tune, Color.WHITE);

Categories

Resources