Browse Source

[feat]键盘插件,实现粘贴、删除、清空、发送功能

hezihao 8 months ago
parent
commit
125c952e0a

+ 1 - 1
plugins/keyboard_android/android/src/main/AndroidManifest.xml

@@ -20,7 +20,7 @@
         <service
             android:name=".keyboard.CustomKeyboardService"
             android:exported="true"
-            android:label="追爱小键盘"
+            android:label="@string/keyboard_app_name"
             android:permission="android.permission.BIND_INPUT_METHOD">
             <intent-filter>
                 <action android:name="android.view.InputMethod" />

+ 29 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/AiKeyboardComponent.kt

@@ -16,6 +16,7 @@ import com.atmob.keyboard_android.ext.click
 import com.atmob.keyboard_android.ext.setGone
 import com.atmob.keyboard_android.ext.setVisible
 import com.atmob.keyboard_android.model.AiKeyboardKeyModel
+import com.atmob.keyboard_android.util.InputMethodUtil
 import com.atmob.keyboard_android.util.KeyboardHolder
 import com.atmob.keyboard_android.util.recyclerview.GridDivider
 import com.atmob.keyboard_android.widget.indicator.TabPagerTitleView
@@ -40,6 +41,7 @@ class AiKeyboardComponent @JvmOverloads constructor(
     private lateinit var vMagicIndicator: MagicIndicator
     private lateinit var vPasteBarLayout: View
     private lateinit var vKeyList: RecyclerView
+    private lateinit var vPasteBtn: View
     private lateinit var vDeleteBtn: View
     private lateinit var vClearBtn: View
     private lateinit var vSendBtn: View
@@ -61,6 +63,7 @@ class AiKeyboardComponent @JvmOverloads constructor(
         vMagicIndicator = view.findViewById(R.id.magic_indicator)
         vPasteBarLayout = view.findViewById(R.id.paste_bar_layout)
         vKeyList = view.findViewById(R.id.key_list)
+        vPasteBtn = view.findViewById(R.id.paste_btn)
         vDeleteBtn = view.findViewById(R.id.delete_btn)
         vClearBtn = view.findViewById(R.id.clear_btn)
         vSendBtn = view.findViewById(R.id.send_btn)
@@ -179,11 +182,37 @@ class AiKeyboardComponent @JvmOverloads constructor(
      * 设置操作按钮
      */
     private fun setupActionBtn() {
+        // 粘贴
+        vPasteBtn.click {
+            val text = KeyboardHolder.getKeyboardService()
+                ?.getKeyboardViewModel()?.userClipboardData?.value ?: ""
+            if (text.isBlank()) {
+                return@click
+            }
+            KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
+                InputMethodUtil.inputText(it.currentInputConnection, text)
+            }
+        }
+
+        // 删除
         vDeleteBtn.click {
+            KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
+                InputMethodUtil.deleteInput(it.currentInputConnection)
+            }
         }
+
+        // 清空
         vClearBtn.click {
+            KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
+                InputMethodUtil.clearInput(it.currentInputConnection)
+            }
         }
+
+        // 发送
         vSendBtn.click {
+            KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
+                InputMethodUtil.clickSendBtn(it.currentInputConnection)
+            }
         }
     }
 

+ 5 - 62
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/keyboard/CustomKeyboardService.kt

@@ -1,13 +1,9 @@
 package com.atmob.keyboard_android.keyboard
 
-import android.annotation.SuppressLint
+import android.inputmethodservice.InputMethodService
 import android.view.View
 import android.view.Window
 import android.view.inputmethod.EditorInfo
-import android.widget.Button
-import android.widget.EditText
-import android.widget.GridLayout
-import android.widget.Toast
 import androidx.lifecycle.LifecycleOwner
 import com.atmob.keyboard_android.R
 import com.atmob.keyboard_android.keyboard.ext.InputMethodLifecycleService
@@ -62,7 +58,6 @@ class CustomKeyboardService : InputMethodLifecycleService(), ICustomKeyboardServ
         if (flutterEngine != null) {
             mMethodChannel =
                 MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "keyboard_android")
-            LogUtil.d("MethodChannel 初始化成功")
 
             // 设置 MethodChannel 的回调
             mMethodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
@@ -122,7 +117,6 @@ class CustomKeyboardService : InputMethodLifecycleService(), ICustomKeyboardServ
                         it["label"]!! to it["method"]!!
                     }
                     LogUtil.d("按键映射获取成功: $mKeyMappings")
-                    setupKeyboardButtons(vKeyboardView!!)
                 }
             }
 
