I am Creating custom keyboard. I am using KeyboardView for custom keyboard. I am trying to change the keys background color. While I am setting by xml it is working fine. But When I try with java code it is not working as expected. Here is my code.
@Override
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
List<Keyboard.Key> keys = getKeyboard().getKeys();
for (Keyboard.Key key : keys) {
if (key.codes[0] == 53) {
// drawKeyBackground(canvas, key);
drawKeyBackground(R.drawable.samplekeybackground,canvas,key);
drawText(canvas, key);
}
}
}
private void drawKeyBackground(int drawableId, Canvas canvas, Keyboard.Key key) {
Drawable npd = context.getResources().getDrawable(
drawableId);
int[] drawableState = key.getCurrentDrawableState();
if (key.codes[0] != 0) {
npd.setState(drawableState);
}
npd.setBounds(key.x, key.y, key.x + key.width, key.y
+ key.height);
npd.draw(canvas);
}
This code is working fine. But I am trying to change samplekeybackground.xml to java code.
public StateListDrawable getSelectorDrawable() {
StateListDrawable out = new StateListDrawable();
out.addState(new int[] { android.R.attr.state_pressed }, createDrawable(Color.GREEN));
out.addState(new int[] { android.R.attr.state_focused }, createDrawable(Color.GREEN));
out.addState(new int[] { android.R.attr.state_enabled }, createDrawable(Color.BLUE));
return out;
}
public GradientDrawable createDrawable(int color) {
GradientDrawable out = new GradientDrawable();
out.setShape(GradientDrawable.RECTANGLE);
out.setGradientType(GradientDrawable.LINEAR_GRADIENT);
out.setColor(color);
out.setStroke(2, color);
out.setCornerRadius(0F);
return out;
}
Finally call the method by following code:
private void drawKeyBackground(Canvas canvas, Keyboard.Key key) {
Drawable npd = getSelectorDrawable();
int[] drawableState = key.getCurrentDrawableState();
if (key.codes[0] != 0) {
npd.setState(drawableState);
}
npd.setBounds(key.x, key.y, key.x + key.width, key.y
+ key.height);
npd.draw(canvas);
}
But when I click the key pressed_state color is working. But normal state is not working.
Please help me to resolve this issue.
Gracefully this class solved my issue.
public class StateDrawableBuilder {
private static final int[] STATE_SELECTED = new int[]{android.R.attr.state_selected};
private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed};
private static final int[] STATE_ENABED = new int[]{android.R.attr.state_enabled};
private static final int[] STATE_DISABED = new int[]{-android.R.attr.state_enabled};
private static final int[] STATE_NORMAL = new int[]{};
private Drawable normalDrawable;
private Drawable selectedDrawable;
private Drawable pressedDrawable;
private Drawable disabledDrawable;
public StateDrawableBuilder setNormalDrawable(Drawable normalDrawable) {
this.normalDrawable = normalDrawable;
return this;
}
public StateDrawableBuilder setPressedDrawable(Drawable pressedDrawable) {
this.pressedDrawable = pressedDrawable;
return this;
}
public StateDrawableBuilder setSelectedDrawable(Drawable selectedDrawable) {
this.selectedDrawable = selectedDrawable;
return this;
}
public StateDrawableBuilder setDisabledDrawable(Drawable disabledDrawable) {
this.disabledDrawable = disabledDrawable;
return this;
}
public StateListDrawable build() {
StateListDrawable stateListDrawable = new StateListDrawable();
if (this.selectedDrawable != null) {
stateListDrawable.addState(STATE_SELECTED, this.selectedDrawable);
}
if (this.pressedDrawable != null) {
stateListDrawable.addState(STATE_PRESSED, this.pressedDrawable);
}
if (this.normalDrawable != null) {
stateListDrawable.addState(STATE_NORMAL, this.normalDrawable);
}
if (this.disabledDrawable != null) {
stateListDrawable.addState(STATE_DISABED, this.disabledDrawable);
}
return stateListDrawable;
}
public static Drawable getShapeDrawable(int color,int rad,int border,int borderColor){
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setColor(color);
gradientDrawable.setStroke(border,borderColor);
return gradientDrawable;
}
private ShapeDrawable getShapeDrawable(int color,int rad,int border) {
RoundRectShape roundRectShape = new RoundRectShape(new float[]{
rad, rad, rad, rad,
rad, rad, rad, rad}, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
shapeDrawable.getPaint().setColor(color);
shapeDrawable.getPaint().setStrokeWidth(border);
return shapeDrawable;
}
}
and use the builder like following.
StateListDrawable npd = new StateDrawableBuilder()
.setNormalDrawable(StateDrawableBuilder.getShapeDrawable(Color.RED,10,5,Color.BLUE))
.setPressedDrawable(StateDrawableBuilder.getShapeDrawable(Color.GREEN,10,5,Color.BLUE))
.setSelectedDrawable(StateDrawableBuilder.getShapeDrawable(Color.GREEN,10,5,Color.BLUE))
.build();
Now KeyboardView key bg color and focus color is working as expected..