继承了KeyboradView,写了一个自定义键盘,以dialog的形式弹出,解决两个问题
1.使用DialogFragment,在onStart中,定义dialog的属性,使其像系统输入法一样的特性,即不获取焦点,可以点击下面的activity界面
open class KeyboardDialog : BaseDialogFragment() {
private var mContentView: View? = null;
override fun onAttach(context: Context) {
super.onAttach(context)
initStyle();
}
fun setView(view:View){
mContentView = view;
}
override fun onStart() {
val params = dialog.window.attributes
params.width = (SystemUtil.getScreenPixels()[0])!!.toInt()
params.gravity = Gravity.BOTTOM;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
dialog.window.setDimAmount(0f)
var windowSetFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
var windowModFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_DIM_BEHIND
// mTakesFocus如果设置为true,会导致弹出之后,activity的window失去焦点,
// 当弹出此dialog之后,再点击调出系统输入法的EditText,点击第二次才会弹出系统输入法
var mTakesFocus = false;
if (!mTakesFocus) {
windowSetFlags = windowSetFlags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
} else {
windowSetFlags = windowSetFlags or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
windowModFlags = windowModFlags or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
}
dialog.window.setFlags(windowSetFlags, windowModFlags)
setCanceledOnTouchOutside(true)
dialog.window!!.attributes = params
super.onStart()
}
}
- 如果使用 windowSetFlags = windowSetFlags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,会导致dialog不能获取返回键,但是系统输入法弹出后,点击返回键,输入法dialog会消失,现在点击返回键,直接返回上个界面,为解决这个问题,使用fragment的addToBackStackf方法,就能实现点击返回键DialogFragment消失,从而键盘消失
/**
* 调用addToBackStack,可监听用户点击返回键
*/
fun showCanback(activity: AppCompatActivity) {
val ft: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
// 添加回退栈
ft.addToBackStack(null);
super.show(ft, FRAGMENT_TAG_PRE + this.javaClass.simpleName)
}
3.键盘上的有预览功能时,怎么解决手指滑动到 退格 确定 等特殊按键的时候,不弹出预览,
特殊按键在xml中定义时,label为空,如退格键,因为退格键直接使用的图片
<!-- 退格键 -->
<Key
android:codes="-5"
android:isRepeatable="true"
android:keyEdgeFlags="right" />
这样会导致预览时,报label为null的NPE,为解决此问题,则在onDraw中,判断keycode是否为特殊键,如果是,则调用
specialKey.label="";
这样解决NPE,但是会弹出空预览,以下自定义预览Textview,通过判断预览内容为空时,就不显示
public class PreviewTextView extends AppCompatTextView {
// 获取屏幕宽度
int screenWidth = SystemUtil.getScreenPixels()[0];
public PreviewTextView(Context context) {
super(context);
}
public PreviewTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public PreviewTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setText(CharSequence text, BufferType type){
super.setText(text,type);
// 不显示空预览
if (getText().toString().trim().length() == 0) {
setVisibility(GONE);
}else{
setVisibility(VISIBLE);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int[] mCoordinates = new int[2];
getLocationOnScreen(mCoordinates);
if(mCoordinates[0]==0){
// 如果是最左边的预览,则显示左侧预览背景
setBackground(getResources().getDrawable(R.drawable.bg_keyboard_pop_left));
}else if(Math.abs(screenWidth-mCoordinates[0]-(right-left))<5){
setBackground(getResources().getDrawable(R.drawable.bg_keyboard_pop_right));
}
else{
setBackground(getResources().getDrawable(R.drawable.bg_keyboard_pop));
}
}
@Override
public void setVisibility(int visibility) {
if (getText().toString().trim().length() == 0) {
visibility = GONE;
}
super.setVisibility(visibility);
}
}
在layout_keyboard_popup.xml中使用PreviewTextView
<?xml version="1.0" encoding="utf-8"?>
<com.xxx.keyboard.PreviewTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_keyboard_pop"
android:gravity="top|center_horizontal"
android:paddingTop="5dp"
android:textColor="@color/lib_keyborad_enable_text"
android:textSize="35sp"
tools:text="苏" />
把layout_keyboard_popup.xml设置到KeyboarView的 android:keyPreviewLayout属性中
<com.xxx.CustomKeyboardCoreView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keyPreviewHeight="97dp"
android:background="@null"
android:keyBackground="@drawable/bg_keyboard_item_transparent"
android:keyPreviewLayout="@layout/layout_keyboard_popup"
android:keyTextSize="16sp"
android:labelTextSize="16sp"/>