Browse Source

[feat]键盘插件,封装路由组件

hezihao 9 months ago
parent
commit
2264cdcc4b
15 changed files with 346 additions and 131 deletions
  1. 64 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/AnimationComponent.kt
  2. 1 12
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/BaseUIComponent.kt
  3. 49 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/GroupComponent.kt
  4. 1 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/IUIComponent.kt
  5. 33 42
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/RouteComponent.kt
  6. 1 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/animator/impl/NoOptAnimator.kt
  7. 12 11
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/SettingComponent.kt
  8. 11 6
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/ToolBarComponent.kt
  9. 11 12
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/LoginPageComponent.kt
  10. 14 13
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/VipPageComponent.kt
  11. 23 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/root/IKeyboardRootComponent.kt
  12. 47 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/root/KeyboardRootComponent.kt
  13. 40 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/ViewTreeHelper.java
  14. 36 0
      plugins/keyboard_android/android/src/main/res/layout/component_keyboard_root.xml
  15. 3 33
      plugins/keyboard_android/android/src/main/res/layout/keyboard_layout.xml

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

@@ -0,0 +1,64 @@
+package com.atmob.keyboard_android.component.base
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import com.atmob.keyboard_android.component.base.animator.ComponentAnimator
+import com.atmob.keyboard_android.component.base.animator.impl.NoAnimationAnimator
+
+/**
+ * 带有动画功能的组件基类
+ */
+abstract class AnimationComponent @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : FrameLayout(context, attrs, defStyleAttr), IUIComponent {
+    /**
+     * 动画执行器
+     */
+    private val mComponentAnimator: ComponentAnimator
+
+    init {
+        // 创建组件动画执行器
+        mComponentAnimator = getComponentAnimator().newInstance() as ComponentAnimator
+        mComponentAnimator.attachUIComponent(this)
+    }
+
+    override fun show(onStart: (() -> Unit)?, onFinish: (() -> Unit)?) {
+        mComponentAnimator.show(onStart, onFinish = {
+            onComponentShow()
+            onFinish?.invoke()
+        })
+    }
+
+    override fun hide(onStart: (() -> Unit)?, onFinish: (() -> Unit)?) {
+        mComponentAnimator.hide(onStart, onFinish = {
+            onComponentHide()
+            onFinish?.invoke()
+        })
+    }
+
+    override fun asView(): ViewGroup {
+        return this
+    }
+
+    /**
+     * 获取组件的动画执行器
+     */
+    protected open fun getComponentAnimator(): Class<*> {
+        // 默认不使用动画,进行切换
+        return NoAnimationAnimator::class.java
+    }
+
+    /**
+     * 组件打开时回调
+     */
+    protected open fun onComponentShow() {
+    }
+
+    /**
+     * 组件关闭时回调
+     */
+    protected open fun onComponentHide() {
+    }
+}

+ 1 - 12
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/BaseUIComponent.kt

@@ -4,16 +4,14 @@ import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.view.View
-import android.view.ViewGroup
 import com.atmob.keyboard_android.component.ComponentMediator
-import com.atmob.keyboard_android.component.base.animator.impl.NoOptAnimator
 
 /**
  * UI组件抽象类,定义生命周期方法
  */
 abstract class BaseUIComponent<T : IUIComponent> @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
