Android编程实现自定义输入法功能示例【输入密码时防止第三方窃取】

发布时间 - 2026-01-10 22:41:54    点击率:

本文实例讲述了Android编程实现自定义输入法功能。分享给大家供大家参考,具体如下:

对于Android用户而言,一般都会使用第三方的输入法。可是,在输入密码时(尤其是支付相关的密码),使用第三方输入法有极大的安全隐患。目前很多网银类的APP和支付宝等软件在用户输入密码时,都会弹出自定义的输入法而不是直接使用系统输入法。

这里介绍的就是如何实现一个简单的自定义输入法。当然,也可以自己写一个Dialog加上几十个按钮让用户输入,只不过这样显得不够专业。

(一)首先上效果图:

1.前面两个输入框使用了自定义的输入法:

2.第三个输入框没有进行任何设置,因此将使用默认的输入法:

(二)代码简介:

1.主页面布局,由3个输入框加上一个android.inputmethodservice.KeyboardView组成。android.inputmethodservice.KeyboardView是一个系统自带的继承自View的组件,但是它不在android.view这个包下面,因此这里需要写上完整的包名。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <!--前两个EditText均使用自定义的输入法-->
  <EditText
    android:id="@+id/input_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:hint="one password"
    android:layout_alignParentTop="true"
    android:inputType="textPassword" />
  <EditText
    android:id="@+id/input_password2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/input_password"
    android:layout_margin="8dp"
    android:hint="another password"
    android:inputType="textPassword" />
  <!--这个EditText使用默认的输入法-->
  <EditText
    android:id="@+id/input_normal_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/input_password2"
    android:layout_margin="8dp"
    android:hint="normal text" />
  <android.inputmethodservice.KeyboardView
    android:id="@+id/keyboardview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:visibility="gone" />
</RelativeLayout>

2.KeyboardView是一个显示输入法的容器控件,使用时需要设置具体的输入法面板内容。

(1)首先在res下新建xml目录,然后创建文件keys_layout.xml,即输入法面板的内容。每个row表示一行,Keyboad的属性keyWidth和keyHeight表示每个按键的大小,25%p表示占父组件的25%. Key的属性codes表示该按键的编号(点击时系统回调方法中会返回这个值,用以区分不同的按键),keyLabel表示按键上面显示的文字。还有很多其它的属性,不再陈述。

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
  android:keyWidth="25%p"
  android:keyHeight="10%p">
  <Row>
    <Key
      android:codes="55"
      android:keyLabel="7"
      android:keyEdgeFlags="left" />
    <Key
      android:codes="56"
      android:keyLabel="8" />
    <Key
      android:codes="57"
      android:keyLabel="9" />
    <!--删除按键长按时连续响应-->
    <Key
      android:codes="60001"
      android:keyLabel="DEL"
      android:isRepeatable="true" />
  </Row>
  <Row>
    <Key
      android:codes="52"
      android:keyLabel="4"
      android:keyEdgeFlags="left" />
    <Key
      android:codes="53"
      android:keyLabel="5" />
    <Key
      android:codes="54"
      android:keyLabel="6" />
    <Key
      android:codes="48"
      android:keyLabel="0" />
  </Row>
  <Row>
    <Key
      android:codes="49"
      android:keyLabel="1"
      android:keyEdgeFlags="left" />
    <Key
      android:codes="50"
      android:keyLabel="2" />
    <Key
      android:codes="51"
      android:keyLabel="3" />
    <Key
      android:codes="60002"
      android:keyLabel="Cancel" />
  </Row>
</Keyboard>

(2)为了使用方便,新建一个类:KeyboardBuilder.java,用于初始化自定义输入法和绑定EditText,代码如下:

