欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-08-13 14:58:05
在项目中,产品对于输入方式会有特殊的要求,需要对输入方式增加特定的限制,这就需要采用自定义键盘。本文主要讲述数字键盘和字母键盘的自定义实现。 项目地址: 键盘效...

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

项目地址:

键盘效果:

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

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

  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资源文件可以从以下链接获取:
数字键盘xmllayoutres
字母键盘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效果如下:

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

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

创建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,有需要的用户也可以直接修改项目的源码。

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