自定义键盘怎么避免预览特殊按键以及监听返回键的问题

继承了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()

    }
}
  1. 如果使用 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"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值