ソースを参照

[feat]键盘插件,使用路由切换,配合bringChildToFront方法,将子组件移动到最上方,避免用多个响应式变量来联动切换,导致互相影响的布局错乱

hezihao 8 ヶ月 前
コミット
febef1c360

+ 2 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/RouteComponent.kt

@@ -38,6 +38,8 @@ class RouteComponent @JvmOverloads constructor(
                     it.hide()
                 }
             }
+            // 将自己的层级,移动到父View的最顶层,从而覆盖住兄弟组件
+            targetComponent.asView().parent.bringChildToFront(targetComponent.asView())
             // 再显示自己
             targetComponent.show()
         }

+ 13 - 12
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/AiChatComponent.kt

@@ -48,8 +48,7 @@ class AiChatComponent @JvmOverloads constructor(
     override fun bindView(view: View) {
         vBackBtn.click {
             // 关闭面板
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateAiChatPageShowing(false)
+            hide()
         }
         vReGenerateBtn.click {
             // 重新生成
@@ -98,16 +97,18 @@ class AiChatComponent @JvmOverloads constructor(
      * 配置ViewModel
      */
     private fun setupViewModel() {
-        KeyboardHolder.getKeyboardService()?.run {
-            // 监听Ai生成页,显示或隐藏
-            getKeyboardViewModel().aiChatPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                if (isShowing) {
-                    show()
-                } else {
-                    hide()
-                }
-            }
-        }
+    }
+
+    override fun onComponentShow() {
+        super.onComponentShow()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateAiChatPageShowing(true)
+    }
+
+    override fun onComponentHide() {
+        super.onComponentHide()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateAiChatPageShowing(false)
     }
 
     /**

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

@@ -7,7 +7,9 @@ import android.view.View
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.atmob.keyboard_android.R
+import com.atmob.keyboard_android.component.ComponentMediator
 import com.atmob.keyboard_android.component.base.BaseUIComponent
+import com.atmob.keyboard_android.component.child.IAiChatComponent
 import com.atmob.keyboard_android.component.child.IAiKeyboardComponent
 import com.atmob.keyboard_android.component.item.AiKeyboardKeyViewBinder
 import com.atmob.keyboard_android.constant.Constants
@@ -170,8 +172,7 @@ class AiKeyboardComponent @JvmOverloads constructor(
             mKeyListAdapter = MultiTypeAdapter(mKeyListItems).apply {
                 register(AiKeyboardKeyModel::class.java, AiKeyboardKeyViewBinder {
                     // 点击键盘按键,打开AI生成内容面板
-                    KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                        ?.updateAiChatPageShowing(true)
+                    controlAiChatPageShowing(true)
                 })
             }
             layoutManager = GridLayoutManager(context, Constants.AI_KEYBOARD_KEY_LIST_SPAN_COUNT)
@@ -248,7 +249,7 @@ class AiKeyboardComponent @JvmOverloads constructor(
                 // 切换Tab
                 vMagicIndicator.onPageSelected(newTab.getIndex())
                 // 关闭Ai内容生成面板
-                getKeyboardViewModel().updateAiChatPageShowing(false)
+                controlAiChatPageShowing(false)
                 // 根据Tab,重新加载数据
                 loadKeyListByTab(newTab)
             }
@@ -309,7 +310,19 @@ class AiKeyboardComponent @JvmOverloads constructor(
             vPasteBarLayout.setVisible()
         }
         // 隐藏AI生成内容面板
-        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-            ?.updateAiChatPageShowing(false)
+        controlAiChatPageShowing(false)
+    }
+
+    /**
+     * 控制Ai生成内容面板,是否显示
+     */
+    private fun controlAiChatPageShowing(isShow: Boolean) {
+        val aiChatComponent =
+            ComponentMediator.findComponent<IAiChatComponent>(IAiChatComponent::class.java)
+        if (isShow) {
+            aiChatComponent?.show()
+        } else {
+            aiChatComponent?.hide()
+        }
     }
 }

+ 27 - 25
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/KeyboardSelectComponent.kt

@@ -50,8 +50,7 @@ class KeyboardSelectComponent @JvmOverloads constructor(
     override fun bindView(view: View) {
         vBackBtn.click {
             // 关闭选择页
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateKeyboardSelectPageShowing(false)
+            hide()
         }
         vSaveBtn.click {
             val selectKeyboard =
@@ -63,8 +62,7 @@ class KeyboardSelectComponent @JvmOverloads constructor(
             KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
                 ?.updateKeyboardType(selectKeyboard.name)
             // 关闭选择器
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateKeyboardSelectPageShowing(false)
+            hide()
         }
 
         // 配置列表
@@ -114,34 +112,38 @@ class KeyboardSelectComponent @JvmOverloads constructor(
         return IKeyboardSelectComponent::class.java
     }
 
+    override fun onComponentShow() {
+        super.onComponentShow()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateKeyboardSelectPageShowing(true)
+    }
+
+    override fun onComponentHide() {
+        super.onComponentHide()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateKeyboardSelectPageShowing(false)
+    }
+
     /**
      * 设置ViewModel
      */
     private fun setupViewModel() {
         KeyboardHolder.getKeyboardService()?.run {
             getKeyboardViewModel().run {
-                // 处理显示和关闭
-                keyboardSelectPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                    if (isShowing) {
-                        show()
-                    } else {
-                        hide()
-                    }
-                }
                 // 监听帮助模式切换时,关闭掉选择页
-                helpMode.observe(getLifecycleOwner()) {
-                    if (keyboardSelectPageShowing.value == true) {
-                        hide()
-                    }
-                }
-                // 设置页打开,则关闭掉选择页
-                settingPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                    if (isShowing) {
-                        if (keyboardSelectPageShowing.value == true) {
-                            updateKeyboardSelectPageShowing(false)
-                        }
-                    }
-                }
+//                helpMode.observe(getLifecycleOwner()) {
+//                    if (keyboardSelectPageShowing.value == true) {
+//                        hide()
+//                    }
+//                }
+                // 如果设置页打开,则关闭掉选择页
+//                settingPageShowing.observe(getLifecycleOwner()) { isShowing ->
+//                    if (isShowing) {
+//                        if (keyboardSelectPageShowing.value == true) {
+//                            updateKeyboardSelectPageShowing(false)
+//                        }
+//                    }
+//                }
             }
         }
     }

+ 11 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/QuickSwitchComponent.kt

@@ -5,8 +5,10 @@ import android.util.AttributeSet
 import android.view.View
 import android.widget.TextView
 import com.atmob.keyboard_android.R
+import com.atmob.keyboard_android.component.ComponentMediator
 import com.atmob.keyboard_android.component.base.BaseUIComponent
 import com.atmob.keyboard_android.component.child.IQuickSwitchComponent
+import com.atmob.keyboard_android.component.root.IKeyboardRootComponent
 import com.atmob.keyboard_android.enums.HelpMode
 import com.atmob.keyboard_android.ext.click
 import com.atmob.keyboard_android.ui.popup.ModeSwitchPopupWindow
@@ -51,14 +53,21 @@ class QuickSwitchComponent @JvmOverloads constructor(
                         // 切换模式
                         KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
                             ?.updateHelpMode(newMode)
+                        // 切换到键盘页
+                        val keyboardRootComponent = ComponentMediator.findComponent<IKeyboardRootComponent>(
+                            IKeyboardRootComponent::class.java
+                        )
+                        keyboardRootComponent?.switchKeyBoardPage()
                     }
                 })
             }
         }
         vKeyboardSelectLayout.click {
             // 显示键盘选择页
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateKeyboardSelectPageShowing(true)
+            val keyboardRootComponent = ComponentMediator.findComponent<IKeyboardRootComponent>(
+                IKeyboardRootComponent::class.java
+            )
+            keyboardRootComponent?.switchKeyboardSelectPage()
         }
 
         setupViewModel()