@@ -137,61 +131,6 @@ class CustomKeyboardService : InputMethodLifecycleService(), ICustomKeyboardServ
     }
 
     /**
-     * 设置键盘按钮
-     *
-     * @param keyboardView 键盘视图
-     */
-    @SuppressLint("ClickableViewAccessibility")
-    private fun setupKeyboardButtons(keyboardView: View) {
-        LogUtil.d("当前键映射: $mKeyMappings")
-        val editText = keyboardView.findViewById<EditText>(R.id.keyboard_input)
-        val btnPaste = keyboardView.findViewById<Button>(R.id.btn_paste)
-        val btnDelete = keyboardView.findViewById<Button>(R.id.btn_delete)
-        val btnClear = keyboardView.findViewById<Button>(R.id.btn_clear)
-        val btnSend = keyboardView.findViewById<Button>(R.id.btn_send)
-        val numberPad = keyboardView.findViewById<GridLayout>(R.id.number_pad)
-
-        // 禁止触摸输入
-        editText.setOnTouchListener { _, _ ->
-            true
-        }
-        // 清空,避免重复创建
-        numberPad.removeAllViews()
-
-        LogUtil.d("setupKeyboardButtons: 添加 ${mKeyMappings.size} 个按钮")
-
-        mKeyMappings.forEach { (label, methodName) ->
-            val button = Button(this).apply {
-                text = label
-                layoutParams = GridLayout.LayoutParams()
-                // 每次点击时,都动态获取数据
-                setOnClickListener {
-                    sendDynamicTextRequest(methodName, editText.text.toString())
-                }
-            }
-            numberPad.addView(button)
-        }
-
-        btnPaste.setOnClickListener {
-            InputMethodUtil.pasteInput(editText, fail = {
-                Toast.makeText(this, "剪贴板为空", Toast.LENGTH_SHORT).show()
-            })
-        }
-
-        btnDelete.setOnClickListener {
-            InputMethodUtil.deleteInput(currentInputConnection)
-        }
-
-        btnClear.setOnClickListener {
-            InputMethodUtil.clearInput(currentInputConnection)
-        }
-
-        btnSend.setOnClickListener {
-            InputMethodUtil.clickSendBtn(currentInputConnection)
-        }
-    }
-
-    /**
      * 动态调用 Flutter 获取文本
      *
      * @param methodName 方法名
@@ -227,4 +166,8 @@ class CustomKeyboardService : InputMethodLifecycleService(), ICustomKeyboardServ
     override fun getLifecycleOwner(): LifecycleOwner {
         return this
     }
+
+    override fun asInputMethodService(): InputMethodService {
+        return this
+    }
 }

+ 6 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/keyboard/ICustomKeyboardService.kt

@@ -1,5 +1,6 @@
 package com.atmob.keyboard_android.keyboard
 
+import android.inputmethodservice.InputMethodService
 import android.view.Window
 import androidx.lifecycle.LifecycleOwner
 import com.atmob.keyboard_android.mvvm.viewmodel.KeyboardViewModel
@@ -22,4 +23,9 @@ interface ICustomKeyboardService {
      * 获取LifecycleOwner
      */
     fun getLifecycleOwner(): LifecycleOwner
+
+    /**
+     * 转换为InputMethodService类型返回
+     */
+    fun asInputMethodService(): InputMethodService
 }

+ 4 - 3
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/InputMethodUtil.kt

@@ -34,9 +34,9 @@ class InputMethodUtil private constructor() {
         }
 
         /**
-         * 粘贴文本到输入框中
+         * 粘贴文本到自己的输入框中
          */
-        fun pasteInput(
+        fun pasteText2EditText(
             editText: EditText,
             success: (() -> Unit)? = null,
             fail: (() -> Unit)? = null
@@ -44,7 +44,8 @@ class InputMethodUtil private constructor() {
             val clipboard = editText.context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
             val clipData = clipboard.primaryClip
             if (clipData != null && clipData.itemCount > 0) {
-                editText.setText(clipData.getItemAt(0).text.toString())
+                val text = clipData.getItemAt(0).text.toString()
+                editText.setText(text)
                 success?.invoke()
             } else {
                 fail?.invoke()

+ 0 - 72
plugins/keyboard_android/android/src/main/res/layout/keyboard_layout.xml

@@ -26,76 +26,4 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:visibility="gone" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:padding="5dp"
-        android:visibility="gone">
-
-        <!-- 输入框 -->
-        <EditText
-            android:id="@+id/keyboard_input"
-            android:layout_width="match_parent"
-            android:layout_height="50dp"
-            android:cursorVisible="false"
-            android:focusable="false"
-            android:hint="复制过来的文本"
-            android:inputType="none"
-            android:longClickable="true"
-            android:textSize="18sp" />
-
-        <!-- 数字键盘 + 操作按钮 -->
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:weightSum="4">
-
-            <GridLayout
-                android:id="@+id/number_pad"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="3"
-                android:columnCount="3"
-                android:padding="5dp"
-                android:rowCount="4">
-
-                <!-- 这里原有的静态按钮定义已全部删除 -->
-            </GridLayout>
-
-            <!-- 操作按钮 -->
-            <LinearLayout
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <Button
-                    android:id="@+id/btn_paste"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:text="粘贴" />
-
-                <Button
-                    android:id="@+id/btn_delete"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:text="删除" />
-
-                <Button
-                    android:id="@+id/btn_clear"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:text="清空" />
-
-                <Button
-                    android:id="@+id/btn_send"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:text="发送" />
-            </LinearLayout>
-        </LinearLayout>
-    </LinearLayout>
 </FrameLayout>

+ 3 - 3
plugins/keyboard_android/android/src/main/res/layout/quick_switch_component.xml

@@ -16,9 +16,9 @@
             android:id="@+id/mode_switch_layout"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginStart="1dp"
-            android:layout_marginTop="1dp"
-            android:layout_marginBottom="1dp"
+            android:layout_marginStart="2dp"
+            android:layout_marginTop="1.5dp"
+            android:layout_marginBottom="1.5dp"
             android:background="@mipmap/ic_quick_switch_checked"
             android:gravity="center_vertical">
 

+ 1 - 0
plugins/keyboard_android/android/src/main/res/values/string.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+    <string name="keyboard_app_name">追爱小键盘</string>
     <string name="login_tip">请登录后使用</string>
     <string name="go_login">去登录</string>
     <string name="vip_tip">您的免费提问次数已用完\n可订阅会员解锁无线提问</string>