This question already has answers here:
Android: How to create a StateListDrawable programmatically
(3 answers)
Closed 8 years ago.
I want to create selector drawables programmatically. The shape has to be in the following form:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#4aa5d4" />
</shape></item>
<item><shape>
<stroke android:width="1dp" android:color="#4aa5d4" />
</shape></item>
</selector>
Why? Because i want those 2 colors the be changeable. I know i have to create some kind of Drawable for this. I already managed to create my own GradientDrawables like this:
public GradientDrawable getBackgroundGradient() {
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[] { BACKGROUND_GRADIENT_TOP_COLOR, BACKGROUND_GRADIENT_BOTTOM_COLOR });
return gd;
}
But now I need a SelectorDrawable.
Ok, here is, what i came up with using the linked topic.
public StateListDrawable getSelectorDrawable(int color) {
StateListDrawable out = new StateListDrawable();
out.addState(new int[] { android.R.attr.state_pressed }, createNormalDrawable(color));
out.addState(StateSet.WILD_CARD, createStrokeDrawable(color));
return out;
}
public GradientDrawable createNormalDrawable(int color) {
GradientDrawable out = new GradientDrawable();
out.setColor(color);
return out;
}
public GradientDrawable createStrokeDrawable(int color) {
GradientDrawable out = new GradientDrawable();
out.setStroke(1, color);
return out;
}
You can just supply a drawable as the resource in your Selector XML. The drawable can be anything (PNG, XML, etc)
Like this:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/shape_highlighted"
android:state_pressed="true"/>
<item
android:drawable="#drawable/shape_disabled"
android:state_enabled="false"/>
<item
android:drawable="#drawable/shape_normal"/>
</selector>
Related
My radio buttons have background which is selector drawable.
And I want to change the color of state_checked="true" item's drawable programmatically.
The background of radiobutton :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:drawable="#drawable/checkbox_membertag_inactive" />
<item android:state_checked="true"
android:drawable="#drawable/checkbox_membertag_active"/>
</selector>
checkbox_membertag_active :
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/white" />
<corners
android:radius="36dp" />
<solid
android:color="#color/white" />
</shape>
and I tried in this way. I want to change the #color/white of active item to starColor which I pre-declared. But it's still white color.
rgEventStyle.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#SuppressLint("ResourceAsColor")
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton checkedEvtStyle = findViewById(checkedId);
StateListDrawable stateListDrawable = (StateListDrawable) checkedEvtStyle.getBackground();
stateListDrawable.addState(new int[]{android.R.attr.state_checked},new ColorDrawable(starColor));
stateListDrawable.addState(new int[]{-android.R.attr.state_checked}, new ColorDrawable(R.color.gray5));
checkedEvtStyle.setBackground(stateListDrawable);
}
});
Try with ColorStatList like the Code below :
rgEventStyle.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#SuppressLint("ResourceAsColor")
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int[][] state =
{
new int[]{android.R.attr.state_checked},
new int[]{-android.R.attr.state_checked}
};
int[] color = new int[]
{
ContextCompat.getColor(getApplicationContext(), R.starColor),
ContextCompat.getColor(getApplicationContext(), R.color.gray5)
};
RadioButton checkedEvtStyle = findViewById(checkedId);
ColorStateList colorStateList = new ColorStateList(state, color);
checkedEvtStyle.setBackgroundTintList(colorStateList);
}
});
I'm trying to change the background color of a button I made to a certain color when toggled and back when untoggled, but when I do the color changes the shape of the button.
Here is my code:
public void onClick(View v){
if(index < 9)
GameEngine.getInstance().setNumber(number);
else if(index == 9)
GameEngine.getInstance().setNumber(number);
else if (index == 12) {
GameEngine.getInstance().draftModeSetter();
v.setBackgroundColor(Color.parseColor("#ffb6c1"));
}
}
And here is the result before color change and the result after color change. You can clearly see the "draft" button gets becomes bigger and a sharper square.
If the background color was set using
btn.getBackground().setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
it can be reset using:
btn.getBackground().clearColorFilter();
I think you should use xml : shape, selector like :
shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<solid android:color="#color/blue_400" />
<stroke
android:width="1dp"
android:color="#color/blue_400" />
</shape>
selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/shape_comm_bt_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/shape_comm_bt_normal"
android:state_pressed="false" />
</selector>
use
<Button
...
android:background="#drawable/selector_common_bt"
...
/>
View.OnFocusChangeListener focusListener = new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus){
editText.getBackground().setColorFilter(ContextCompat.getColor(getActivity().getApplicationContext(),R.color.ed_background), PorterDuff.Mode.SRC_ATOP);
} else {
int color = Color.parseColor("#FFFFFF");
editText.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
}
};
<color name="ed_background">#33FFFFFF</color>
This makes the edit text underline black, but I want it to be a transparent white. Setting a custom style with xml also sets it to black. How can I make the underline a transparent white with java?
You can try smth like this:
creates drawable xml for ex edittext_lined.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-2dp" android:right="-2dp" android:left="-2dp">
<shape>
<solid android:color="#android:color/transparent" />
<stroke android:color="#color/ed_background" android:width="1dp"/>
</shape>
</item>
then in code:
editText.setBackgroundResource(R.drawable.edittext_lined);
Just set the edittext background color to white/transparent in xml layout / in code.
I have a selector for a toggle button checked and unchecked - is there a way that I can use a custom layer list with a shape and use different colours? I am adding them in at runtime but using XML as the design.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/toggle_custom"/>
<item android:state_checked="false" android:drawable="#drawable/toggle_custom_off"/>
</selector>
And my toggle_custom and toggle_custom_off
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/mainColourOn">
<shape android:shape="rectangle" />
</item>
<item android:bottom="10dp">
<shape android:shape="rectangle">
<solid android:color="#E6FFFFFF"/>
</shape>
</item>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/mainColourOff">
<shape android:shape="rectangle"/>
</item>
<item android:bottom="10dp">
<shape android:shape="rectangle">
<solid android:color="#FFF"/>
</shape>
</item>
LayerDrawable layerOn = (LayerDrawable) getResources().getDrawable(R.drawable.toggle_custom, getTheme());
LayerDrawable layerOff = (LayerDrawable) getResources().getDrawable(R.drawable.toggle_custom_off, getTheme());
GradientDrawable toggleOn = (GradientDrawable) layerOn.findDrawableByLayerId(R.id.mainColourOn);
GradientDrawable toggleOff = (GradientDrawable) layerOff.findDrawableByLayerId(R.id.mainColourOff);
int colour = persons.get(i).getColour();
toggleOn.mutate();
toggleOff.mutate();
toggleOn.setColor(colour);
toggleOff.setColor(colour);
So for example have one toggle that is using the colour red and another using blue using the same XML. Thanks
You can reuse the xml for the layer-list Drawable and create the StateListDrawable for each ToggleButton programmatically like this:
void setToggleButtonColor(ToggleButton tButton, int colour)
{
LayerDrawable layerOn = (LayerDrawable) ContextCompat.getDrawable(this, R.drawable.toggle_custom);
layerOn.mutate();
LayerDrawable layerOff = (LayerDrawable) ContextCompat.getDrawable(this, R.drawable.toggle_custom_off);
layerOff.mutate();
Drawable toggleOn = layerOn.findDrawableByLayerId(R.id.mainColourOn);
Drawable toggleOff = layerOff.findDrawableByLayerId(R.id.mainColourOff);
toggleOn.setColorFilter(colour, PorterDuff.Mode.MULTIPLY);
toggleOff.setColorFilter(colour, PorterDuff.Mode.MULTIPLY);
StateListDrawable tbBackground = new StateListDrawable();
tbBackground.addState(new int[]{android.R.attr.state_checked}, layerOn );
tbBackground.addState(StateSet.WILD_CARD, layerOff);
tButton.setBackgroundDrawable(tbBackground);
}
Let's test it with two ToggleButtons:
ToggleButton toggleButton1 = (ToggleButton) findViewById(R.id.togglebutton1);
toggleButton1.setChecked(true);
ToggleButton toggleButton2 = (ToggleButton) findViewById(R.id.togglebutton2);
toggleButton2.setChecked(true);
setToggleButtonColor(toggleButton1, ContextCompat.getColor(this, R.color.blue));
setToggleButtonColor(toggleButton2, ContextCompat.getColor(this, R.color.magenta));
I'm trying to make buttons rounded, random background color? When I tried the code below, the button isn't rounded.
Here is the code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newtestament);
LinearLayout layout = (LinearLayout) findViewById(R.id.linearlayoutnew);
String[] values = { "Matthai", "Marka", "Luka", "Johan",
"Sawltak Tangthu", "Rom Laikhak", "Korin Masa", "Korin Nihna",
"Galati", "Efesa", "Filippi", "Kolose", "Thesalonika Masa",
"Thesalonika Nihna", "Timoti Masa", "Timoti Nihna", "Titus",
"Filemon", "Hebru", "James", "Peter Masa", "Peter Nihna",
"Johan Masa", "Johan Nihna", "Johan Thumna", "Jude",
"Maangmuhna" };
Button[] b = new Button[values.length];
for (int i = 0; i < b.length; i++) {
b[i] = new Button(this);
}
int[] btnColor = { 0xAAe60038, 0xAA9142d6, 0xAAf07b04, 0xAA1515ff,
0xAA23699e, 0xAA0a71ff, 0xAA3e3d39, 0xAA00b323, 0xAA754e45,
0xAAfa061e, 0xAAe66d2d, 0xAAff00ff };
// calling random
Random random = new Random();
// ramdomizing a color
int c = btnColor[random.nextInt(btnColor.length)];
for (int i = 0; i < values.length; i++) {
// applying button rounded xml style
b[i].setBackgroundDrawable(getResources().getDrawable(
R.drawable.round));
// setting randomized color
b[i].setBackgroundColor(c);
// layout
LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
// margin
((MarginLayoutParams) params).setMargins(5, 5, 5, 5);
// padding
b[i].setPadding(10, 10, 10, 10);
// text color
b[i].setTextColor(0xFFFFFFFF);
// text
b[i].setText(values[i]);
// text size
b[i].setTextSize(18);
Typeface face = Typeface.createFromAsset(getBaseContext()
.getAssets(), "UBUNTU-R.TTF");
b[i].setTypeface(face);
layout.addView(b[i], params);
}
}
Here is round.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- you can use any color you want I used here gray color -->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
I think the problems are setBackgroundDrawable, setBackgroundColor and romdomizing. What additional codes are needed? ??? Update:How to edit round.xml to make the button rounded?
You are setting button background as drawable and then the color also. So statements are executed sequentially. So in the end your button should have a background color set.
So try commenting one of them and run the code again.
b[i].setBackgroundDrawable(getResources().getDrawable( R.drawable.round));
// set background drawable
// first your background drawable will be set
b[i].setBackgroundColor(c);
//set background color.
bkg.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/pressed" />
<item android:state_focused="false"
android:drawable="#drawable/normal" />
</selector>
normal.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke android:width="3dp"
android:color="#0FECFF" /><!-- #330000FF #ffffffff -->
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
pressed.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF1A47"/>
<stroke android:width="3dp"
android:color="#0FECFF"/>
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
b[i].setBackgroundResource(R.drawable.bkg);
Snap Shot
Edit:
int colors []= {Color.RED, Color.BLACK, Color.BLUE,Color.GREEN};
Random r = new Random();
for (int i = 0; i < colors.length; i++) {
b[i].setBackgroundColor(colors[r.nextInt(3)]);
}
look at Document . view.setBackgroundDrawable(drawable) and b[i].setBackgroundColor(c); you can't use both at a time. it will take to effect last one only.