android 自定义键盘碰到的问题及解决方法



      最近有个需求,需要在输入法的键盘上再弹出一个自定义的键盘(相当于弹出2个键盘,一上一下),该键盘上主要是一些自定义的文字和符号。

而且不管下面用的是什么输入法(搜狗,谷歌,QQ等),上面的键盘都必须显示出来。

      开始的想发是在应用层做,只要能获取弹出的输入法的高度,然后在把自己做的键盘加到上面就可以了。可是后来发现在应用层无法获取输入法的高度。

虽然可以通过输入法把布局顶上去的办法可以获取得到,但是这样就必须把输入法设置死,不是本人想要的效果。后来发现有一种通过模拟点击来抛异常的方法也可以获取高度。但是感觉不怎么靠谱,最后没办法,只好想办法在FRAMWORK里加。。。。

      于是碰到了2个问题。

      1、怎么把输入法键盘的按钮替换成自己的图片按钮。

      使用XML配置出来的键盘里设置了keyIcon,显示的时候也确实把按键替换成自己的图片了,但是没有我想要的反选效果,反选效果只能是用一张图片,而我想要的效果是每一个按键都有不同的反选效果。于是看KeyBoardView代码,发现是在onDraw里调用了onBufferDraw来绘制按钮的。而onBufferDraw是private类型的,于是只好自己重写了个KeyBoardView(其实就是把里面的代码拷贝出来,然后改一些资源ID,值到编译通过为止)然后找到绘制按钮icon的代码。加了一句。

else if (key.icon != null) {
                final int drawableX = (key.width - padding.left - padding.right 
                                - key.icon.getIntrinsicWidth()) / 2 + padding.left;
                final int drawableY = (key.height - padding.top - padding.bottom 
                        - key.icon.getIntrinsicHeight()) / 2 + padding.top;
                canvas.translate(drawableX, drawableY);
                key.icon.setBounds(0, 0, 
                        key.icon.getIntrinsicWidth(), key.icon.getIntrinsicHeight());
                //只要加这一句
                key.icon.setState(drawableState);
                //
                key.icon.draw(canvas);
                canvas.translate(-drawableX, -drawableY);
            }

      2、加入自定义键盘后,点击不响应。。。

      这个问题也查了很久。先说怎么加自定义的键盘。

      找到系统输入法的布局文件,在frameworks/base/core/res/res/layout/input_method.xml中。于是在这个布局里加入了自定义键盘的布局,然后在Inputmethodservice里初始化键盘以及对一些UI交互做处理。思路还是对的。但是编译出来放到模拟器上跑,自定义键盘是显示出来了,位置也对,在输入法的上面,可是不管怎么点都没响应。一直找原因。最后发现在inputmethodservice里有个Insets类,发现这个类是可以控制输入法布局的可点击区域的。默认的配置是只能点击键盘、候选词2个区域,计算区域大小调的方法是onComputeInsets。该方法如下:

 public void onComputeInsets(Insets outInsets) {
        int[] loc = mTmpLocation;
        if (mInputFrame.getVisibility() == View.VISIBLE) {
            mInputFrame.getLocationInWindow(loc);
        } else {
            View decor = getWindow().getWindow().getDecorView();
            loc[1] = decor.getHeight();
        }
        if (isFullscreenMode()) {
            // In fullscreen mode, we never resize the underlying window.
            View decor = getWindow().getWindow().getDecorView();
            outInsets.contentTopInsets = decor.getHeight();
        } else {
            outInsets.contentTopInsets = loc[1];
        }
        if (mCandidatesFrame.getVisibility() == View.VISIBLE) {
            mCandidatesFrame.getLocationInWindow(loc);
        }
        outInsets.visibleTopInsets = loc[1];
        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE;
        outInsets.touchableRegion.setEmpty();
    }

只要在这个里面把自定义的键盘VIEW 也加进来getLocationInWindow(loc)一下。就解决了这个问题了。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值