12

How can I set backgrounds for each key on the android keyboard. KeyboardView android:keyBackground provides one background for all keys. But I want to set different backgrounds for every key.

asked Jul 6, 2010 at 10:01
1
  • You had any succes with settings custom keybackgrounds for a single key on the keyboard? Commented Jun 23, 2012 at 16:37

4 Answers 4

9

I custom MyKeyBoradView extend the KeyBoardView and override the onDraw method.

public class MyKeyBoardView extends KeyboardView {
 private Context mContext;
 private Keyboard mKeyBoard;
 public MyKeyBoardView(Context context, AttributeSet attrs) {
 super(context, attrs);
 this.mContext = context;
 }
 public MyKeyBoardView(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 this.mContext = context;
 }
 /**
 * ov
 */
 @Override
 public void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 mKeyBoard = this.getKeyboard();
 List<Key> keys = null;
 if (mKeyBoard != null) {
 keys = mKeyBoard.getKeys();
 }
 if (keys != null) {
 for (Key key : keys) {
 // TODO: 16/8/23 different key set the different background
 if (key.codes[0] == -4) {
 drawKeyBackground(R.drawable.bg_keyboardview_yes, canvas, key);
 drawText(canvas, key);
 }
 }
 }
 }
 private void drawKeyBackground(int drawableId, Canvas canvas, Key key) {
 Drawable npd = mContext.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);
 }
 private void drawText(Canvas canvas, Key key) {
 Rect bounds = new Rect();
 Paint paint = new Paint();
 paint.setTextAlign(Paint.Align.CENTER);
 paint.setAntiAlias(true);
 paint.setColor(Color.WHITE);
 if (key.label != null) {
 String label = key.label.toString();
 Field field;
 if (label.length() > 1 && key.codes.length < 2) {
 int labelTextSize = 0;
 try {
 field = KeyboardView.class.getDeclaredField("mLabelTextSize");
 field.setAccessible(true);
 labelTextSize = spToPx((int) field.get(this));
 } catch (NoSuchFieldException e) {
 e.printStackTrace();
 } catch (IllegalAccessException e) {
 e.printStackTrace();
 }
 paint.setTextSize(labelTextSize);
 paint.setTypeface(Typeface.DEFAULT_BOLD);
 } else {
 int keyTextSize = 0;
 try {
 field = KeyboardView.class.getDeclaredField("mLabelTextSize");
 field.setAccessible(true);
 keyTextSize = spToPx((int) field.get(this));
 } catch (NoSuchFieldException e) {
 e.printStackTrace();
 } catch (IllegalAccessException e) {
 e.printStackTrace();
 }
 paint.setTextSize(keyTextSize);
 paint.setTypeface(Typeface.DEFAULT);
 }
 paint.getTextBounds(key.label.toString(), 0, key.label.toString()
 .length(), bounds);
 canvas.drawText(key.label.toString(), key.x + (key.width / 2),
 (key.y + key.height / 2) + bounds.height() / 2, paint);
 } else if (key.icon != null) {
 key.icon.setBounds(key.x + (key.width - key.icon.getIntrinsicWidth()) / 2, key.y + (key.height - key.icon.getIntrinsicHeight()) / 2,
 key.x + (key.width - key.icon.getIntrinsicWidth()) / 2 + key.icon.getIntrinsicWidth(), key.y + (key.height - key.icon.getIntrinsicHeight()) / 2 + key.icon.getIntrinsicHeight());
 key.icon.draw(canvas);
 }
 }
 public int spToPx(float sp) {
 return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getContext().getResources().getDisplayMetrics());
 }
}

The realization effect is as follows enter image description here

This links:https://github.com/xuejinwei/NumberKeyboard

ChrisMM
10.2k21 gold badges41 silver badges60 bronze badges
answered Aug 23, 2016 at 3:30
Sign up to request clarification or add additional context in comments.

Comments

5

If you are writing your own IME, try using a drawable for the FOREground image (with android:keyIcon in XML or Key.icon in Java) that is equal to the size of the entire key. This is essentially equivalent to setting the background image of a single key. Of course you will also have to include the foreground in your image.

You will also have to use a background image with no padding, so it doesn't peek around the edges. See this posting for details on how to do this: how does a 9patch png work in android apps

Barry

answered May 28, 2011 at 4:50

Comments

2

I've been trying to do this too. The key background is drawn in onBufferDraw() in KeyboardView class. Problem is it is a private method, so you can't override it with a subclass. So I tried copying KeyboardView altogether and modifying that, but it uses com.android.internal.R resources, which an external app doesn't have access. So that approach doesn't work.

At this point it's starting to look like I have to throw Android's Keyboard classes out the window and write the whole thing from scratch --all b/c I can't get change the background image of the space key. Ridiculous.

answered Mar 21, 2011 at 20:48

Starting from scratch is not that difficult. In fact you can just copy/paste KeyboardView.java from the open source into a new subclass of KeyboardView, and start customizing it to suit your purposes.
Many classes in Android are that impossible to customize. It would be much easier to accomplish if Android's architecture used delegates (or listeners) and permitted the replacement of helper classes at more points.
I suggest copy/pasting KeyboardView.java into your own custom keyboard view class. That way you get all the functionality pre-written and you can override anything you need to. That's what I did.
-1

Perhaps you could define a new Input Method.

answered Jul 6, 2010 at 18:21

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.