+ 7 - 7
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/SettingComponent.kt

@@ -58,13 +58,13 @@ class SettingComponent @JvmOverloads constructor(
     private fun setupViewModel() {
         KeyboardHolder.getKeyboardService()?.run {
             // 如果键盘选择页打开,则关闭设置页
-            getKeyboardViewModel().keyboardSelectPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                if (isShowing) {
-                    if (getKeyboardViewModel().settingPageShowing.value == true) {
-                        hide()
-                    }
-                }
-            }
+//            getKeyboardViewModel().keyboardSelectPageShowing.observe(getLifecycleOwner()) { isShowing ->
+//                if (isShowing) {
+//                    if (getKeyboardViewModel().settingPageShowing.value == true) {
+//                        hide()
+//                    }
+//                }
+//            }
         }
     }
 

+ 10 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/root/IKeyboardRootComponent.kt

@@ -20,4 +20,14 @@ interface IKeyboardRootComponent : IUIComponent {
      * 切换到设置页
      */
     fun switchSettingPage()
+
+    /**
+     * 切换到键盘选择页
+     */
+    fun switchKeyboardSelectPage()
+
+    /**
+     * 切换到键盘页
+     */
+    fun switchKeyBoardPage()
 }

+ 10 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/root/KeyboardRootComponent.kt

