进阶指南
默认的键盘配置
如果初始化时没有额外配置,直接使用键盘控件时,默认的键盘配置如下:
配置项 | 默认值 | 说明 |
---|---|---|
键位显示与键值映射关系乱序 | false | 默认不做映射处理 |
字母键盘乱序布局 | false | 字母键盘不做默认不乱序布局,可根据实际使用情况配置 |
数字键盘乱序布局 | true | 默认乱序布局,可根据实际使用情况配置 |
符号键盘乱序布局 | true | 默认乱序布局,可根据实际使用情况配置 |
键位数据更新频率 | 5min | 切换安全键盘使用会话或者同一个使用会话超过5分钟,则会重新刷新键盘布局 |
自定义键位数据
键位数据类型说明:
PrimaryKeyCode
对键盘按键的操作码进行了统一定义:
int KEYCODE_SHIFT = -1; // 功能类型按键:切换大小写
int KEYCODE_MODE_CHANGE_NUMBER = -2; // 功能类型按键:切换到数字键盘
int KEYCODE_MODE_CHANGE_LETTER = -3; // 功能类型按键:切换到字母键盘
int KEYCODE_MODE_CHANGE_SYMBOL = -4; // 功能类型按键:切换到符号键盘
int KEYCODE_CANCEL = -5; // 功能类型按键:取消输入
int KEYCODE_DONE = -6; // 功能类型按键:输入完成
int KEYCODE_DELETE = -7; // 功能类型按键:删除
int KEYCODE_COLLAPSE = -8; // 功能类型按键:点击收起
int KEYCODE_INPUT = 0; // 可输入类型按键
具体按键区域划分如下图(数字键盘为例):
/**
* 自定义键位数据供应者
*
* @param positionProvider 键位数据供应者自定义实现,需要提供完整的键盘数据
*/
@Override
public void customKeyPositionProvider(@NonNull final AbstractKeyPositionProvider positionProvider)
接口参数说明:
参数名称 | 参数类型 | 参数描述 | 必选 |
---|---|---|---|
positionProvider |
AbstractKeyPositionProvider |
自定义键位数据供应者 | Y |
AbstractKeyPositionProvider
抽象类的接口说明:
方法名称 | 参数 | 方法描述 | 是否需要重写方法 | 备注 |
---|---|---|---|---|
setContext(byte[] context) |
context :后台下发的byte数组上下文数据 |
设置上下文数据,密文解密时需要用到该字段数据 | F | 业务逻辑用,无需重写 |
provideLetterKeyBoardPositions(Context context) |
context :上下文对象 |
获取字母键盘的键位数据 | T | 字母键盘的键位数据在这方法体内组装 |
provideNumberKeyBoardPositions(Context context) |
context :上下文对象 |
获取数字键盘的键位数据 | T | 数字键盘的键位数据在这方法体内组装 |
provideSymbolKeyBoardPositions(Context context) |
context :上下文对象 |
获取符号键盘的键位数据 | T | 数字键盘的键位数据在这方法体内组装 |
doShuffle(int subKeyboard, boolean val) |
subKeyboard :指定子键盘,详情请查看SubKeyboard 中的定义;val :true (键位布局随机乱序);false 键位布局按指定顺序 |
设置子键盘的键位是否乱序布局 | F | - |
setInputType(KeyboardInputType inputType) |
inputType :限定键盘的输入类型,详情请查看KeyboardInputType 中的定义 |
限制键盘的输入类型 | F | - |
checkKeyPositionData(KeyboardInputType inputType) |
inputType :限定键盘的输入类型,详情请查看KeyboardInputType 中的定义 |
检查键位数据与限定是输入类型是否匹配 | F | - |
clearCaches() |
VOID |
清除缓存接口 | F | 按需实现 |
setRefreshKeyPosition() |
VOID |
强制刷新键位布局 | F | - |
appFnKeyItemForLetterKeyboard(@NonNull List<KeyPosition> keys, Context context) |
keys : 键位数据结构列表 |
为字母键盘添加默认的控制键位数据 | F | 具体用法请参见下方示例 |
appFnKeyItemForNumberKeyboard(@NonNull List<KeyPosition> keys, Context context) |
keys : 键位数据结构列表 |
为数字键盘添加默认的控制键位数据 | F | 具体用法请参见下方示例 |
appFnKeyItemForSymbolKeyboard(@NonNull List<KeyPosition> keys, Context context) |
keys : 键位数据结构列表 |
为字符键盘添加默认的控制键位数据 | F | 具体用法请参见下方示例 |
hasLetters() |
VOID |
检查是否提供了字母键盘数据 | F | - |
hasDigits() |
VOID |
检查是否提供了数字键盘数据 | F | - |
hasSymbols() |
VOID |
检查是否提供了符号键盘数据 | F | - |
**自定键位数据可参考SDK中DefaultKeyPositionProvider实现。
KeyPositionBuilder
的接口说明:
键位数据的构建类
方法名称 | 参数 | 方法描述 | 备注 |
---|---|---|---|
KeyPositionBuilder(@ResPrimaryKey int primaryKey) |
primaryKey :键位操作码,详情请看PrimaryKeyCode |
带参构造函数 | - |
setDisplayContent(String text, int normalStateDisplayDrawable, int pressStateDisplayDrawable) |
text :键位显示内容normalStateDisplayDrawable :键位默认状态下显示的图片资源pressStateDisplayDrawable :键位按下状态下显示的图片资源 |
获取字母键盘的键位数据 | 二选一,所有参数都不为空时,优先显示图片资源 |
setMagicChar(char lowercaseChar, char uppercaseChar) |
lowercaseChar :小写默认字节uppercaseChar :大写魔法字节 |
设置键值映射值 | 非字母键位时,两个值一致 |
setKeyStyle(float norSize, float preSize, @ColorInt int norColor, @ColorInt int preColor) |
norSize :默认状态下文字大小preSize :按下状态下文字大小norColor :默认状态下文字色值preColor :按下状态下文字色值 |
设置键位显示样式 | - |
markAsBackspaceKey() |
VOID |
设置为空格键键位 | - |
build() |
VOID |
构建并返回KeyPosition 结构体 |
- |
- 键位数据的组装规则:
以数字键盘为例,接口provideSymbolKeyBoardPositions(Context context)
返回的list元素组成及排序(红色标)如下:
元素组装原则:
- 每行从左到右,到边换行。
- 遇到跨行键位,换行。
自定义键位布局
- 键位的行距和间距配置
在 安全键盘控件使用方式 已经提到,键盘的UI控件需要配合CustomKeyboardWrapper
,里面提供了众多键盘UI自定义的接口,其中键位的行距和间距也是通过这个包装类的接口实现的:
方法名称 | 参数 | 方法描述 | 备注 |
---|---|---|---|
setGaps(@ResSubKeyboard int subKeyBoard, int horizontalGap, int verticalGap) |
subKeyBoard :指定设置的自键盘horizontalGap :键位间的水平间距verticalGap :键位间的行间距 |
带参构造函数 |
- 键位的配置
出于autolayout
自适应分辨率的需要,键位的布局配置采用权重
和屏幕百分比
的数据标注方式。
名词 | 类型 | 名词解释 | 用途 | 计算方式 |
---|---|---|---|---|
weight |
float | 权重 | 标志键位的宽、高 | 以宽度权重计算为例,一行键位中,数量最多的键位宽度为基准,取值1.0f ,特殊宽度的键位宽度 * 1.0f / 基准宽度 得出特殊键位的宽度权重。 |
screenPercent |
float | 屏幕百分比 | 标注键盘行的左右外边距 | 设计师给出的外边距像素 * 1.0f / 出图的分辨率像素 |
键位布局采用按行布局的方式,键位布局的数据结构为KeyboardLayoutRow
:
方法名称 | 参数 | 方法描述 | 备注 |
---|---|---|---|
KeyboardLayoutRow(@IntRange(from = 1, to = Integer.MAX_VALUE) int columnCount) |
columnCount :改行的键位个数 |
带参构造函数 | - |
setKeyItemWidthWeight(@FloatRange(from = 0.0f, to = 5.0f) float... weight) |
weight :键位宽度权重数组,该行中键位权重按排序的顺序往里面塞 |
设置键位的宽度权重 | 数组长度小于columnCount 时默认补1.0f ;长度超长时则截取 |
setKeyItemLayoutPadding(@FloatRange(from = 0.0f, to = 20) float... padding) |
padding :每个键位的左内边距 |
设置键位的做内边距 | 键位与前一个键位的左间距= horizontalGap +padding |
setKeyItemLayoutHeightWeight(@IntRange(from = 1, to = 2) int... weight) |
weight :键位高度权重数组,该行中键位权重按排序的顺序往里面塞 |
设置键位的高度权重 | 不建议太高 |
setMarginScreenPercent(@FloatRange(from = 0.0f, to = 1.0f) float leftMargin, @FloatRange(from = 0.0f, to = 1.0f) float rightMargin) |
leftMargin :屏幕占比标注方式的左外边距rightMargin :屏幕占比标注方式的右外边距 |
设置行布局的外边距 | - |
setMargin(@FloatRange(from = 0, to = Integer.MAX_VALUE) float leftMargin, @FloatRange(from = 0, to = Integer.MAX_VALUE) float rightMargin) |
leftMargin :像素标注方式的左外边距rightMargin :像素标注方式的右外边距 |
设置行布局的外边距 | - |
布局规则:
- 每行从左到右,到边换行。
- 遇到跨行键位,换行。
从上图可以看到,第一行有四个键位,存在一个跨行按键,因而第二行只布局了三个,第三行同第一行,第四行同第二行。
- 自定义布局数据
通过实现AbsKeyboardLayoutProvider可以实现自定义布局数据,展示键盘时可以通过通过CustomKeyboardWrapper如下接口指定AbsKeyboardLayoutProvider。
/**
* 自定义键位布局数据提供者
*
* @param layoutProvider 键位布局提供者自定义实现,需要提供完整键盘的布局数据
*/
@Override
public void customKeyboardLayoutProvider(@NonNull AbsKeyboardLayoutProvider layoutProvider)
接口参数说明:
参数名称 | 参数类型 | 参数描述 | 必选 |
---|---|---|---|
layoutProvider |
AbsKeyboardLayoutProvider |
自定义键位布局数据供应者 | Y |
AbsKeyboardLayoutProvider
抽象类的接口说明:
public abstract class AbsKeyboardLayoutProvider implements ISwitchInputType, Serializable {
/**
* 提供字母键盘键位布局数据
*/
public abstract List<KeyboardLayoutRow> provideLetterKeyboardLayout(Context context);
/**
* 提供字数字盘键位布局数据
*/
public abstract List<KeyboardLayoutRow> provideNumberKeyboardLayout(Context context);
/**
* 提供符号键盘键位布局数据
*/
public abstract List<KeyboardLayoutRow> provideSymbolKeyboardLayout(Context context);
}
AbsKeyboardLayoutProvider实现可参考DefaultKeyboardLayoutProvider。
自定义键位样式设置
除了上述自定设置之外,还提供了更多键位样式自定义设置,具体如下图:
CustomKeyboardWrapper
提供的具体接口说明如下:
方法名称 | 参数 | 方法描述 | 备注 |
---|---|---|---|
setKeyTextStyle(@ResSubKeyboard int subKeyBoard, int textSize, @ColorInt int textNormalStateColor, @ColorInt int textPressStateColor) |
subKeyBoard :指定子键盘textSize :文字字号textNormalStateColor :普通状态下的文字颜色textPressStateColor :按下状态下的文字颜色 |
按键文字的样式配置 | |
setContentKeyFillStyle(@ResSubKeyboard int subKeyBoard, Drawable normalStateDrawable, Drawable pressStateDrawable) setEnterKeyFillStyle(@ResSubKeyboard int subKeyBoard, Drawable normalStateDrawable, Drawable pressStateDrawable) setFnKeyFillStyle(@ResSubKeyboard int subKeyBoard, Drawable normalStateDrawable, Drawable pressStateDrawable) |
subKeyBoard :指定子键盘normalStateDrawable :普通状态下的填充图片pressStateDrawable :按下状态下的填充图片 |
设置内容键位的填图片 | |
setContentKeyFillStyle(@ResSubKeyboard int subKeyBoard, @ColorInt int normalStateFillColor, @ColorInt int pressStateFillColor) setEnterKeyFillStyle(@ResSubKeyboard int subKeyBoard, @ColorInt int normalStateFillColor, @ColorInt int pressStateFillColor) setFnKeyFillStyle(@ResSubKeyboard int subKeyBoard, @ColorInt int normalStateFillColor, @ColorInt int pressStateFillColor) |
subKeyBoard :指定子键盘normalStateFillColor :普通状态下的填充颜色pressStateFillColor :按下状态下的填充颜色 |
设置内容键位的填充颜色 | |
setBorderStyle(@ResSubKeyboard int subKeyBoard, float borderWidth, float borderCorner, @IBorderLayout.HideRadiusSide int hideRadiusSide, @ColorInt int normalStateColor, @ColorInt int focusStateColor) |
subKeyBoard :指定子键盘borderWidth :边框笔触宽度borderCorner :边框圆角大小hideRadiusSide :指定不需要圆角的边normalStateColor :普通状态下边框的颜色focusStateColor :按下状态下边框的颜色 |
配置键位边框的样式 | |
setBorderRadius(@ResSubKeyboard int subKeyBoard, float borderCorner, @IBorderLayout.HideRadiusSide int hideRadiusSide) |
subKeyBoard :指定子键盘hideRadiusSide :指定不需要圆角的边 |
设置行布局的外边距 | |
setLayerStyle(@ResSubKeyboard int subKeyBoard, float layerNormalStateHeight, float layerPressStateHeight, @ColorInt int layerColor) |
subKeyBoard :指定子键盘layerNormalStateHeight :默认状态下阴影高度layerPressStateHeight :按下状态下阴影高度layerColor :阴影色值 |
设置键位底部阴影的样式 |
密码强度检测与两次密码输入一致性检测
- 用于用户注册或者设置密码时使用安全键盘输入的场景下,可以使用以下两个 API 来分别检测密码强度与两次密码输入一致性:
/**
* 弱密码(密码强度)检测
* @param context 解密上下文
* @param inputText 安全键盘输入内容
* @param repeatNum 重复位数
* @param ePwdStrength 检测级别 参见下方EPwdStrength
* @param callBack 结果回调
*/
KeyboardHelper.inputTextWeakCheck(mContext, input, repeatNum, checkStrength, new InputTextCheckCallBack() {
@Override
public void result(int retCode, boolean isWeak) {
// retCode 参见下方ERetCode
// isWeak true表示弱密码 false表示非弱密码
if (retCode == 0 && !isWeak) {
ToastUtil.showToast(PasswordCheckActivity.this, "通过!");
}else{
ToastUtil.showToast(PasswordCheckActivity.this, "不通过!,返回码: " + retCode + " isWeak: " + isWeak);
}
}
});
/**
* 二次密码校验
* @param firstInputContext 初次输入解密上下文
* @param secondInputContext 二次输入解密上下文
* @param firstInputText 首次输入
* @param secondInputText 二次输入
* @param repeatNum 重复位数
* @param ePwdStrength 检测级别 参见下方EPwdStrength
* @param callBack 结果回调
* 注意: 二次密码校验 包含 密码强度检测功能
*/
KeyboardHelper.inputTextDoubleCheck(firstInputContext,secondInputContext, input, input2, repeatNum, checkStrength, new InputTextCheckCallBack() {
@Override
public void result(int retCode, boolean isWeak) {
// retCode 参见下方ERetCode
// isWeak true表示弱密码 false表示非弱密码
if (retCode == 0 && !isWeak) {
ToastUtil.showToast(PasswordCheckActivity.this, "通过!");
} else {
ToastUtil.showToast(PasswordCheckActivity.this, "不通过!,返回码: " + retCode + " isWeak: " + isWeak);
}
}
});
- 检测级别(检测强度)
public interface EPwdStrength {
public static final int EPS_NONE = 0; // 不检测
public static final int EPS_SIMPLE = 1; // 纯数字或者字母键盘:包含连续、重复字母或数字为弱密码
public static final int EPS_LETTER = 2; // 数字+字母键盘:包含连续、重复字母或数字为弱密码;无数字或者字母为弱密码
public static final int EPS_CASE = 3; // 数字+字母键盘:包含连续、重复字母或数字为弱密码;无数字或者字母为弱密码;无大小写字母为弱密码
public static final int EPS_SYMBOL = 4; // 数字+字母+特殊字符:包含连续、重复字母或数字为弱密码;无数字或者字母为弱密码;无大小写字母为弱密码;无特殊字符为弱密码
}
- retCode 返回码
public interface ERetCode {
public static final int ERC_NONE = 0; // 操作成功
public static final int ERC_INVALID_REQ_PARAM = 1; // 请求的参数有问题
public static final int ERC_SERVICE_CONFIG_ERROR = 2; // 服务的配置有误
public static final int ERC_ENCODE_OUT_OF_RANGE = 3; // 处理的输入内容超时范围
public static final int ERC_QUERY_DATA_FROM_DCACHE_EXCEPTION = 4; // 查询异常
public static final int ERC_KEYPOSITION_EXIPRED = 5; // 键盘数据已经过期,需要重新输入再验证
public static final int ERC_RECOVER_FAILED = 6; // 还原失败
public static final int ERC_DOUBLE_CHECK_ERROR = 7; // 两次密码输入不一致
}
获取键位数据
如果想要完全自定义键盘UI,可以使用如下API手动自行获取键位数据,然后自行实现UI。
/**
* 获取键位数据
* @param inputType 键位数据类型
* // 默认类型
* NONE,
* // 仅数字键盘
* NUMERIC,
* // 仅身份证键盘
* CN_ID_CARD;
* @param keyPositionCallBack 回调
*/
KeyboardWrapperApi.getKeyboardPositionData(KeyboardInputType.NUMERIC,new IKeyPositionCallBack() {
@Override
public void result(int retCode, KeyboardPosition position, byte[] context) {
//context 解密上下文 后端服务解密时用到
}
});
/**
* 获取键位数据 此方法键位数据类型为 KeyboardInputType.NONE(默认类型)
* @param keyPositionCallBack 回调
*/
KeyboardWrapperApi.getKeyboardPositionData(new IKeyPositionCallBack() {
@Override
public void result(int retCode, KeyboardPosition position, byte[] context) {
//context 解密上下文 后端服务解密时用到
}
});
键位数据结构如下:
/**
* 当获取的键位数据类型为 KeyboardInputType.NONE(默认类型)时,字母,数字,符号,键位数据字段都有值.
* 当KeyboardInputType.NUMERIC时 仅数字键位数据字段有值
* 当KeyboardInputType.CN_ID_CARD时 仅数字键位数据字段有值且包含'x'
*/
public final class KeyboardPosition extends com.qq.taf.jce.JceStruct{
// 字母键位数据
public Protocol.Keyboard.KeyPositionList letterKeyPosition = null;
// 数字键位数据
public Protocol.Keyboard.KeyPositionList numberKeyPosition = null;
// 符号键位数据
public Protocol.Keyboard.KeyPositionList symbolKeyPosition = null;
}
public final class KeyPositionList extends com.qq.taf.jce.JceStruct{
public boolean isFullKeyboardPosition = false;
//键位数据List
public java.util.ArrayList<Protocol.Keyboard.KeyPositionContent> positionList = null;
}
public final class KeyPositionContent extends com.qq.taf.jce.JceStruct{
public int primaryKeyCode = Protocol.Keyboard.EPrimaryKeyCode.EPKC_INPUT;
//键位显示值
public String display = "";
//键位点击时输出的混淆值,此值为ASCII码,使用时转为char即可
//小写
public short lowercaseChar = 0;
//大写
public short uppercaseChar = 0;
}
自定义键盘示例
示例效果:自定义明文键盘,并在数字键盘场景下新增小数点。
自定义明文键位数据
public class CustomKeyPositionProvider extends AbstractKeyPositionProvider { @Override public List<KeyPosition> provideLetterKeyBoardPositions(Context context) { boolean needRefresh = false; synchronized (mLetters) { if (mLetters.isEmpty()) { needRefresh = true; } } if (needRefresh) { List<KeyPosition> ret = new ArrayList<>(internalLetterKeyboardData()); if (mShuffleLetterKeyPosition) { ShuffleUtil.shuffle(ret); } appFnKeyItemForLetterKeyboard(ret, context); synchronized (mLetters) { mLetters.addAll(ret); } } return new ArrayList<>(mLetters); } @Override public List<KeyPosition> provideNumberKeyBoardPositions(Context context) { boolean needRefresh = false; synchronized (mNumbers) { if (mNumbers.isEmpty()) { needRefresh = true; } } if (needRefresh) { List<KeyPosition> ret = new ArrayList<>(internalNumberKeyboardData()); if (mShuffleNumberKeyPosition) { ShuffleUtil.shuffle(ret); } appFnKeyItemForNumberKeyboard(ret, context); KeyPosition.KeyPositionBuilder var3 = new KeyPosition.KeyPositionBuilder(PrimaryKeyCode.KEYCODE_INPUT); var3.setMagicChar('.', '.'); var3.setDisplayContent(".", -1, -1); ret.add(12, var3.build()); synchronized (mNumbers) { mNumbers.addAll(ret); } } return new ArrayList<>(mNumbers); } @Override public List<KeyPosition> provideSymbolKeyBoardPositions(Context context) { boolean needRefresh = false; synchronized (mSymbols) { if (mSymbols.isEmpty()) { needRefresh = true; } } if (needRefresh) { List<KeyPosition> ret = new ArrayList<>(internalSymbolKeyboardData()); if (mShuffleSymbolKeyPosition) { ShuffleUtil.shuffle(ret); } appFnKeyItemForSymbolKeyboard(ret, context); synchronized (mSymbols) { mSymbols.addAll(ret); } } return new ArrayList<>(mSymbols); } /** * 默认为qwerty键位布局 */ private List<KeyPosition> internalLetterKeyboardData() { final String letters = "qwertyuiopasdfghjklzxcvbnm"; List<KeyPosition> keys = new ArrayList<>(); KeyPosition.KeyPositionBuilder builder = null; char[] chars = letters.toCharArray(); for (char letter : chars) { builder = new KeyPosition.KeyPositionBuilder(PrimaryKeyCode.KEYCODE_INPUT); builder.setDisplayContent(String.valueOf(letter), -1, -1) .setMagicChar(letter, Character.toUpperCase(letter)); keys.add(builder.build()); } return keys; } private List<KeyPosition> internalNumberKeyboardData() { final String numberText = "0123456789"; List<KeyPosition> keys = new ArrayList<>(); KeyPosition.KeyPositionBuilder builder = null; char[] chars = numberText.toCharArray(); for (char text : chars) { builder = new KeyPosition.KeyPositionBuilder(PrimaryKeyCode.KEYCODE_INPUT); builder.setDisplayContent(String.valueOf(text), -1, -1) .setMagicChar(text, text); keys.add(builder.build()); } return keys; } private List<KeyPosition> internalSymbolKeyboardData() { final String symbols = "_\\{}[]^*+=-/:;()$&@\"#%.,<>?!'"; List<KeyPosition> keys = new ArrayList<>(); KeyPosition.KeyPositionBuilder builder = null; char[] chars = symbols.toCharArray(); for (char letter : chars) { builder = new KeyPosition.KeyPositionBuilder(PrimaryKeyCode.KEYCODE_INPUT); builder.setDisplayContent(String.valueOf(letter), -1, -1); builder.setMagicChar(letter, letter); keys.add(builder.build()); } return keys; } }
自定义键位布局数据
以DefaultKeyboardLayoutProvider为基础,修改provideNumberKeyboardLayout,为小数点添加布局数据。
public class CustomKeyboardLayoutProvider extends DefaultKeyboardLayoutProvider { @Override public List<KeyboardLayoutRow> provideNumberKeyboardLayout(Context context) { KeyboardLayoutRow var2 = new KeyboardLayoutRow(4); var2.setKeyItemLayoutHeightWeight(new int[]{1, 1, 1, 2}); var2.setKeyItemWidthWeight(new float[]{1.0F, 1.0F, 1.0F, 0.711F}); var2.setKeyItemLayoutPadding(new float[]{0.0F, 0.0F, 0.0F, context.getResources().getDimension(com.tencent.tmf.keyboard.R.dimen.default_number_keyboard_horizontal_key_extra_gap)}); AtomicInteger var3 = new AtomicInteger(0); var2.mRowIndex = var3.getAndIncrement(); ArrayList var4 = new ArrayList(); var4.add(var2); var2 = new KeyboardLayoutRow(3); var2.mRowIndex = var3.getAndIncrement(); var4.add(var2); var2 = new KeyboardLayoutRow(4); var2.setKeyItemLayoutHeightWeight(new int[]{1, 1, 1, 2}); var2.setKeyItemWidthWeight(new float[]{1.0F, 1.0F, 1.0F, 0.711F}); var2.setKeyItemLayoutPadding(new float[]{0.0F, 0.0F, 0.0F, context.getResources().getDimension(com.tencent.tmf.keyboard.R.dimen.default_number_keyboard_horizontal_key_extra_gap)}); var2.mRowIndex = var3.getAndIncrement(); var4.add(var2); if (KeyboardInputType.isCnIDCardInputType(this.mCurrInputType)) { var2 = new KeyboardLayoutRow(2); var2.mRowIndex = var3.getAndIncrement(); var2.setMarginScreenPercent(0.2699F, 0.0F); } else if (KeyboardInputType.isNumericInputType(this.mCurrInputType)) { var2 = new KeyboardLayoutRow(2); //数字键盘留出小数点位置 var2.mRowIndex = var3.getAndIncrement(); var2.setMarginScreenPercent(0.2699F, 0); } else { var2 = new KeyboardLayoutRow(3); var2.mRowIndex = var3.getAndIncrement(); } var4.add(var2); return var4; } }
展示键盘时指定positionProvider及layoutProvider
KeyboardWrapperApi .doInputWithPopupKeyboard(KeyboardDemoActivity.this, mSafeEditText, mSafeEditText.hashCode(), new ICustomKeyboardWrapper() { @Override public void wrapper(CustomKeyboardWrapper wrapper) { //安全键盘属性设置 wrapper.setInputType(KeyboardInputType.NUMERIC); wrapper.customKeyPositionProvider(new CustomKeyPositionProvider()); wrapper.customKeyboardLayoutProvider(new CustomKeyboardLayoutProvider()); } }, new IInputCompleteListener() { @Override public void onComplete(byte[] context, String msg) { } });