Android 自定义软键盘遇到的问题
来源:互联网 发布:pmi指数知乎 编辑:程序博客网 时间:2024/06/10 15:18
首先来分析一下软键盘的基本属性
- 软键盘的实现
- 点击输入框从底部弹出软键盘
- 弹出软键盘后焦点在输入框
- 弹出软键盘不遮挡输入框
软键盘的实现
可以使用KeyboardView也可以自己写布局写点击事件(除特殊情况不推荐)
KeyboardView的简单实现方法
一、在res下新建xml文件夹,在xml文件夹中新建keyboard.xml文件
<?xml version="1.0" encoding="utf-8"?><Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="33.3333%p" android:horizontalGap="0px" android:verticalGap="0px" android:keyHeight="80dp"> <Row> <Key android:codes="55" android:keyLabel="7" /> <Key android:codes="56" android:keyLabel="8" /> <Key android:codes="57" android:keyLabel="9" android:keyEdgeFlags="right"/> </Row> <Row> <Key android:codes="52" android:keyLabel="4" /> <Key android:codes="53" android:keyLabel="5" /> <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="right"/> </Row> <Row> <Key android:codes="49" android:keyLabel="1" /> <Key android:codes="50" android:keyLabel="2" /> <Key android:codes="51" android:keyLabel="3" android:keyEdgeFlags="right"/> </Row> <Row> <Key android:codes="46" android:keyLabel="." /> <Key android:codes="48" android:keyLabel="0" /> <Key android:codes="-3" android:keyEdgeFlags="right" android:keyLabel="OK"/> </Row></Keyboard>
二、这个地方有的实现有点不一样,一般来说不应该在每一个布局里都加入KeyboardViw,比如我使用的在MainActivity,Main里面全是fragment所以就直接在布局里面了
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/img_bg"> <FrameLayout android:id="@+id/frame" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="50dp"> </FrameLayout> <android.inputmethodservice.KeyboardView android:id="@+id/keyboardview" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/write" android:layout_alignParentBottom="true" android:focusable="true" android:usableInTouchMode="true" android:visibility="invisible"/></RelativeLayout>
然后
import android.animation.Animator;import android.animation.AnimatorInflater;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.app.Activity;import android.content.Context;import android.inputmethodservice.InputMethodService;import android.inputmethodservice.Keyboard;import android.inputmethodservice.KeyboardView;import android.media.AudioManager;import android.text.Editable;import android.util.Log;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.inputmethod.InputConnection;import android.widget.EditText;import com.kubu.terminal.R;import java.util.List;import static android.content.Context.AUDIO_SERVICE;/** * Created by steven on 2017/7/31. */public class KeyBoradUtil extends InputMethodService implements KeyboardView.OnKeyboardActionListener{ private Context mContext;//上下文对象 private KeyboardView mKeyboardView; private Keyboard mKeyboard; private EditText mEdit; /** * 必须activity作为上下文对像 * * * @param context */ public KeyBoradUtil(Context context) { mContext = context; //初始化键盘布局,下面在放进 KeyBoardView里面去。 mKeyboard = new Keyboard(mContext, R.xml.keyboard); //配置keyBoardView try { mKeyboardView = (KeyboardView) ((Activity)mContext).findViewById(R.id.keyboardview); mKeyboardView.setKeyboard(mKeyboard); //设置键盘 mKeyboardView.setEnabled(true); mKeyboardView.setPreviewEnabled(false); //这个是,效果图按住是出来的预览图。 //设置监听,不设置的话会报错。监听放下面了。 mKeyboardView.setOnKeyboardActionListener(this); } catch (Exception e) { Log.e("sun", "keyview初始化失败"); } } public void setEdit(EditText mEdit) { this.mEdit = mEdit; } @Override public void onPress(int primaryCode) { } @Override public void onRelease(int primaryCode) { } @Override public void onKey(int primaryCode, int[] keyCodes) { Editable editable = mEdit.getText(); int start = mEdit.getSelectionStart(); if (primaryCode == Keyboard.KEYCODE_CANCEL) {// 完成 hideKeyboard(); } else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退 if (editable != null && editable.length() > 0) { if (start > 0) { editable.delete(start - 1, start); } } } else if (primaryCode == 57419) { // go left if (start > 0) { mEdit.setSelection(start - 1); } } else if (primaryCode == 57421) { // go right if (start < mEdit.length()) { mEdit.setSelection(start + 1); } } else { editable.insert(start, Character.toString((char) primaryCode)); } } @Override public void onText(CharSequence text) { } @Override public void swipeLeft() { } @Override public void swipeRight() { } @Override public void swipeDown() { } @Override public void swipeUp() { } //显示软键盘 public void showKeyboard() { int visibility = mKeyboardView.getVisibility(); if (visibility == View.GONE || visibility == View.INVISIBLE) { mKeyboardView.setVisibility(View.VISIBLE); int hight = mKeyboardView.getHeight(); Log.d("TAG",hight+""); ObjectAnimator bad = ObjectAnimator.ofFloat(mKeyboardView, "translationY", hight, 0); bad.setDuration(300); bad.start(); } } //关闭软键盘 public void hideKeyboard() { int visibility = mKeyboardView.getVisibility(); if (visibility == View.VISIBLE) { int hight = mKeyboardView.getHeight(); ObjectAnimator bad = ObjectAnimator.ofFloat(mKeyboardView, "translationY", 0, hight); bad.setDuration(300); bad.start(); bad.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mKeyboardView.setVisibility(View.INVISIBLE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } }}
注意在布局里KeyboardView的android:visibility=”invisible”不能为gone,否则getHeight()为空 ,然后初始化 mKeyBoard = new KeyBoradUtil(getActivity()),并在editText的setOnTouchListener里面显示软键盘。
@Override public boolean onTouch(View v, MotionEvent event) { switch (v.getId()) { case R.id.et_phone: //隐藏系统软键盘 setInputType(et_phone); mKeyBoard.setEdit(et_phone); break; case R.id.et_password: //隐藏系统软键盘 setInputType(et_password); mKeyBoard.setEdit(et_password); break; } mKeyBoard.showKeyboard(); return false; } private void setInputType(EditText editText) { if (android.os.Build.VERSION.SDK_INT <= 10) {//4.0以下 danielinbiti editText.setInputType(InputType.TYPE_NULL); } else { getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); try { Class<EditText> cls = EditText.class; Method setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class); setShowSoftInputOnFocus.setAccessible(true); setShowSoftInputOnFocus.invoke(editText, false); } catch (Exception e) { e.printStackTrace(); } } }
像我上面说的整个工程就一个Activity,初始化以及显示都在那一个Activity里面,那么如果不是这样的呢,额…,想过使用PopupWindows,但是PopupWindows弹出后,输入框的光标没有了(⊙﹏⊙),而且点返回按钮的时候只是仅仅关闭弹窗(跟实际软键盘效果不符,可能有其他处理方法,感觉没意义),然后又想到用addView的方式加进去,又发现不同布局可能最外层可能不一样,没法统一处理,目前没找到好的解决办法。
最后不遮挡输入框的做法,很简单,我们知道了软键盘的高度,那么通过一系列的计算通过view.scrollTo(0,editH-keyboardH+10);移动布局就行了,具体看代码
为了拿到View,我在KeyBoradUtil中加了个setView()
public void setView(View view){ this.view = view;}
public void showKeyboard() { //计算输入框底部到父布局顶部的距离,有50dp的padding int editH = mEdit.getBottom()+DisplayUtil.dip2px(mContext,50); //计算软键盘顶部到父布局顶部的距离 int keyboardH = mKeyboardView.getTop(); //移动布局 if (editH>keyboardH) { if (view != null) { //加了10的偏移,看个人爱好,可以不加 view.scrollTo(0,editH-keyboardH+10); } } int visibility = mKeyboardView.getVisibility(); if (visibility == View.GONE || visibility == View.INVISIBLE) { mKeyboardView.setVisibility(View.VISIBLE); int hight = mKeyboardView.getHeight(); Log.d("TAG",hight+""); ObjectAnimator bad = ObjectAnimator.ofFloat(mKeyboardView, "translationY", hight, 0); bad.setDuration(200); bad.start(); } }
public void hideKeyboard() { int visibility = mKeyboardView.getVisibility(); if (visibility == View.VISIBLE) { if (view != null) { //布局恢复 view.scrollTo(0,0); } int hight = mKeyboardView.getHeight(); ObjectAnimator bad = ObjectAnimator.ofFloat(mKeyboardView, "translationY", 0, hight); bad.setDuration(200); bad.start(); bad.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { mKeyboardView.setVisibility(View.INVISIBLE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } }
- Android 自定义软键盘遇到的问题
- android:总结自定义软键盘遇到的小问题
- android软键盘遇到的问题
- Android全屏下输入法软键盘遇到的问题
- 【Android】EditText 遇到软键盘遮挡底部一点的问题
- webview软键盘遇到的问题
- android EditText自定义软键盘光标问题
- android 自定义软键盘
- Android 自定义软键盘
- Android自定义软键盘
- Android 自定义软键盘
- Android 自定义软键盘
- Android自定义软键盘的实现
- Android自定义软键盘的实现
- Android自定义软键盘的实现
- Android自定义软键盘的实现
- android软键盘右下角的功能键自定义
- Android自定义软键盘的实现
- Android 打开本地文件
- 多线程理解杂记
- Android TextView加载Html图文混排
- nexus配置maven私服
- LabelAtlas
- Android 自定义软键盘遇到的问题
- LabelBMFont
- 读前辈的大话设计模式(一)之简单工厂模式,抒自己的读后感
- hdu4296 Buildings
- PHP微信公众平台开发:配置、微信api接入验证
- hdu 3697 Selecting courses(贪心)
- 《利用Python进行数据分析》笔记---第2章--MovieLens 1M数据集
- Sprite
- caffe中各种loss函数