@@ -6,6 +6,8 @@ import android.view.View
 import com.atmob.keyboard_android.R
 import com.atmob.keyboard_android.component.base.BaseUIComponent
 import com.atmob.keyboard_android.component.base.RouteComponent
+import com.atmob.keyboard_android.component.child.IKeyBoardContainerComponent
+import com.atmob.keyboard_android.component.child.IKeyboardSelectComponent
 import com.atmob.keyboard_android.component.child.ISettingComponent
 import com.atmob.keyboard_android.component.page.ILoginPageComponent
 import com.atmob.keyboard_android.component.page.IVipPageComponent
@@ -44,4 +46,12 @@ class KeyboardRootComponent @JvmOverloads constructor(
     override fun switchSettingPage() {
         vRouteComponent.routeChildComponent(ISettingComponent::class.java)
     }
+
+    override fun switchKeyboardSelectPage() {
+        vRouteComponent.routeChildComponent(IKeyboardSelectComponent::class.java)
+    }
+
+    override fun switchKeyBoardPage() {
+        vRouteComponent.routeChildComponent(IKeyBoardContainerComponent::class.java)
+    }
 }

+ 28 - 10
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/widget/ClippedLayout.java

@@ -20,8 +20,19 @@ import com.atmob.keyboard_android.R;
  * 裁切背景顶部的布局
  */
 public class ClippedLayout extends FrameLayout {
+    /**
+     * 顶部裁切的高度
+     */
     private float topOffset;
 
+    /**
+     * 裁切是否开启
+     */
+    private boolean clipEnable = true;
+
+    /**
+     * Debug使用的画笔
+     */
     private Paint debugPaint;
 
     public ClippedLayout(@NonNull Context context) {
@@ -62,6 +73,7 @@ public class ClippedLayout extends FrameLayout {
                 R.styleable.ClippedLayout_cl_clip_top_offset,
                 0
         );
+        clipEnable = typedArray.getBoolean(R.styleable.ClippedLayout_cl_clip_enable, true);
         typedArray.recycle();
     }
 
@@ -79,8 +91,10 @@ public class ClippedLayout extends FrameLayout {
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         // 裁切后,让顶部透明区域,不消费点击事件
-        if (event.getY() < topOffset) {
-            return false;
+        if (clipEnable) {
+            if (event.getY() < topOffset) {
+                return false;
+            }
         }
         return super.onTouchEvent(event);
     }
@@ -90,16 +104,20 @@ public class ClippedLayout extends FrameLayout {
      */
     @Override
     public void draw(@NonNull Canvas canvas) {
-        // 预览模式:完整绘制背景,红色区域
-        if (isInEditMode()) {
-            super.draw(canvas);
-            canvas.drawRect(0, 0, getWidth(), topOffset, debugPaint);
+        if (clipEnable) {
+            // 预览模式:完整绘制背景,红色区域
+            if (isInEditMode()) {
+                super.draw(canvas);
+                canvas.drawRect(0, 0, getWidth(), topOffset, debugPaint);
+            } else {
+                // 正式环境:应用裁剪
+                canvas.save();
+                canvas.clipRect(0, topOffset, getWidth(), getHeight());
+                super.draw(canvas);
+                canvas.restore();
+            }
         } else {
-            // 正式环境:应用裁剪
-            canvas.save();
-            canvas.clipRect(0, topOffset, getWidth(), getHeight());
             super.draw(canvas);
-            canvas.restore();
         }
     }
 

+ 2 - 1
plugins/keyboard_android/android/src/main/res/layout/component_key_board_container.xml

@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/keyboard_height"
+    android:background="@mipmap/bg_keyboard"
     android:orientation="vertical">
 
     <!-- 工具栏 -->

+ 1 - 2
plugins/keyboard_android/android/src/main/res/layout/component_keyboard_root.xml

@@ -2,8 +2,7 @@
 <com.atmob.keyboard_android.component.base.RouteComponent xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/root_route_component"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/keyboard_height"
-    android:background="@mipmap/bg_keyboard">
+    android:layout_height="@dimen/keyboard_height">
 
     <!-- 键盘组件 -->
     <com.atmob.keyboard_android.component.child.impl.KeyBoardContainerComponent

+ 2 - 0
plugins/keyboard_android/android/src/main/res/values/attrs_clipped_layout.xml

@@ -4,5 +4,7 @@
     <declare-styleable name="ClippedLayout">
         <!-- 顶部的裁切区域的高度,单位为dp -->
         <attr name="cl_clip_top_offset" format="dimension" />
+        <!-- 裁切是否可用 -->
+        <attr name="cl_clip_enable" format="boolean" />
     </declare-styleable>
 </resources>