跳转至

Android PDA键盘逻辑

预期效果

由于PDA上有实体键盘,大部分操作直接使用实体键盘完成,使用软键盘辅助输入。点击输入框,只获取输入框的焦点而不弹出软键盘,这样方便使用实体键盘输入。在输入框旁放置一个按钮,用于控制软键盘的弹出和关闭。 功能点如下:

  • 输入框获取焦点后,仅可使用实体键盘输入不弹出软键盘。
  • 点击弹出/收起软键盘按钮后,根据当前键盘状态弹出或收起软键盘。
  • 点击软键盘内置的收起按钮后,要实时改变弹出/收起软键盘按钮的状态。

最终效果

点击输入框后:

丢失

点击弹出键盘按钮后:

丢失

实现过程

布局代码:

<!--工单号-->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/prescription_work_no"
        android:textColor="@color/holo_blue_bright"
        android:textSize="18sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ykh.tisanems.utils.KeyboardEditText
            android:id="@+id/prescription_work_no_search_key"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="@string/prescription_work_search_key"
            android:imeOptions="actionSearch"
            android:textColor="@color/colorAccent"
            android:textColorHint="@color/colorPrimaryLight" />

        <ImageView
            android:id="@+id/prescription_work_no_search_keyboard"
            android:layout_width="44dp"
            android:layout_height="44dp"
            android:padding="8dp"
            android:src="@drawable/icon_keyboard" />
    </LinearLayout>
</LinearLayout>

KeyboardEditText 可以使用EditText代替

控制代码:

//监听软键盘变化
KeyboardVisibilityEvent.setEventListener(
        context,
        new KeyboardVisibilityEventListener() {
            @Override
            public void onVisibilityChanged(boolean isOpen) {
                if (!isOpen) {
                    prescription_work_search_key.setInputType(InputType.TYPE_NULL);
                    prescription_work_search_keyboard.setImageResource(R.drawable.icon_keyboard);

                    prescription_work_no_search_key.setInputType(InputType.TYPE_NULL);
                    prescription_work_no_search_keyboard.setImageResource(R.drawable.icon_keyboard);
                }
            }
        });

prescription_work_search_key.setInputType(InputType.TYPE_NULL);

//软键盘弹出关闭
prescription_work_search_keyboard.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (prescription_work_search_key.getInputType() == InputType.TYPE_NULL) {
            prescription_work_search_key.setInputType(InputType.TYPE_CLASS_TEXT);
            prescription_work_search_key.requestFocus();
            prescription_work_search_key.setSelection(prescription_work_search_key.length());
            imm.showSoftInput(prescription_work_search_key, InputMethodManager.SHOW_FORCED);

            prescription_work_search_keyboard.setImageResource(R.drawable.icon_keyboard_off);
        } else {
            prescription_work_search_key.setInputType(InputType.TYPE_NULL);
            imm.hideSoftInputFromWindow(prescription_work_search_key.getWindowToken(), 0);

            prescription_work_search_keyboard.setImageResource(R.drawable.icon_keyboard);
        }
    }
});

//输入框焦点变化
prescription_work_search_key.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean b) {
        // 无论是否可输入、是否有焦点 都置于键盘关闭状态
        prescription_work_search_key.setInputType(InputType.TYPE_NULL);
        prescription_work_search_keyboard.setImageResource(R.drawable.icon_keyboard);

        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(prescription_work_search_key.getWindowToken(), 0);
    }
});

//开始搜索
prescription_work_search_key.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
        if (keyEvent.getAction() != KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
            searchPrescriptionWork(prescription_work_search_key.getText().toString().trim());
        }
        //不失去焦点
        return false;
    }
});

说明:

  1. 使用库KeyboardVisibilityEvent来全局监听软键盘的弹出和关闭,关闭时设置界面上所有的输入框的输入类型为InputType.TYPE_NULL,展开/收起软键盘按钮状态为收起。
  2. 设置该输入框的输入类型为InputType.TYPE_NULL,以保证点击后能获取到焦点但是不展开软键盘。
  3. 为展开/收起软键盘按钮设置点击事件,若当前输入框的输入类型为InputType.TYPE_NULL则认为当前软键盘收起,则展开软键盘并设置输入类型为InputType.TYPE_CLASS_TEXT,否则则收起键盘并设置输入框类型为InputType.TYPE_NULL
  4. 设置输入框焦点变化时始终收起软键盘。
  5. 为键盘和软键盘的Enter按钮绑定事件。