public class KeyboardBuilder {
  private static final String TAG = "KeyboardBuilder";
  private Activity mActivity;
  private KeyboardView mKeyboardView;
  public KeyboardBuilder(Activity ac, KeyboardView keyboardView, int keyBoardXmlResId) {
    mActivity = ac;
    mKeyboardView = keyboardView;
    Keyboard mKeyboard = new Keyboard(mActivity, keyBoardXmlResId);
    // Attach the keyboard to the view
    mKeyboardView.setKeyboard(mKeyboard);
    // Do not show the preview balloons
    mKeyboardView.setPreviewEnabled(false);
    KeyboardView.OnKeyboardActionListener keyboardListener = new KeyboardView.OnKeyboardActionListener() {
      @Override
      public void onKey(int primaryCode, int[] keyCodes) {
        // Get the EditText and its Editable
        View focusCurrent = mActivity.getWindow().getCurrentFocus();
        if (focusCurrent == null || !(focusCurrent instanceof EditText)) {
          return;
        }
        EditText edittext = (EditText) focusCurrent;
        Editable editable = edittext.getText();
        int start = edittext.getSelectionStart();
        // Handle key
        if (primaryCode == Constant.CodeCancel) {
          hideCustomKeyboard();
        } else if (primaryCode == Constant.CodeDelete) {
          if (editable != null && start > 0) {
            editable.delete(start - 1, start);
          }
        } else {
          // Insert character
          editable.insert(start, Character.toString((char) primaryCode));
        }
      }
      @Override
      public void onPress(int arg0) {
      }
      @Override
      public void onRelease(int primaryCode) {
      }
      @Override
      public void onText(CharSequence text) {
      }
      @Override
      public void swipeDown() {
      }
      @Override
      public void swipeLeft() {
      }
      @Override
      public void swipeRight() {
      }
      @Override
      public void swipeUp() {
      }
    };
    mKeyboardView.setOnKeyboardActionListener(keyboardListener);
  }
  //绑定一个EditText
  public void registerEditText(EditText editText) {
    // Make the custom keyboard appear
    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
      @Override
      public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
          showCustomKeyboard(v);
        } else {
          hideCustomKeyboard();
        }
      }
    });
    editText.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Log.d(TAG, "onClick");
        showCustomKeyboard(v);
      }
    });
    editText.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        Log.d(TAG, "onTouch");
        EditText edittext = (EditText) v;
        int inType = edittext.getInputType();    // Backup the input type
        edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
        edittext.onTouchEvent(event);        // Call native handler
        edittext.setInputType(inType);       // Restore input type
        edittext.setSelection(edittext.getText().length());
        return true;
      }
    });
  }
  public void hideCustomKeyboard() {
    mKeyboardView.setVisibility(View.GONE);
    mKeyboardView.setEnabled(false);
  }
  public void showCustomKeyboard(View v) {
    mKeyboardView.setVisibility(View.VISIBLE);
    mKeyboardView.setEnabled(true);
    if (v != null) {
      ((InputMethodManager) mActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
  }
  public boolean isCustomKeyboardVisible() {
    return mKeyboardView.getVisibility() == View.VISIBLE;
  }
}

3.最后是主Activity的代码,这里就很简单了。

/**
 * 自定义安全输入法
 */
public class MainActivity extends ActionBarActivity {
  private KeyboardBuilder builder;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboardview);
    builder = new KeyboardBuilder(this, keyboardView, R.xml.keys_layout);
    EditText editText = (EditText) findViewById(R.id.input_password);
    builder.registerEditText(editText);
    EditText editText2 = (EditText) findViewById(R.id.input_password2);
    builder.registerEditText(editText2);
  }
  @Override
  public void onBackPressed() {
    if (builder != null && builder.isCustomKeyboardVisible()) {
      builder.hideCustomKeyboard();
    } else {
      this.finish();
    }
  }
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android视图View技巧总结》、《Android开发动画技巧汇总》、《Android编程之activity操作技巧总结》、《Android布局layout技巧总结》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


# Android  # 自定义  # 输入法  # Android文本输入框(EditText)输入密码时显示与隐藏  # Android 实现密码输入框动态明文/密文切换显示效果  # Android程序开发之防止密码输入错误 密码明文显示功能  # Android实现动态显示或隐藏密码输入框的内容  # Android仿支付宝支付密码输入框  # Android 自定义输入支付密码的软键盘实例代码  # Android仿支付宝、京东的密码键盘和输入框  # Android自定义View仿支付宝输入六位密码功能  # Android的支付密码输入框实现浅析  # Android高仿微信支付密码输入控件  # Android仿微信/支付宝密码输入框  # Android编程实现打勾显示输入密码功能  # 是一个  # 输入框  # 第三方  # 绑定  # 输入密码  # 进阶  # 操作技巧  # 相关内容  # 尤其是  # 感兴趣  # 给大家  # 很简单  # 弹出  # 第三个  # 更多关于  # 还有很多  # 所述  # 写上  # 几十个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何挑选最适合建站的高性能VPS主机?  Laravel如何实现一对一模型关联?(Eloquent示例)  如何快速查询域名建站关键信息?  免费网站制作appp,免费制作app哪个平台好?  油猴 教程,油猴搜脚本为什么会网页无法显示?  Laravel API资源类怎么用_Laravel API Resource数据转换  用yum安装MySQLdb模块的步骤方法  HTML 中如何正确使用模板变量为元素的 name 属性赋值  如何在Windows环境下新建FTP站点并设置权限?  Python结构化数据采集_字段抽取解析【教程】  如何用IIS7快速搭建并优化网站站点?  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】  Laravel PHP版本要求一览_Laravel各版本环境要求对照  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  Laravel如何配置Horizon来管理队列?(安装和使用)  如何在万网自助建站平台快速创建网站?  Python3.6正式版新特性预览  Python文件异常处理策略_健壮性说明【指导】  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  如何获取PHP WAP自助建站系统源码?  如何确保西部建站助手FTP传输的安全性?  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  如何解决hover在ie6中的兼容性问题  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】  如何基于云服务器快速搭建网站及云盘系统?  如何在云服务器上快速搭建个人网站?  PHP正则匹配日期和时间(时间戳转换)的实例代码  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  如何登录建站主机?访问步骤全解析  音乐网站服务器如何优化API响应速度?  如何快速搭建高效可靠的建站解决方案?  如何快速搭建高效WAP手机网站吸引移动用户?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  详解vue.js组件化开发实践  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】