android开发(45) 自定义软键盘(输入法)
概述
在项目开发中遇到一个需求,”只要数字键盘的输入,仅仅有大写字母的输入,某些输入法总是会提示更新,弹出广告等“,使得我们需要自定义输入。
关联到的知识
- KeyboardView 一个视图对象,展示了键盘。它需要关联到一个 Keyboard对象才能展示。
- Keyboard 键盘对象,通过加载xml的配置获得键盘的排列。
- xml 文件键盘描述 一个xml文件,放置在 xml 资源文件夹下,描述了 显示的键盘按钮,和排列,键盘宽度和高度等。
具体实现
准备xml键盘描述文件
在xml文件夹下创建文件,下面的代码中使用 “ 33%p” 这样的单位指定一定的 百分比,以适配屏幕,详细内容如下:
<?xml version="1.0" encoding="UTF-8"?><!-- 数字键盘 -->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="0dp"
android:keyHeight="61dp"
android:keyWidth="33%p"
android:verticalGap="0dp">
<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" />
</Row>
<Row>
<Key
android:codes="52"
android:keyEdgeFlags="left"
android:keyLabel="4" />
<Key
android:codes="53"
android:keyLabel="5" />
<Key
android:codes="54"
android:keyLabel="6" />
</Row>
<Row>
<Key
android:codes="55"
android:keyEdgeFlags="left"
android:keyLabel="7" />
<Key
android:codes="56"
android:keyLabel="8" />
<Key
android:codes="57"
android:keyLabel="9" />
</Row>
<Row>
<Key
android:codes="48"
android:keyEdgeFlags="left"
android:keyLabel="0" />
<Key
android:codes="-5"
android:isRepeatable="true"
android:keyIcon="@drawable/keyboard_delete"
android:keyWidth="66%p" />
</Row>
</Keyboard>
创建Keyboard对象
要先配置好xml文件,在构造方法里传入上面的xml文件
this.keyboard = new Keyboard(mActivity, R.xml.small_keyboard);
构造KeyboardView
keyboardView 对象可以在 xml 中描述,类似下面这样
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@drawable/keyboard_key"
android:keyTextColor="@color/white"
android:keyTextSize="@dimen/sp_32"
android:visibility="visible" />
获得 KeyboardView并进行配置,需要关联到具体的 keyboard 对象
KeyboardView keyboardView = (KeyboardView) viewContainer.findViewById(R.id.keyboard_view);
this.keyboardView = keyboardView;
this.keyboardView.setKeyboard(keyboard);
this.keyboardView.setEnabled(true);
this.keyboardView.setPreviewEnabled(false);
this.keyboardView.setOnKeyboardActionListener(listener2);
隐藏系统自带的键盘
根据android系统的版本的不同,有不同的方法,需要利用反射,见代码:
/**
* 隐藏系统键盘
*
* @param editText
*/
public static void hideSystemSofeKeyboard(EditText editText) {
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= 11) {
try {
Class<EditText> cls = EditText.class;
Method setShowSoftInputOnFocus;
setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
setShowSoftInputOnFocus.setAccessible(true);
setShowSoftInputOnFocus.invoke(editText, false); } catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} else {
editText.setInputType(InputType.TYPE_NULL);
}
}
从底部弹出键盘
输入法需要从页面底部向上弹出,需要一个过渡动画,android每个页面都有一个window,window包含了一个getDecorView 根视图,我们要把键盘的视图添加到这个根视图下,配合动画出现键盘。
public void showSoftKeyboard() { if (viewContainer == null) {
viewContainer = mActivity.getLayoutInflater().inflate(R.layout.keyboardview_layout, null);
} else {
if (viewContainer.getParent() != null)
return;
} FrameLayout frameLayout = (FrameLayout) mActivity.getWindow().getDecorView();
KeyboardView keyboardView = (KeyboardView) viewContainer.findViewById(R.id.keyboard_view);
this.keyboardView = keyboardView;
this.keyboardView.setKeyboard(keyboard);
this.keyboardView.setEnabled(true);
this.keyboardView.setPreviewEnabled(false);
this.keyboardView.setOnKeyboardActionListener(listener2); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
frameLayout.addView(viewContainer, lp);
//viewContainer.setVisibility(View.GONE);
viewContainer.setAnimation(AnimationUtils.loadAnimation(mActivity, R.anim.down_to_up));
}
完整的代码如下:
package vir56k.democustomkeyboard; import android.app.Activity;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.os.Build;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.FrameLayout; import java.lang.reflect.Method; public class PopupKeyboardUtil {
private Activity mActivity; private KeyboardView keyboardView;
private Keyboard keyboard;// 全键盘包括数字和字母 private EditText editText1; public PopupKeyboardUtil(Activity mActivity) {
this.mActivity = mActivity;
this.keyboard = new Keyboard(mActivity, R.xml.small_keyboard);
} public void attachTo(EditText editText, boolean isAuto) {
this.editText1 = editText;
hideSystemSofeKeyboard(this.editText1);
setAutoShowOnFocs(isAuto);
} public void setAutoShowOnFocs(boolean enable) {
if (editText1 == null)
return;
if (enable)
editText1.setOnFocusChangeListener(onFocusChangeListener1);
else
editText1.setOnFocusChangeListener(null);
} View.OnFocusChangeListener onFocusChangeListener1 = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
showSoftKeyboard();
else
hideSoftKeyboard();
}
}; View viewContainer; public void showSoftKeyboard() { if (viewContainer == null) {
viewContainer = mActivity.getLayoutInflater().inflate(R.layout.keyboardview_layout, null);
} else {
if (viewContainer.getParent() != null)
return;
} FrameLayout frameLayout = (FrameLayout) mActivity.getWindow().getDecorView();
KeyboardView keyboardView = (KeyboardView) viewContainer.findViewById(R.id.keyboard_view);
this.keyboardView = keyboardView;
this.keyboardView.setKeyboard(keyboard);
this.keyboardView.setEnabled(true);
this.keyboardView.setPreviewEnabled(false);
this.keyboardView.setOnKeyboardActionListener(listener2); FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
frameLayout.addView(viewContainer, lp);
//viewContainer.setVisibility(View.GONE);
viewContainer.setAnimation(AnimationUtils.loadAnimation(mActivity, R.anim.down_to_up));
} public void hideSoftKeyboard() {
if (viewContainer != null && viewContainer.getParent() != null) {
((ViewGroup) viewContainer.getParent()).removeView(viewContainer);
}
} public boolean isShowing() {
if (viewContainer == null)
return false;
return viewContainer.getVisibility() == View.VISIBLE;
} /**
* 隐藏系统键盘
*
* @param editText
*/
public static void hideSystemSofeKeyboard(EditText editText) {
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= 11) {
try {
Class<EditText> cls = EditText.class;
Method setShowSoftInputOnFocus;
setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
setShowSoftInputOnFocus.setAccessible(true);
setShowSoftInputOnFocus.invoke(editText, false); } catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} else {
editText.setInputType(InputType.TYPE_NULL);
}
} private OnKeyboardActionListener listener2 = new OnKeyboardActionListener() {
@Override
public void swipeUp() {
} @Override
public void swipeRight() {
} @Override
public void swipeLeft() {
} @Override
public void swipeDown() {
} @Override
public void onText(CharSequence text) {
} @Override
public void onRelease(int primaryCode) {
} @Override
public void onPress(int primaryCode) {
} @Override
public void onKey(int primaryCode, int[] keyCodes) {
if (editText1 != null) {
keyCode_delect(primaryCode, editText1);
}
keyboardView.postInvalidate();
}
}; /**
* 判断回退键 和大小写切换
*
* @param primaryCode
* @param edText
*/
private void keyCode_delect(int primaryCode, EditText edText) { Editable editable = edText.getText();
int start = edText.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
if (edText.hasFocus()) {
if (!TextUtils.isEmpty(editable)) {
if (start > 0) {
editable.delete(start - 1, start);
}
}
} } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小写切换
keyboardView.setKeyboard(keyboard);
} else {
if (edText.hasFocus()) {
editable.insert(start, Character.toString((char) primaryCode));
}
}
} }
功能完成后,具体调用的演示:
package vir56k.democustomkeyboard; import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText; public class MainActivity extends AppCompatActivity {
EditText edittext1;
PopupKeyboardUtil smallKeyboardUtil;
private View viewContainer; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); edittext1 = (EditText) findViewById(R.id.edittext1); smallKeyboardUtil = new PopupKeyboardUtil(self());
smallKeyboardUtil.attachTo(edittext1, false);
//smallKeyboardUtil.setAutoShowOnFocs(false);
} public void onClickView(View view) {
if (view.getId() == R.id.btn1)
smallKeyboardUtil.showSoftKeyboard();
if (view.getId() == R.id.btn2)
smallKeyboardUtil.hideSoftKeyboard(); } private Activity self() {
return this;
}
}
完整的代码下载:
https://github.com/vir56k/demo/tree/master/demo.customkeyboard
android开发(45) 自定义软键盘(输入法)的更多相关文章
- Android开发案例 - 自定义虚拟键盘
所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘, 如下图: 本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚 ...
- Android App监听软键盘按键的三种方式
前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“GO”按键加载url页面:在点击搜索框的时候,点击右下角的sea ...
- Android App监听软键盘按键的三种方式(转)
最近有类似需求,在csdn上刚好发现,粘贴过来,以防止忘记喽 前言: 我们在android手机上面有时候会遇到监听手机软键盘按键的时候,例如:我们在浏览器输入url完毕后可以点击软键盘右下角的“G ...
- Android中点击隐藏软键盘最佳方法——Android开发之路4
Android中点击隐藏软键盘最佳方法 实现功能:点击EditText,软键盘出现并且不会隐藏,点击或者触摸EditText以外的其他任何区域,软键盘被隐藏: 1.重写dispatchTouchEve ...
- android开发之自定义组件
android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...
- android 弹出的软键盘遮挡住EditText文本框的解决方案
1.android 弹出的软键盘遮挡住EditText文本框的解决方案: 把Activit对应的布局文件filename.xml文件里的控件用比重设置布局.(例如:android:layout_wei ...
- 钉钉开发笔记(5)android系统中html软键盘的适配
最近项目中发现个别Android手机中存在弹出的软键盘会遮挡输入框的现象,最后自己写了一个方法(如下),问题基本解决. 记录下来,防止忘记.有什么不对的地方欢迎指正.O(∩_∩)O 1 //键盘适配 ...
- 软键盘 输入法管理器 InputMethodManager
基本介绍 软键盘的显示原理 软键盘其实是一个Dialog.InputMethodService为我们的输入法创建了一个Dialog,并且对某些参数进行了设置,使之能够在底部或者全屏显示.当我们点击输 ...
- android显示和隐藏软键盘(转)
显示键盘: EditText editText.setFocusable(true); editText.setFocusableInTouchMode(true); editText.request ...
随机推荐
- 要想有什么样的成就就要有什么样的眼光-SNF快速开发平台
1.普通人的圈子,谈论的是闲事,赚的是 工资,想的是明天. 2.生意人的圈子,谈论的是项目,赚的是 利润,想的是下一年. 3.事业人的圈子,谈论的是机会,赚的是 财富,想到的是未来和保障. 4.智慧人 ...
- IOS6 IOS7 Mapkit draw Rout(地图划线)
IOS7 比较简单 CLLocationCoordinate2D _start2D; CLLocationCoordinate2D _end2D; NSArray *_routes; IOS6 ...
- javascript读取xml文件读取节点数据的例子
分享下用javascript读取xml文件读取节点数据方法. 读取的节点数据,还有一种情况是读取节点属性数据. <head> <title></title> < ...
- Java常考面试题(一)
序言 我是一只乱飞乱撞的菜鸟,写的文章目前是以记录自己学习,和方便以后查看,期待日后不久能通过自己的努力,获得一点小小的成功,然后写出我的学习经验总结性文章来. ---WH 一.什么是虚拟机?为什么J ...
- [nginx]盗链和防盗链场景模拟实现
盗链环境模拟 http://www.daolian.com/index.html 这个页面盗用http://www.maotai.com/qq.jpg这个站点页面的图. <!doctype ht ...
- PostgreSQL PL/Python 和 PL/Postgres 函数互相调用
create or replace function hello(name text) returns text as $$ # str = name+',你吃饭了吗?'; # return 'hel ...
- sql的split()函数
ALTER function [dbo].[StrToList_Test](@Str varchar()) returns @table table( value nvarchar(max) ) as ...
- UVa 10697 - Firemen barracks
题目:已知三点.求到三点距离同样的点. 分析:计算几何.分三类情况讨论: 1.三点共线,不成立. 2.多点重叠,有多组解. 3.是三角形,输出中点. 说明:注意绝对值小于0.05的按0计算:负数的四舍 ...
- nodejs中aes-128-cbc加密和解密
和java程序进行交互的时候,java那边使用AES 128位填充模式:AES/CBC/PKCS5Padding加密方法,在nodejs中采用对应的aes-128-cbc加密方法就能对应上,因为有使用 ...
- [Windows Azure]The Autoscaling Application Block
The Autoscaling Application Block 5 out of 6 rated this helpful - Rate this topic ...