当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义键盘的实现(数字键盘和字母键盘)

Android自定义键盘的实现(数字键盘和字母键盘)

2019年07月24日  | 移动技术网IT编程  | 我要评论

甜味白开水,藏书妹,5号特工组2

在项目中,产品对于输入方式会有特殊的要求,需要对输入方式增加特定的限制,这就需要采用自定义键盘。本文主要讲述数字键盘和字母键盘的自定义实现。

项目地址:

键盘效果:

自定义键盘的实现步骤如下:

  1. 自定义customkeyboard, 继承自系统keyboard,实现keyboardview.onkeyboardactionlistener相关接口,以处理用户的点击回调;
  2. 自定义customkeyboardview, 继承自keyboardview,实现自定义键盘绘制;
  3. 创建keyboardmanager, 用于处理自定义键盘的显示以及和输入ui的交互

自定义customkeyboard

android系统keyboard的构造方法如下:

 /**
   * creates a keyboard from the given xml key layout file.
   * @param context the application or service context
   * @param xmllayoutresid the resource file that contains the keyboard layout and keys.
   */
  public keyboard(context context, int xmllayoutresid) {
    this(context, xmllayoutresid, 0);
  }

  /**
   * creates a keyboard from the given xml key layout file. weeds out rows
   * that have a keyboard mode defined but don't match the specified mode.
   * @param context the application or service context
   * @param xmllayoutresid the resource file that contains the keyboard layout and keys.
   * @param modeid keyboard mode identifier
   * @param width sets width of keyboard
   * @param height sets height of keyboard
   */
  public keyboard(context context, @xmlres int xmllayoutresid, int modeid, int width,
      int height) {
      ...
  }

其中,参数xmllayoutresid是必须的,另外还可以通过计算系统键盘的高度来设定自定义键盘的高度。

xmllayoutres的格式如下:

<?xml version="1.0" encoding="utf-8"?>
<keyboard android:keywidth="24.9%p"
     android:keyheight="49dp"
     android:horizontalgap="0.1333%p"
     android:verticalgap="1px"
     xmlns:android="http://schemas.android.com/apk/res/android">
  <row>
    <key android:codes="49" android:keyedgeflags="left"
       android:keylabel="1" />
    <key android:codes="50" android:keylabel="2" />
    <key android:codes="51" android:keylabel="3" />
    <key android:codes="-5" android:iconpreview="@drawable/key_num_del_bg"
       android:isrepeatable="true"/>
  </row>
  ...
</keyboard>

详细的数字键盘和字母键盘xmllayoutres资源文件可以从以下链接获取:

customkeyboard主要目的就是赋予xmllayoutres并实现特定按键的点击处理,其主要重载的方法是onkey(int primarycode, int[] keycodes)。详细代码如下:

public abstract class basekeyboard extends keyboard implements keyboardview.onkeyboardactionlistener{

 @override
 public void onkey(int primarycode, int[] keycodes) {
    if(null != medittext && medittext.hasfocus() && !handlespecialkey(primarycode)) {
      editable editable = medittext.gettext();
      int start = medittext.getselectionstart();
      int end = medittext.getselectionend();
      if (end > start){
        editable.delete(start,end);
      }
      if(primarycode == keycode_delete) {
        if(!textutils.isempty(editable)) {
          if(start > 0) {
            editable.delete(start-1,start);
          }
        }
      }else if(primarycode == getkeycode(r.integer.hide_keyboard)){
        hidekeyboard();
      }else {
        editable.insert(start,character.tostring((char) primarycode));
      }
    }
  }

 public abstract boolean handlespecialkey(int primarycode);
}

如上所示是basekeyboard,数字键盘和字母键盘需要继承它,并实现public abstract boolean handlespecialkey(int primarycode)方法。

自定义customkeyboardview

keyboardview 是承载不同的keyboard并绘制keyboard, 是键盘布局的绘制板, 并与系统交互。通过继承keyboardview自定义customkeyboardview,可以对按键样式实现自定义。考察keyboardview的源码,发现其ui样式都是private类型,这就需要通过反射的方式获取特定的ui属性,并重新进行赋值,同时重载ondraw()方法,在ondraw()中重新绘制。

详细代码可以参考github源码: basekeyboardview源码

自定义键盘的ui效果如下:


数字键盘


字母键盘

创建keyboardmanager

主要处理以下功能逻辑:

  1. 绑定edittext和keyboard,监听edittext的onfocuschangelistener,处理键盘弹出和键盘掩藏;
  2. 处理系统键盘和自定义键盘之间的切换关系;
  3. 处理键盘区域其他自定义view的显示,比如需要让键盘自动搜索功能时,可在manager中进行相关处理

以绑定edittext为例:

public void bindtoeditor(edittext edittext, basekeyboard keyboard) {
  hidesystemsoftkeyboard(edittext);
  edittext.settag(r.id.bind_keyboard_2_editor, keyboard);
  if (keyboard.getkeystyle() == null) {
    keyboard.setkeystyle(mdefaultkeystyle);
  }
  edittext.setonfocuschangelistener(editorfocuschangelistener);
}

private final view.onfocuschangelistener editorfocuschangelistener = new view.onfocuschangelistener() {
  @override
  public void onfocuschange(final view v, boolean hasfocus) {
    if (v instanceof edittext) {
      if (hasfocus) {
       v.postdelayed(new runnable() {
          @override
          public void run() {
            showsoftkeyboard((edittext) v);
          }
        },300);
      } else {
        hidesoftkeyboard();
      }
    }
  }
};

public void showsoftkeyboard(edittext edittext) {
  mrootview.addonlayoutchangelistener(monlayoutchangelistener);
  basekeyboard keyboard = getbindkeyboard(edittext);
  if (keyboard == null) {
    log.e(tag, "edit text not bind to keyboard");
    return;
  }
  keyboard.setedittext(edittext);
  keyboard.setnextfocusview(mkeyboardwithsearchview.getedittext());
  initkeyboard(keyboard);
  ...
}

键盘的使用方式非常简单, 通过keyboardmanager实现调用

数字键盘:

keyboardmanager keyboardmanagernumber = new keyboardmanager(this);
keyboardmanagernumber.bindtoeditor(edittext2, new numberkeyboard(context,numberkeyboard.default_number_xml_layout));

字母键盘:

keyboardmanager keyboardmanagerabc = new keyboardmanager(this);
keyboardmanagerabc.bindtoeditor(edittext1, new abckeyboard(context, abckeyboard.default_abc_xml_layout));

至此,自定义键盘的实现就介绍完了,文中介绍的更多还是实现的思路,具体实现可以参考github,有需要的用户也可以直接修改项目的源码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网