title: Create a custom keypad in android
body: <p>I want to create a custom keypad in my android app that looks like this:</p>
  
  <p><a href="https://www.dropbox.com/s/vwiz4o3pd8q4o81/2015-06-14%2014.53.02.jpg?dl=0" rel="nofollow">https://www.dropbox.com/s/vwiz4o3pd8q4o81/2015-06-14%2014.53.02.jpg?dl=0</a></p>
  
  <p>I have tried to use keyboardview but cannot get what I want. I have also looked at tutorials online on custom keypads but none seems to give hints on how to make the keypad I desire. I have tried putting png images as the backgrounds for the keypad but this has not helped. So far i have made this:</p>
  
  <p><a href="https://www.dropbox.com/s/xrm4v941ofecmut/2015-06-14%2014.54.10.jpg?dl=0" rel="nofollow">https://www.dropbox.com/s/xrm4v941ofecmut/2015-06-14%2014.54.10.jpg?dl=0</a> </p>
  
  <p>Can I get help or links to tutorials and code that will help solve my problem.</p>
  
  <p>This is my current code:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
      android:keyWidth="14.25%p"
      android:hapticFeedbackEnabled="true"
      android:keyHeight="8.5%p"&gt;
  &lt;!--
      android:horizontalGap="0.50%p"
      android:verticalGap="0.50%p"
      NOTE When we add a horizontalGap in pixels, this interferes with keyWidth in percentages adding up to 100%
      NOTE When we have a horizontalGap (on Keyboard level) of 0, this make the horizontalGap (on Key level) to move from after the key to before the key... (I consider this a bug) 
   --&gt;
      &lt;Row&gt;
              &lt;Key android:codes="-1"     android:keyLabel="EVALUATE" android:keyWidth="42.75%p"  android:keyEdgeFlags="left"   /&gt;
              &lt;Key android:codes="-100"     android:keyLabel="RESET" android:keyWidth="28.50%p"     /&gt;
              &lt;Key android:codes="-1000"     android:keyLabel="\u24D8" android:keyWidth="28.50%p"    android:keyEdgeFlags="right"  /&gt;
      &lt;/Row&gt; 
  
      &lt;Row&gt;
          &lt;Key android:codes="1"      android:keyLabel="sin"     android:keyEdgeFlags="left" /&gt;
          &lt;Key android:codes="2"      android:keyLabel="cos"  /&gt;
          &lt;Key android:codes="3"      android:keyLabel="tan"  /&gt;
          &lt;Key android:codes="36"     android:keyLabel="sinh"        /&gt;
          &lt;Key android:codes="37"     android:keyLabel="cosh"     /&gt;
          &lt;Key android:codes="38"     android:keyLabel="tanh"   /&gt;
          &lt;Key android:codes="-2"     android:keyIcon="@drawable/delete_symbol"        android:isRepeatable="true"     android:keyEdgeFlags="right"/&gt;
      &lt;/Row&gt;   
  
      &lt;Row&gt;
          &lt;Key android:codes="4"      android:keyLabel="asin"      android:keyEdgeFlags="left" /&gt;
          &lt;Key android:codes="5"      android:keyLabel="acos"    /&gt;
          &lt;Key android:codes="6"      android:keyLabel="atan"  /&gt;
          &lt;Key android:codes="42"     android:keyLabel="asinh"        /&gt;
          &lt;Key android:codes="43"     android:keyLabel="acosh"     /&gt;
          &lt;Key android:codes="44"     android:keyLabel="atanh"   /&gt;
          &lt;Key android:codes="21"     android:keyLabel="\u00F7"   android:keyEdgeFlags="right" /&gt;   
      &lt;/Row&gt;
      &lt;Row&gt;
          &lt;Key android:codes="7"      android:keyLabel="cosec"       android:keyEdgeFlags="left" /&gt;
          &lt;Key android:codes="8"      android:keyLabel="sec"      /&gt;
          &lt;Key android:codes="9"      android:keyLabel="cot"      /&gt;
          &lt;Key android:codes="33"     android:keyLabel="7"        /&gt;
          &lt;Key android:codes="34"     android:keyLabel="8"       /&gt;
          &lt;Key android:codes="35"     android:keyLabel="9"      /&gt;
          &lt;Key android:codes="20"     android:keyLabel="\u00D7"    android:keyEdgeFlags="right" /&gt;   
      &lt;/Row&gt;
      &lt;Row&gt;
          &lt;Key android:codes="11"     android:keyLabel="e^("    /&gt;
          &lt;Key android:codes="12"     android:keyLabel="ln("   /&gt;
          &lt;Key android:codes="22"     android:keyLabel="x\u207F" /&gt;
          &lt;Key android:codes="30"     android:keyLabel="4"       /&gt;
          &lt;Key android:codes="31"     android:keyLabel="5"        /&gt;
          &lt;Key android:codes="32"     android:keyLabel="6"     /&gt;
          &lt;Key android:codes="19"     android:keyLabel="\u2212"   android:keyEdgeFlags="right" /&gt;
      &lt;/Row&gt;
      &lt;Row&gt;
          &lt;Key android:codes="14"     android:keyLabel="k"        android:keyEdgeFlags="left" /&gt;
          &lt;Key android:codes="15"     android:keyLabel="\u03C0"  /&gt;
          &lt;Key android:codes="13"     android:keyIcon="@drawable/italic_x"  /&gt;
          &lt;Key android:codes="27"     android:keyLabel="1"         /&gt;
          &lt;Key android:codes="28"     android:keyLabel="2"        /&gt;
          &lt;Key android:codes="29"     android:keyLabel="3"      /&gt;
          &lt;Key android:codes="18"     android:keyLabel="+"     android:keyEdgeFlags="right" /&gt;
      &lt;/Row&gt;
      &lt;Row&gt;
          &lt;Key android:codes="-3"     android:keyIcon="@drawable/keyboard_done"  android:keyWidth="28.5%p" android:keyEdgeFlags="left"   /&gt;   
          &lt;Key android:codes="10"     android:keyLabel="\u221a"  /&gt;
          &lt;Key android:codes="16"     android:keyLabel="("         /&gt;
          &lt;Key android:codes="26"     android:keyLabel="0"      /&gt;
          &lt;Key android:codes="17"     android:keyLabel=")"   /&gt;  
          &lt;Key android:codes="23"     android:keyLabel="." android:keyEdgeFlags="right" /&gt;
      &lt;/Row&gt;
  
  &lt;/Keyboard&gt;
  </code></pre>
  
  <p>The code with the java handler for the xml file is:</p>
  
  <pre><code>class CustomKeyboard {
  
  private Activity  mHostActivity;
  
  private Button doneButton = null;
  private Button clearButton = null;
  private Button infoButton = null;
  
  /** The key (code) handler. */
  private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
  
  public final static int CodeEvaluate  = -1;
  public final static int CodeClear  = -100;
  public final static int CodeInfo  = -1000;
  public final static int CodeDelete    = -2; // Keyboard.KEYCODE_DELETE
  public final static int CodeHide      = -3; // Keyboard.KEYCODE_CANCEL
  
  public final static int CodeMINIMUM   = 0;
  public final static int CodeSin       = 1;
  public final static int CodeCos       = 2;
  public final static int CodeTan       = 3;
  public final static int CodeAsin      = 4;
  public final static int CodeAcos      = 5;
  public final static int CodeAtan      = 6;
  public final static int CodeCosec     = 7;
  public final static int CodeSec       = 8;
  public final static int CodeCot       = 9;
  public final static int CodeSqrt      = 10;
  public final static int CodeExp       = 11;
  public final static int CodeLn        = 12;
  public final static int CodeX         = 13;
  public final static int CodeK         = 14;
  public final static int CodePI        = 15;
  public final static int CodeOpenB     = 16;
  public final static int CodeCloseB    = 17;
  public final static int CodePlus      = 18;
  public final static int CodeMinus     = 19;
  public final static int CodeMultiply  = 20;
  public final static int CodeDivide    = 21;
  public final static int CodePower     = 22;
  public final static int CodePoint     = 23;
  public final static int CodeABC       = 24;
  public final static int CodeSpace     = 25;
  
  public final static int CodeMAXIMUM   = 50;   // maximum number of Keys
  
  public String[] keyCodeToText = null;
  
  public void keysInitialise()
  {
  if(keyCodeToText==null) keyCodeToText = new String[CodeMAXIMUM];
  keyCodeToText[CodeSin]      = "sin(";
  keyCodeToText[CodeCos]      = "cos(";
  keyCodeToText[CodeTan]      = "tan(";
  keyCodeToText[CodeAsin]     = "asin(";
  keyCodeToText[CodeAcos]     = "acos(";
  keyCodeToText[CodeAtan]     = "atan(";
  keyCodeToText[CodeCosec]    = "cosec(";
  keyCodeToText[CodeSec]      = "sec(";
  keyCodeToText[CodeCot]      = "cot(";
  keyCodeToText[CodeSqrt]     = "sqrt(";
  keyCodeToText[CodeExp]      = "e^(";
  keyCodeToText[CodeLn]       = "ln(";
  keyCodeToText[CodeX]        = "x";
  keyCodeToText[CodeK]        = "k";
  keyCodeToText[CodePI]       = "pi";
  keyCodeToText[CodeOpenB]    = "(";
  keyCodeToText[CodeCloseB]   = ")";
  keyCodeToText[CodePlus]     = "+";
  keyCodeToText[CodeMinus]    = "-";
  keyCodeToText[CodeMultiply] = "*";
  keyCodeToText[CodeDivide]   = "/";
  keyCodeToText[CodePower]    = "^";
  keyCodeToText[CodePoint]    = ".";
  keyCodeToText[CodeABC  ]    = "";
  }
  
  
  @Override 
  public void onKey(int primaryCode, int[] keyCodes) {
  
  // Get the EditText and its Editable
  View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
  if( focusCurrent==null || focusCurrent.getClass()!=EditText.class )    return;
  
  EditText edittext = (EditText) focusCurrent;
  Editable editable = edittext.getText();
  int start = edittext.getSelectionStart();
  
  keysInitialise();
  
  // Apply the key to the edittext
  if(primaryCode == CodeEvaluate) {
  if(doneButton != null) doneButton.performClick();
  }
  else if (primaryCode == CodeClear){
  if(clearButton != null) clearButton.performClick();
  }
  else if (primaryCode == CodeInfo){
  if(infoButton != null) infoButton.performClick();
  }
  else if(primaryCode ==CodeDelete) {
  if( editable!=null &amp;&amp; start&gt;0 ) editable.delete(start - 1, start);
  }
  else if(primaryCode == CodeHide) {
  hideCustomKeyboard();
  }
  else if(primaryCode &gt; CodeMINIMUM &amp;&amp; primaryCode &lt; CodeMAXIMUM) {
  editable.insert(start, keyCodeToText[primaryCode]);
  }
  else editable.insert(start, Integer.toString(primaryCode));
  }
  
  @Override public void onPress(int arg0) {
  }
  
  @Override public void onRelease(int primaryCode) {
  }
  
  @Override public void onText(CharSequence text) {
  }
  
  public CustomKeyboard(Activity host, int viewid, int layoutid) {
  mHostActivity= host;
  mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid);
  mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
  mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
  mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
  }
  
  /** Returns whether the CustomKeyboard is visible. */
  public boolean isCustomKeyboardVisible() {
      return mKeyboardView.getVisibility() == View.VISIBLE;
  }
  
  /** Make the CustomKeyboard visible, and hide the system keyboard for the given view. */
  public void showCustomKeyboard(View v) {
  mKeyboardView.setVisibility(View.VISIBLE);
  mKeyboardView.setEnabled(true);
  }
  
  /** Make the CustomKeyboard invisible. */
  public void hideCustomKeyboard() {
  mKeyboardView.setVisibility(View.GONE);
  mKeyboardView.setEnabled(false);
  }
  
  /** Hide standard keyboard */
  private void hideStandardKeyboard(View v) {
      if(v != null) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
  }
  
  /** Register the doneButton for which doneButton.performClick()
   *  will be called when the "Done" keypad-button is clicked.
   */
  public void registerDoneButton (Button doneButton) {
  this.doneButton = doneButton;
  }
  public void registerClearButton (Button clearButton) {
  this.clearButton = clearButton;
  }
  public void registerInfoButton (Button infoButton) {
  this.infoButton = infoButton;
  }
  /**
  * Register &lt;var&gt;EditText&lt;var&gt; for using this custom keyboard.
  *
  * @param The EditText that registers to the custom keyboard.
  */
  public void registerEditText(EditText edittext) {
  
  // Make the custom keyboard appear or disappear
  edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
  @Override public void onFocusChange(View v, boolean hasFocus) {
  if(hasFocus) showCustomKeyboard(v);
  else hideCustomKeyboard();
  }
  });
  
  edittext.setOnClickListener(new OnClickListener() {
  @Override public void onClick(View v) {
  showCustomKeyboard(v);
  }
  });
  
  edittext.setOnTouchListener(new OnTouchListener() {
  @Override public boolean onTouch(View v, MotionEvent event) {
  ((EditText) v).onTouchEvent(event);
  hideStandardKeyboard(v);
  return true; // Consume touch event
  }
  });
  }
  </code></pre>