-) : RouteComponent(context, attrs, defStyleAttr), IUIComponent {
+) : GroupComponent(context, attrs, defStyleAttr), IBusinessComponent {
     init {
         // 组件创建,注册组件
         ComponentMediator.registerComponent(getComponentInterfaceClazz(), this)
@@ -52,13 +50,4 @@ abstract class BaseUIComponent<T : IUIComponent> @JvmOverloads constructor(
      * 返回组件的接口
      */
     abstract fun getComponentInterfaceClazz(): Class<T>
-
-    override fun getComponentAnimator(): Class<*> {
-        // 默认不使用动画,进行切换
-        return NoOptAnimator::class.java
-    }
-
-    override fun asView(): ViewGroup {
-        return this
-    }
 }

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

@@ -0,0 +1,49 @@
+package com.atmob.keyboard_android.component.base
+
+import android.content.Context
+import android.util.AttributeSet
+import com.atmob.keyboard_android.ext.getAllChildView
+import com.atmob.keyboard_android.util.ViewTreeHelper
+
+/**
+ * 可以包含其他子组件的容器组件
+ */
+abstract class GroupComponent @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : AnimationComponent(context, attrs, defStyleAttr) {
+    /**
+     * 直接子组件列表,也就是父组件下的直接子组件,不能隔代
+     */
+    private val mDirectChildComponentList: MutableList<IUIComponent> = mutableListOf()
+
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        // 获取所有直接子组件
+        val childComponentList = getAllChildView().filter { view ->
+            view is IUIComponent
+        }.map {
+            it as IUIComponent
+        }.toList()
+        mDirectChildComponentList.clear()
+        mDirectChildComponentList.addAll(childComponentList)
+    }
+
+    override fun onDetachedFromWindow() {
+        super.onDetachedFromWindow()
+        mDirectChildComponentList.clear()
+    }
+
+    /**
+     * 获取所有直接子组件
+     */
+    fun getDirectChildComponentList(): MutableList<IUIComponent> {
+        return mDirectChildComponentList
+    }
+
+    /**
+     * 通过组件Class类型,查找子组件
+     */
+    fun <T : IUIComponent> getChildComponent(componentClass: Class<T>): T? {
+        return ViewTreeHelper.findTargetView(this, componentClass)
+    }
+}

+ 1 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/IUIComponent.kt

@@ -5,7 +5,7 @@ import android.view.ViewGroup
 /**
  * UI组件接口,用于定义基础功能API
  */
-interface IUIComponent : IBusinessComponent {
+interface IUIComponent {
     /**
      * 将组件转换为View实例
      */

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

@@ -2,53 +2,44 @@ package com.atmob.keyboard_android.component.base
 
 import android.content.Context
 import android.util.AttributeSet
-import android.widget.FrameLayout
-import com.atmob.keyboard_android.component.base.animator.ComponentAnimator
 
 /**
- * 带路由功能的组件基类
+ * 带路由功能的组件
  */
-abstract class RouteComponent @JvmOverloads constructor(
+class RouteComponent @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
-) : FrameLayout(context, attrs, defStyleAttr), IUIComponent {
+) : GroupComponent(context, attrs, defStyleAttr) {
     /**
-     * 动画执行器
+     * 切换子组件,也就是先隐藏掉所有兄弟组件,再显示自己
+     *
+     * @param mutex 是否互斥,如果为true,则会隐藏其他子组件后,再显示自己,为false则是不隐藏兄弟组件,直接显示自己
      */
-    private val mComponentAnimator: ComponentAnimator
-
-    init {
-        mComponentAnimator = getComponentAnimator().newInstance() as ComponentAnimator
-        mComponentAnimator.attachUIComponent(this)
-    }
-
-    override fun show(onStart: (() -> Unit)?, onFinish: (() -> Unit)?) {
-        mComponentAnimator.show(onStart, onFinish = {
-            onComponentShow()
-            onFinish?.invoke()
-        })
-    }
-
-    override fun hide(onStart: (() -> Unit)?, onFinish: (() -> Unit)?) {
-        mComponentAnimator.hide(onStart, onFinish = {
-            onComponentHide()
-            onFinish?.invoke()
-        })
-    }
-
-    /**
-     * 获取组件的动画执行器
-     */
-    protected abstract fun getComponentAnimator(): Class<*>
-
-    /**
-     * 组件打开时回调
-     */
-    protected fun onComponentShow() {
-    }
-
-    /**
-     * 组件关闭时回调
-     */
-    protected fun onComponentHide() {
+    fun <T : IUIComponent> toggleChildComponent(
+        targetComponentClass: Class<T>,
+        mutex: Boolean = true
+    ) {
+        // 获取所有直接子组件
+        val directChildComponentList = getDirectChildComponentList()
+
+        // 找到目标组件
+        val targetComponent: IUIComponent? = directChildComponentList.find {
+            // 检查当前子View,是否是目标类型
+            targetComponentClass.isInstance(it)
+        }
+
+        if (targetComponent != null) {
+            // 找到兄弟组件
+            if (mutex) {
+                val siblingComponentList = directChildComponentList.filter {
+                    !targetComponentClass.isInstance(it)
+                }.toList()
+                // 先隐藏所有兄弟
+                siblingComponentList.forEach {
+                    it.hide()
+                }
+            }
+            // 再显示自己
+            targetComponent.show()
+        }
     }
 }

+ 1 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/animator/impl/NoOptAnimator.kt

@@ -6,7 +6,7 @@ import com.atmob.keyboard_android.component.base.animator.ComponentAnimator
 /**
  * 没有动画效果的动画执行器
  */
-class NoOptAnimator : ComponentAnimator() {
+class NoAnimationAnimator : ComponentAnimator() {
     override fun show(onStart: (() -> Unit)?, onFinish: (() -> Unit)?) {
         val uiComponent = getUIComponent()
         uiComponent?.asView()?.let { rootView ->

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

@@ -37,8 +37,7 @@ class SettingComponent @JvmOverloads constructor(
     override fun bindView(view: View) {
         vBackBtn.click {
             // 关闭
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateSettingPageShowing(false)
+            hide()
         }
         vSettingCustomPersonLayout.click {
             ToastUtils.showShort("跳转 => 定制人设")
@@ -58,25 +57,27 @@ class SettingComponent @JvmOverloads constructor(
      */
     private fun setupViewModel() {
         KeyboardHolder.getKeyboardService()?.run {
-            // 监听设置页的显示和隐藏
-            getKeyboardViewModel().settingPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                if (isShowing) {
-                    show()
-                } else {
-                    hide()
-                }
-            }
             // 如果键盘选择页打开,则关闭设置页
             getKeyboardViewModel().keyboardSelectPageShowing.observe(getLifecycleOwner()) { isShowing ->
                 if (isShowing) {
                     if (getKeyboardViewModel().settingPageShowing.value == true) {
-                        getKeyboardViewModel().updateSettingPageShowing(false)
+                        hide()
                     }
                 }
             }
         }
     }
 
+    override fun onComponentShow() {
+        super.onComponentShow()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.updateSettingPageShowing(true)
+    }
+
+    override fun onComponentHide() {
+        super.onComponentHide()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.updateSettingPageShowing(false)
+    }
+
     override fun getComponentAnimator(): Class<*> {
         return if (Constants.COMPONENT_ANIMATOR_ENABLE) {
             TransitionAnimator::class.java

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

@@ -5,8 +5,10 @@ import android.util.AttributeSet
 import android.view.View
 import android.widget.ImageView
 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.IToolBarComponent
+import com.atmob.keyboard_android.component.root.IKeyboardRootComponent
 import com.atmob.keyboard_android.enums.KeyboardGlobalType
 import com.atmob.keyboard_android.ext.click
 import com.atmob.keyboard_android.ext.longClick
@@ -42,8 +44,9 @@ class ToolBarComponent @JvmOverloads constructor(
 
         vIcon.click {
             // 切换到设置页
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateSettingPageShowing(true)
+            val rootComponent =
+                ComponentMediator.findComponent<IKeyboardRootComponent>(IKeyboardRootComponent::class.java)
+            rootComponent?.switchSettingPage()
         }
         vPinyinSwitchBtn.click {
             // 切换拼音键盘或AI键盘
@@ -61,8 +64,9 @@ class ToolBarComponent @JvmOverloads constructor(
         }
         // TODO: hezhiao,测试显示vip页,记得要去掉
         vIcon.longClick {
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateVipPageShowing(true)
+            val rootComponent =
+                ComponentMediator.findComponent<IKeyboardRootComponent>(IKeyboardRootComponent::class.java)
+            rootComponent?.switchVipPage()
             true
         }
         vKeyboardSwitchBtn.click {
@@ -71,8 +75,9 @@ class ToolBarComponent @JvmOverloads constructor(
         }
         vIntimacyLayout.click {
             // 点击亲密度布局,跳转去登录页
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateLoginPageShowing(true)
+            val rootComponent =
+                ComponentMediator.findComponent<IKeyboardRootComponent>(IKeyboardRootComponent::class.java)
+            rootComponent?.switchLoginPage()
         }
 
         setupViewModel()

+ 11 - 12
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/LoginPageComponent.kt

@@ -33,8 +33,7 @@ class LoginPageComponent @JvmOverloads constructor(
     override fun bindView(view: View) {
         vBackBtn.click {
             // 关闭
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateLoginPageShowing(false)
+            hide()
         }
         vLoginBtn.click {
             // 跳转到登录页
@@ -44,16 +43,16 @@ class LoginPageComponent @JvmOverloads constructor(
     }
 
     private fun setData() {
-        // 监听登录页,是否显示
-        KeyboardHolder.getKeyboardService()?.run {
-            getKeyboardViewModel().loginPageShowing.observe(getLifecycleOwner()) { isShowing ->
-                if (isShowing) {
-                    show()
-                } else {
-                    hide()
-                }
-            }
-        }
+    }
+
+    override fun onComponentShow() {
+        super.onComponentShow()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.updateLoginPageShowing(true)
+    }
+
+    override fun onComponentHide() {
+        super.onComponentHide()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.updateLoginPageShowing(false)
     }
 
     override fun getComponentAnimator(): Class<*> {

+ 14 - 13
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/VipPageComponent.kt

@@ -31,27 +31,28 @@ class VipPageComponent @JvmOverloads constructor(
 
     override fun bindView(view: View) {
         vBackBtn.click {
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateVipPageShowing(false)
+            hide()
         }
         vJoinVipBtn.click {
-            KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
-                ?.updateVipPageShowing(false)
+            hide()
         }
 
         setData()
     }
 
     private fun setData() {
-        KeyboardHolder.getKeyboardService()?.run {
-            getKeyboardViewModel().vipPageShowing.observe(getLifecycleOwner()) {
-                if (it) {
-                    show()
-                } else {
-                    hide()
-                }
-            }
-        }
+    }
+
+    override fun onComponentShow() {
+        super.onComponentShow()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateVipPageShowing(true)
+    }
+
+    override fun onComponentHide() {
+        super.onComponentHide()
+        KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
+            ?.updateVipPageShowing(false)
     }
 
     override fun getComponentAnimator(): Class<*> {

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

@@ -0,0 +1,23 @@
+package com.atmob.keyboard_android.component.root
+
+import com.atmob.keyboard_android.component.base.IUIComponent
+
+/**
+ * 键盘根组件接口
+ */
+interface IKeyboardRootComponent : IUIComponent {
+    /**
+     * 切换到Vip页面
+     */
+    fun switchVipPage()
+
+    /**
+     * 切换到登录页
+     */
+    fun switchLoginPage()
+
+    /**
+     * 切换到设置页
+     */
+    fun switchSettingPage()
+}

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

@@ -0,0 +1,47 @@
+package com.atmob.keyboard_android.component.root
+
+import android.content.Context
+import android.util.AttributeSet
+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.ISettingComponent
+import com.atmob.keyboard_android.component.page.ILoginPageComponent
+import com.atmob.keyboard_android.component.page.IVipPageComponent
+
+/**
+ * 键盘根组件
+ */
+class KeyboardRootComponent @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : BaseUIComponent<IKeyboardRootComponent>(context, attrs, defStyleAttr), IKeyboardRootComponent {
+    private lateinit var vRouteComponent: RouteComponent
+
+    override fun onInflateViewId(): Int {
+        return R.layout.component_keyboard_root
+    }
+
+    override fun findView(view: View) {
+        vRouteComponent = view.findViewById(R.id.root_route_component)
+    }
+
+    override fun bindView(view: View) {
+    }
+
+    override fun getComponentInterfaceClazz(): Class<IKeyboardRootComponent> {
+        return IKeyboardRootComponent::class.java
+    }
+
+    override fun switchVipPage() {
+        vRouteComponent.toggleChildComponent(IVipPageComponent::class.java, false)
+    }
+
+    override fun switchLoginPage() {
+        vRouteComponent.toggleChildComponent(ILoginPageComponent::class.java, false)
+    }
+
+    override fun switchSettingPage() {
+        vRouteComponent.toggleChildComponent(ISettingComponent::class.java, false)
+    }
+}

+ 40 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/ViewTreeHelper.java

@@ -0,0 +1,40 @@
+package com.atmob.keyboard_android.util;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * View树工具类
+ */
+public class ViewTreeHelper {
+    /**
+     * 递归遍历ViewGroup的子View,找到第一个符合目标类型的View
+     *
+     * @param root        待遍历的根布局
+     * @param targetClass 目标View的Class类型
+     * @return 找到的目标View,未找到则返回null
+     */
+    public static <T> T findTargetView(ViewGroup root, Class<T> targetClass) {
+        if (root == null || targetClass == null) {
+            throw new IllegalArgumentException("root and targetClass must not be null");
+        }
+
+        for (int i = 0; i < root.getChildCount(); i++) {
+            View child = root.getChildAt(i);
+
+            // 检查当前子View,是否是目标类型
+            if (targetClass.isInstance(child)) {
+                return targetClass.cast(child);
+            }
+
+            // 如果当前子View是ViewGroup,则递归遍历其子View
+            if (child instanceof ViewGroup) {
+                T result = findTargetView((ViewGroup) child, targetClass);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+}

+ 36 - 0
plugins/keyboard_android/android/src/main/res/layout/component_keyboard_root.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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">
+
+    <!-- 键盘组件 -->
+    <com.atmob.keyboard_android.component.child.impl.KeyBoardContainerComponent
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <!-- 键盘选择页 -->
+    <com.atmob.keyboard_android.component.child.impl.KeyboardSelectComponent
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone" />
+
+    <!-- 设置组件 -->
+    <com.atmob.keyboard_android.component.child.impl.SettingComponent
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone" />
+
+    <!-- 登录组件 -->
+    <com.atmob.keyboard_android.component.page.impl.LoginPageComponent
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone" />
+
+    <!-- VIP组件 -->
+    <com.atmob.keyboard_android.component.page.impl.VipPageComponent
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone" />
+</com.atmob.keyboard_android.component.base.RouteComponent>

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

@@ -1,35 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.atmob.keyboard_android.component.root.KeyboardRootComponent xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/route_component"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/keyboard_height"
-    android:background="@mipmap/bg_keyboard">
-
-    <!-- 键盘组件 -->
-    <com.atmob.keyboard_android.component.child.impl.KeyBoardContainerComponent
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-
-    <!-- 键盘选择页 -->
-    <com.atmob.keyboard_android.component.child.impl.KeyboardSelectComponent
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone" />
-
-    <!-- 设置组件 -->
-    <com.atmob.keyboard_android.component.child.impl.SettingComponent
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone" />
-
-    <!-- 登录组件 -->
-    <com.atmob.keyboard_android.component.page.impl.LoginPageComponent
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone" />
-
-    <!-- VIP组件 -->
-    <com.atmob.keyboard_android.component.page.impl.VipPageComponent
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone" />
-</FrameLayout>
+    android:layout_height="wrap_content" />