Jelajahi Sumber

feat: Banner广告栏,公共弹窗增加头图样式,支持半屏弹窗

DoggyZhang 12 jam lalu
induk
melakukan
5e8efda123
35 mengubah file dengan 912 tambahan dan 386 penghapusan
  1. 13 141
      app/src/main/java/com/adealink/weparty/commonui/widget/CommonDialog.kt
  2. 22 0
      app/src/main/java/com/adealink/weparty/module/activity/ActivityModule.kt
  3. 7 0
      app/src/main/java/com/adealink/weparty/module/activity/IActivityService.kt
  4. 46 0
      app/src/main/java/com/adealink/weparty/module/activity/banner/adapter/ImageBannerAdapter.kt
  5. 58 0
      app/src/main/java/com/adealink/weparty/module/activity/data/ActivityData.kt
  6. 10 0
      app/src/main/java/com/adealink/weparty/module/activity/viewmodel/IActivityViewModel.kt
  7. 0 3
      app/src/main/java/com/adealink/weparty/update/UpdateManager.kt
  8. 0 1
      app/src/main/java/com/adealink/weparty/update/dialog/AppUpdateDialog.kt
  9. 30 51
      app/src/main/java/com/adealink/weparty/util/IntentUtil.kt
  10. 61 0
      app/src/main/java/com/adealink/weparty/webview/WebViewDialogFragmentBuilder.kt
  11. 1 1
      app/src/main/res/layout/dialog_app_update.xml
  12. 88 130
      app/src/main/res/layout/layout_common_dialog.xml
  13. 16 0
      app/src/main/res/layout/layout_item_image_banner.xml
  14. 1 0
      app/src/main/res/values/colors.xml
  15. 29 0
      module/activity/src/main/java/com/adealink/weparty/activity/ActivityServiceImpl.kt
  16. 13 0
      module/activity/src/main/java/com/adealink/weparty/activity/data/ActivityData.kt
  17. 9 0
      module/activity/src/main/java/com/adealink/weparty/activity/datasource/remote/ActivityHttpService.kt
  18. 41 1
      module/activity/src/main/java/com/adealink/weparty/activity/viewmodel/ActivityViewModel.kt
  19. 25 1
      module/playmate/src/main/java/com/adealink/weparty/playmate/data/PlaymateListData.kt
  20. 5 5
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/PlaymateListFragment.kt
  21. 74 0
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/adapter/PlaymateBannerItemViewBinder.kt
  22. 39 3
      module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/PlaymateListViewModel.kt
  23. 16 0
      module/playmate/src/main/res/layout/item_playmate_home_banner.xml
  24. 77 0
      module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityComp.kt
  25. 72 0
      module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityDragView.kt
  26. 21 0
      module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityView.kt
  27. 17 12
      module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterDynamicFactory.kt
  28. 3 17
      module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterDynamicLayer.kt
  29. 2 0
      module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterRoomPageFragment.kt
  30. 34 0
      module/room/src/main/res/layout/layout_room_activity.xml
  31. 1 0
      module/room/src/main/res/values/ids.xml
  32. 1 3
      module/share/src/main/java/com/adealink/weparty/share/viewmodel/ShareViewModel.kt
  33. 47 15
      module/wallet/src/main/java/com/adealink/weparty/wallet/comp/WalletActivityComp.kt
  34. 19 0
      module/wallet/src/main/java/com/adealink/weparty/wallet/viewmodel/WalletViewModel.kt
  35. 14 2
      module/wallet/src/main/res/layout/layout_wallet_activity.xml

+ 13 - 141
app/src/main/java/com/adealink/weparty/commonui/widget/CommonDialog.kt

@@ -59,18 +59,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
      */
      */
     var onCancelListener: DialogInterface.OnCancelListener? = null
     var onCancelListener: DialogInterface.OnCancelListener? = null
 
 
-    /**
-     * 顶部图片
-     */
-    private var headerIconUri: Uri? = null
-
-    /**
-     * 标题颜色
-     */
-    private var titleColor: Int = 0
-
-    var customMessageView: View? = null
-
     private val binding by viewBinding(LayoutCommonDialogBinding::bind)
     private val binding by viewBinding(LayoutCommonDialogBinding::bind)
 
 
     private var isDismissAfterClick = true
     private var isDismissAfterClick = true
@@ -125,29 +113,29 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
         val showDefaultConfirm = arguments?.getBoolean(KEY_SHOW_DEFAULT_CONFIRM)
         val showDefaultConfirm = arguments?.getBoolean(KEY_SHOW_DEFAULT_CONFIRM)
         if (confirmText.isNullOrEmpty()) {
         if (confirmText.isNullOrEmpty()) {
             if (showDefaultConfirm == false) {
             if (showDefaultConfirm == false) {
-                binding.tvConfirm.visibility = View.GONE
+                binding.btnConfirm.visibility = View.GONE
             }
             }
         } else {
         } else {
-            binding.tvConfirm.text = confirmText
+            binding.btnConfirm.text = confirmText
         }
         }
         val positiveCountDownMS = arguments?.getLong(KEY_POSITIVE_COUNTDOWN_MS) ?: 0
         val positiveCountDownMS = arguments?.getLong(KEY_POSITIVE_COUNTDOWN_MS) ?: 0
         val isClickableWhenCountDown =
         val isClickableWhenCountDown =
             arguments?.getBoolean(KEY_IS_CLICKABLE_WHEN_COUNTDOWN, false) ?: false
             arguments?.getBoolean(KEY_IS_CLICKABLE_WHEN_COUNTDOWN, false) ?: false
-        if (binding.tvConfirm.isVisible && positiveCountDownMS > 0L) {
-            binding.tvConfirm.isEnabled = isClickableWhenCountDown
+        if (binding.btnConfirm.isVisible && positiveCountDownMS > 0L) {
+            binding.btnConfirm.isEnabled = isClickableWhenCountDown
             positiveCountDownTimer?.cancel()
             positiveCountDownTimer?.cancel()
             positiveCountDownTimer = object : CountDownTimer(positiveCountDownMS, 1000L) {
             positiveCountDownTimer = object : CountDownTimer(positiveCountDownMS, 1000L) {
                 @SuppressLint("SetTextI18n")
                 @SuppressLint("SetTextI18n")
                 override fun onTick(millisUntilFinished: Long) {
                 override fun onTick(millisUntilFinished: Long) {
-                    binding.tvConfirm.text = "${millisUntilFinished / 1000}s"
+                    binding.btnConfirm.text = "${millisUntilFinished / 1000}s"
                     countDownTimerFormat?.let {
                     countDownTimerFormat?.let {
-                        binding.tvConfirm.text = it.invoke(millisUntilFinished)
+                        binding.btnConfirm.text = it.invoke(millisUntilFinished)
                     }
                     }
                 }
                 }
 
 
                 override fun onFinish() {
                 override fun onFinish() {
-                    binding.tvConfirm.isEnabled = true
-                    binding.tvConfirm.text = when (confirmText.isNullOrEmpty()) {
+                    binding.btnConfirm.isEnabled = true
+                    binding.btnConfirm.text = when (confirmText.isNullOrEmpty()) {
                         true -> getCompatString(R.string.commonui_confirm)
                         true -> getCompatString(R.string.commonui_confirm)
                         else -> confirmText
                         else -> confirmText
                     }
                     }
@@ -162,21 +150,15 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
         val showDefaultCancel = arguments?.getBoolean(KEY_SHOW_DEFAULT_CANCEL)
         val showDefaultCancel = arguments?.getBoolean(KEY_SHOW_DEFAULT_CANCEL)
         if (cancelText.isNullOrEmpty()) {
         if (cancelText.isNullOrEmpty()) {
             if (showDefaultCancel == true) {
             if (showDefaultCancel == true) {
-                binding.tvCancel.visibility = View.VISIBLE
+                binding.btnCancel.visibility = View.VISIBLE
             }
             }
         } else {
         } else {
-            binding.tvCancel.text = cancelText
-            binding.tvCancel.visibility = View.VISIBLE
+            binding.btnCancel.text = cancelText
+            binding.btnCancel.visibility = View.VISIBLE
         }
         }
     }
     }
 
 
     private fun initHeader() {
     private fun initHeader() {
-        //头图
-        headerIconUri = arguments?.getParcelable(KEY_HEADER_ICON_URI)
-        if (headerIconUri != null) {
-            binding.headerIv.visibility = View.VISIBLE
-            binding.headerIv.setImageURI(headerIconUri, true)
-        }
         //顶部关闭按钮
         //顶部关闭按钮
         val showTopCloseBtn = arguments?.getBoolean(KEY_SHOW_TOP_CLOSE_BTN) ?: false
         val showTopCloseBtn = arguments?.getBoolean(KEY_SHOW_TOP_CLOSE_BTN) ?: false
         if (showTopCloseBtn) {
         if (showTopCloseBtn) {
@@ -190,34 +172,9 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
     }
     }
 
 
     private fun initTitleMessageView() {
     private fun initTitleMessageView() {
-        // 顶部背景图
-        val topBgRes = arguments?.getInt(KEY_TOP_BG_RES) ?: 0
-        if (topBgRes != 0) {
-            binding.ivTopBg.visibility = View.VISIBLE
-            binding.ivTopBg.setImageResource(topBgRes)
-        } else {
-            binding.ivTopBg.visibility = View.GONE
-        }
-
-        //标题上面的图片
-        val topImageUri: Uri? = arguments?.getParcelable(KEY_TOP_IMG_URI)
-        val topImageWidth = arguments?.getInt(KEY_TOP_IMG_WIDTH) ?: 0
-        val topImageHeight = arguments?.getInt(KEY_TOP_IMG_HEIGHT) ?: 0
-        if (topImageUri != null) {
-            binding.ivTop.visibility = View.VISIBLE
-            val lp = binding.ivTop.layoutParams
-            lp.width = topImageWidth
-            lp.height = topImageHeight
-            binding.ivTop.layoutParams = lp
-            binding.ivTop.setImageURI(topImageUri, true)
-        } else {
-            binding.ivTop.visibility = View.GONE
-        }
-
         val title = arguments?.getCharSequence(KEY_TITLE)
         val title = arguments?.getCharSequence(KEY_TITLE)
         val msg = arguments?.getCharSequence(KEY_MESSAGE)
         val msg = arguments?.getCharSequence(KEY_MESSAGE)
         val msgGravity = arguments?.getInt(KEY_MESSAGE_GRAVITY)
         val msgGravity = arguments?.getInt(KEY_MESSAGE_GRAVITY)
-        titleColor = arguments?.getInt(KEY_TITLE_COLOR) ?: 0
         //若标题为空,内容展示在标题的位置上
         //若标题为空,内容展示在标题的位置上
         if (title.isNullOrEmpty()) {
         if (title.isNullOrEmpty()) {
             binding.tvMessage.visibility = View.GONE
             binding.tvMessage.visibility = View.GONE
@@ -226,23 +183,17 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             binding.tvTitle.text = title
             binding.tvTitle.text = title
             initMessageView(binding.tvMessage, msg, msgGravity)
             initMessageView(binding.tvMessage, msg, msgGravity)
         }
         }
-
-        //自定义messageView
-        if (customMessageView != null) {
-            binding.flSubBlock.visibility = View.VISIBLE
-            binding.flSubBlock.addView(customMessageView)
-        }
     }
     }
 
 
     private fun initEvent() {
     private fun initEvent() {
-        binding.tvConfirm.setOnClickListener {
+        binding.btnConfirm.setOnClickListener {
             onPositive?.invoke()
             onPositive?.invoke()
             if (isDismissAfterClick) {
             if (isDismissAfterClick) {
                 dismissAllowingStateLoss()
                 dismissAllowingStateLoss()
             }
             }
         }
         }
 
 
-        binding.tvCancel.setOnClickListener {
+        binding.btnCancel.setOnClickListener {
             onNegative?.invoke()
             onNegative?.invoke()
             if (isDismissAfterClick) {
             if (isDismissAfterClick) {
                 dismissAllowingStateLoss()
                 dismissAllowingStateLoss()
@@ -287,12 +238,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
         private const val KEY_SHOW_DEFAULT_CANCEL = "show_default_cancel"
         private const val KEY_SHOW_DEFAULT_CANCEL = "show_default_cancel"
         private const val KEY_SHOW_DEFAULT_CONFIRM = "show_default_confirm"
         private const val KEY_SHOW_DEFAULT_CONFIRM = "show_default_confirm"
         private const val KEY_IS_DISMISS_AFTER_CLICK = "is_dismiss_after_click"
         private const val KEY_IS_DISMISS_AFTER_CLICK = "is_dismiss_after_click"
-        private const val KEY_HEADER_ICON_URI = "header_icon_uri"
-        private const val KEY_TITLE_COLOR = "title_color"
-        private const val KEY_TOP_BG_RES = "top_bg_res"
-        private const val KEY_TOP_IMG_URI = "top_img_uri"
-        private const val KEY_TOP_IMG_WIDTH = "top_img_width"
-        private const val KEY_TOP_IMG_HEIGHT = "top_img_height"
         private const val KEY_SHOW_TOP_CLOSE_BTN = "key_show_top_close_btn"
         private const val KEY_SHOW_TOP_CLOSE_BTN = "key_show_top_close_btn"
         private const val KEY_POSITIVE_COUNTDOWN_MS = "positive_countdown_ms"
         private const val KEY_POSITIVE_COUNTDOWN_MS = "positive_countdown_ms"
         private const val KEY_IS_CLICKABLE_WHEN_COUNTDOWN =
         private const val KEY_IS_CLICKABLE_WHEN_COUNTDOWN =
@@ -300,7 +245,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
 
 
         @JvmStatic
         @JvmStatic
         fun newInstance(
         fun newInstance(
-            headerIconUri: Uri? = null,
             title: CharSequence? = null,
             title: CharSequence? = null,
             message: CharSequence? = null,
             message: CharSequence? = null,
             messageGravity: Int = Gravity.CENTER,
             messageGravity: Int = Gravity.CENTER,
@@ -318,12 +262,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             canceledOnTouchOutside: Boolean,
             canceledOnTouchOutside: Boolean,
             onCancelListener: DialogInterface.OnCancelListener? = null,
             onCancelListener: DialogInterface.OnCancelListener? = null,
             isDismissAfterClick: Boolean = true,
             isDismissAfterClick: Boolean = true,
-            titleColor: Int = 0,
-            customMessageView: View? = null,
-            topBgRes: Int = 0,
-            topImageUri: Uri? = null,
-            topImageWidth: Int,
-            topImageHeight: Int,
             showTopCloseBtn: Boolean,
             showTopCloseBtn: Boolean,
             positiveCountDownMS: Long = 0,
             positiveCountDownMS: Long = 0,
             isClickableWhenCountDown: Boolean = false,
             isClickableWhenCountDown: Boolean = false,
@@ -340,12 +278,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             bundle.putBoolean(KEY_SHOW_DEFAULT_CONFIRM, showDefaultConfirm)
             bundle.putBoolean(KEY_SHOW_DEFAULT_CONFIRM, showDefaultConfirm)
             bundle.putBoolean(KEY_SHOW_DEFAULT_CANCEL, showDefaultCancel)
             bundle.putBoolean(KEY_SHOW_DEFAULT_CANCEL, showDefaultCancel)
             bundle.putBoolean(KEY_IS_DISMISS_AFTER_CLICK, isDismissAfterClick)
             bundle.putBoolean(KEY_IS_DISMISS_AFTER_CLICK, isDismissAfterClick)
-            bundle.putParcelable(KEY_HEADER_ICON_URI, headerIconUri)
-            bundle.putInt(KEY_TITLE_COLOR, titleColor)
-            bundle.putInt(KEY_TOP_BG_RES, topBgRes)
-            bundle.putParcelable(KEY_TOP_IMG_URI, topImageUri)
-            bundle.putInt(KEY_TOP_IMG_WIDTH, topImageWidth)
-            bundle.putInt(KEY_TOP_IMG_HEIGHT, topImageHeight)
             bundle.putBoolean(KEY_SHOW_TOP_CLOSE_BTN, showTopCloseBtn)
             bundle.putBoolean(KEY_SHOW_TOP_CLOSE_BTN, showTopCloseBtn)
             bundle.putLong(KEY_POSITIVE_COUNTDOWN_MS, positiveCountDownMS)
             bundle.putLong(KEY_POSITIVE_COUNTDOWN_MS, positiveCountDownMS)
             bundle.putBoolean(KEY_IS_CLICKABLE_WHEN_COUNTDOWN, isClickableWhenCountDown)
             bundle.putBoolean(KEY_IS_CLICKABLE_WHEN_COUNTDOWN, isClickableWhenCountDown)
@@ -358,14 +290,12 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             dialog.onCancelListener = onCancelListener
             dialog.onCancelListener = onCancelListener
             dialog.mCancelable = cancelable
             dialog.mCancelable = cancelable
             dialog.mCanceledOnTouchOutside = canceledOnTouchOutside
             dialog.mCanceledOnTouchOutside = canceledOnTouchOutside
-            dialog.customMessageView = customMessageView
             dialog.arguments = bundle
             dialog.arguments = bundle
             return dialog
             return dialog
         }
         }
     }
     }
 
 
     class Builder {
     class Builder {
-        private var headerIconUri: Uri? = null
         private var title: CharSequence? = null
         private var title: CharSequence? = null
         private var message: CharSequence? = null
         private var message: CharSequence? = null
         private var messageGravity: Int = Gravity.CENTER
         private var messageGravity: Int = Gravity.CENTER
@@ -383,13 +313,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
         private var canceledOnTouchOutside: Boolean = false
         private var canceledOnTouchOutside: Boolean = false
         private var onCancelListener: DialogInterface.OnCancelListener? = null
         private var onCancelListener: DialogInterface.OnCancelListener? = null
         private var isDismissAfterClick: Boolean = true
         private var isDismissAfterClick: Boolean = true
-
-        private var titleColor: Int = 0
-        private var topImageUri: Uri? = null
-        private var customMessageView: View? = null
-        private var topBgRes: Int = 0
-        private var topImageWidth: Int = 0
-        private var topImageHeight: Int = 0
         private var showTopCloseBtn: Boolean = false
         private var showTopCloseBtn: Boolean = false
         private var positiveCountDownMS: Long = 0
         private var positiveCountDownMS: Long = 0
         private var isClickableWhenCountDown: Boolean = false //倒计时期间能否点击按钮
         private var isClickableWhenCountDown: Boolean = false //倒计时期间能否点击按钮
@@ -401,45 +324,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             return this
             return this
         }
         }
 
 
-        fun topBgResource(resourceId: Int): Builder {
-            topBgRes = resourceId
-            return this
-        }
-
-        fun customMessageView(view: View): Builder {
-            customMessageView = view
-            return this
-        }
-
-        fun topImageResource(resourceId: Int): Builder {
-            topImageUri = UriUtil.getUriForResourceId(resourceId)
-            return this
-        }
-
-        fun topImageResource(resourceId: Int, width: Int, height: Int): Builder {
-            topImageUri = UriUtil.getUriForResourceId(resourceId)
-            topImageWidth = width
-            topImageHeight = height
-            return this
-        }
-
-        fun topImageUrl(url: String, width: Int, height: Int): Builder {
-            topImageUri = UriUtil.parseUriOrNull(url)
-            topImageWidth = width
-            topImageHeight = height
-            return this
-        }
-
-        fun headerIconResource(resourceId: Int): Builder {
-            headerIconUri = UriUtil.getUriForResourceId(resourceId)
-            return this
-        }
-
-        fun headerIconUrl(url: String): Builder {
-            headerIconUri = UriUtil.parseUriOrNull(url)
-            return this
-        }
-
         fun title(title: CharSequence): Builder {
         fun title(title: CharSequence): Builder {
             this.title = title
             this.title = title
             return this
             return this
@@ -495,11 +379,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
             return this
             return this
         }
         }
 
 
-        fun titleColor(@ColorRes color: Int): Builder {
-            this.titleColor = color
-            return this
-        }
-
         fun messageGravity(gravity: Int): Builder {
         fun messageGravity(gravity: Int): Builder {
             this.messageGravity = gravity
             this.messageGravity = gravity
             return this
             return this
@@ -527,7 +406,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
 
 
         fun build(): CommonDialog {
         fun build(): CommonDialog {
             return newInstance(
             return newInstance(
-                headerIconUri,
                 title,
                 title,
                 message,
                 message,
                 messageGravity,
                 messageGravity,
@@ -542,12 +420,6 @@ open class CommonDialog : BaseDialogFragment(R.layout.layout_common_dialog) {
                 canceledOnTouchOutside,
                 canceledOnTouchOutside,
                 onCancelListener,
                 onCancelListener,
                 isDismissAfterClick,
                 isDismissAfterClick,
-                titleColor,
-                customMessageView,
-                topBgRes,
-                topImageUri,
-                topImageWidth,
-                topImageHeight,
                 showTopCloseBtn,
                 showTopCloseBtn,
                 positiveCountDownMS,
                 positiveCountDownMS,
                 isClickableWhenCountDown,
                 isClickableWhenCountDown,

+ 22 - 0
app/src/main/java/com/adealink/weparty/module/activity/ActivityModule.kt

@@ -1,7 +1,13 @@
 package com.adealink.weparty.module.activity
 package com.adealink.weparty.module.activity
 
 
+import androidx.lifecycle.ViewModelStoreOwner
 import com.adealink.frame.aab.BaseDynamicModule
 import com.adealink.frame.aab.BaseDynamicModule
+import com.adealink.frame.aab.constant.AABModuleNotInitError
+import com.adealink.frame.base.Rlt
 import com.adealink.weparty.R
 import com.adealink.weparty.R
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
 
 
 object ActivityModule : BaseDynamicModule<IActivityService>(IActivityService::class),
 object ActivityModule : BaseDynamicModule<IActivityService>(IActivityService::class),
     IActivityService {
     IActivityService {
@@ -22,10 +28,26 @@ object ActivityModule : BaseDynamicModule<IActivityService>(IActivityService::cl
             override fun onLogout() {
             override fun onLogout() {
 
 
             }
             }
+
+            override suspend fun pullBanners(banner: Banner): Rlt<List<BannerData>> {
+                return Rlt.Failed(AABModuleNotInitError())
+            }
+
+            override fun getActivityViewModel(owner: ViewModelStoreOwner): IActivityViewModel? {
+                return null
+            }
         }
         }
     }
     }
 
 
     override fun onLogout() {
     override fun onLogout() {
         getService().onLogout()
         getService().onLogout()
     }
     }
+
+    override suspend fun pullBanners(banner: Banner): Rlt<List<BannerData>> {
+        return getService().pullBanners(banner)
+    }
+
+    override fun getActivityViewModel(owner: ViewModelStoreOwner): IActivityViewModel? {
+        return getService().getActivityViewModel(owner)
+    }
 }
 }

+ 7 - 0
app/src/main/java/com/adealink/weparty/module/activity/IActivityService.kt

@@ -1,7 +1,14 @@
 package com.adealink.weparty.module.activity
 package com.adealink.weparty.module.activity
 
 
+import androidx.lifecycle.ViewModelStoreOwner
+import com.adealink.frame.base.Rlt
 import com.adealink.weparty.aab.IService
 import com.adealink.weparty.aab.IService
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
 
 
 interface IActivityService : IService<IActivityService> {
 interface IActivityService : IService<IActivityService> {
+    suspend fun pullBanners(banner: Banner): Rlt<List<BannerData>>
+    fun getActivityViewModel(owner: ViewModelStoreOwner): IActivityViewModel?
 
 
 }
 }

+ 46 - 0
app/src/main/java/com/adealink/weparty/module/activity/banner/adapter/ImageBannerAdapter.kt

@@ -0,0 +1,46 @@
+package com.adealink.weparty.module.activity.banner.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.ImageView
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.widget.banner.adapter.BannerAdapter
+import com.adealink.weparty.databinding.LayoutItemImageBannerBinding
+import com.adealink.weparty.module.activity.data.BannerData
+import com.facebook.drawee.generic.RoundingParams
+
+class ImageBannerAdapter(
+    banners: List<BannerData>,
+    val scaleType: ImageView.ScaleType? = null,
+    val cornerRadiusPx: Float? = null
+) : BannerAdapter<BannerData, BindingViewHolder<LayoutItemImageBannerBinding>>(banners) {
+
+    override fun onCreateHolder(
+        parent: ViewGroup,
+        viewType: Int,
+    ): BindingViewHolder<LayoutItemImageBannerBinding> {
+        return BindingViewHolder(
+            LayoutItemImageBannerBinding.inflate(
+                LayoutInflater.from(parent.context),
+                parent,
+                false
+            )
+        )
+    }
+
+    override fun onBindView(
+        holder: BindingViewHolder<LayoutItemImageBannerBinding>,
+        data: BannerData,
+        position: Int,
+        size: Int,
+    ) {
+        holder.binding.icon.setImageUrl(data.img)
+        scaleType?.let {
+            holder.binding.icon.scaleType = scaleType
+        }
+        cornerRadiusPx?.let {
+            holder.binding.icon.hierarchy.setRoundingParams(RoundingParams.fromCornersRadius(it))
+        }
+    }
+
+}

+ 58 - 0
app/src/main/java/com/adealink/weparty/module/activity/data/ActivityData.kt

@@ -0,0 +1,58 @@
+package com.adealink.weparty.module.activity.data
+
+import android.net.Uri
+import com.adealink.weparty.util.IS_DIALOG
+import com.google.gson.annotations.GsonNullable
+import com.google.gson.annotations.SerializedName
+
+enum class Banner(val type: Int) {
+    HOME(1),
+    ROOM(2),
+    WALLET(3),
+}
+
+data class BannerData(
+    @SerializedName("img") val img: String,
+    @SerializedName("title") val title: String,
+    @SerializedName("subtitle") val subtitle: String,
+    @SerializedName("target") val target: Int, //0=无跳转,1=H5页面,2=H5半屏
+    @GsonNullable
+    @SerializedName("jump") val jump: String?,
+    @GsonNullable
+    @SerializedName("startTime") val startTime: Long?,
+    @GsonNullable
+    @SerializedName("stopTime") val stopTime: Long?,
+) {
+    fun isAvailable(): Boolean {
+        val nowTs = System.currentTimeMillis()
+        return if (startTime != null && stopTime != null) {
+            nowTs in startTime..<stopTime
+        } else if (startTime != null) {
+            startTime < nowTs
+        } else if (stopTime != null) {
+            nowTs < stopTime
+        } else {
+            true
+        }
+    }
+
+    fun getJumpUrl(): String? {
+        return when (target) {
+            1 -> {
+                jump
+            }
+
+            2 -> {
+                val url = jump
+                if (url.isNullOrEmpty()) {
+                    return null
+                }
+                Uri.parse(url).buildUpon().apply {
+                    appendQueryParameter(IS_DIALOG, "true")
+                }.toString()
+            }
+
+            else -> null
+        }
+    }
+}

+ 10 - 0
app/src/main/java/com/adealink/weparty/module/activity/viewmodel/IActivityViewModel.kt

@@ -1,4 +1,14 @@
 package com.adealink.weparty.module.activity.viewmodel
 package com.adealink.weparty.module.activity.viewmodel
 
 
+import androidx.lifecycle.LiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtLiveData
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
+
 interface IActivityViewModel {
 interface IActivityViewModel {
+
+    val bannersLD: ExtLiveData<List<BannerData>>
+
+    fun pullBanners(banner: Banner): LiveData<Rlt<List<BannerData>>>
 }
 }

+ 0 - 3
app/src/main/java/com/adealink/weparty/update/UpdateManager.kt

@@ -274,8 +274,5 @@ class UpdateManager : BaseFrame<IUpdateListener>(), IUpdateManager, ActivityLife
             canceledOnTouchOutside(false)
             canceledOnTouchOutside(false)
             dismissAfterClick(false)
             dismissAfterClick(false)
         }.build().show(checkActivity.supportFragmentManager, FORCE_UPDATE_DIALOG)
         }.build().show(checkActivity.supportFragmentManager, FORCE_UPDATE_DIALOG)
-
-
-        showCompleteUpdateDialog()
     }
     }
 }
 }

+ 0 - 1
app/src/main/java/com/adealink/weparty/update/dialog/AppUpdateDialog.kt

@@ -225,7 +225,6 @@ class AppUpdateDialog : BaseDialogFragment(R.layout.dialog_app_update) {
     }
     }
 
 
     class Builder {
     class Builder {
-        private var headerIconUri: Uri? = null
         private var title: CharSequence? = null
         private var title: CharSequence? = null
         private var message: CharSequence? = null
         private var message: CharSequence? = null
         private var messageGravity: Int = Gravity.CENTER
         private var messageGravity: Int = Gravity.CENTER

+ 30 - 51
app/src/main/java/com/adealink/weparty/util/IntentUtil.kt

@@ -2,7 +2,6 @@ package com.adealink.weparty.util
 
 
 import android.content.Context
 import android.content.Context
 import android.content.Intent
 import android.content.Intent
-import android.net.Uri
 import android.os.Build
 import android.os.Build
 import android.os.Bundle
 import android.os.Bundle
 import androidx.core.net.toUri
 import androidx.core.net.toUri
@@ -13,9 +12,18 @@ import com.adealink.frame.util.DisplayUtil
 import com.adealink.frame.util.PackageUtil
 import com.adealink.frame.util.PackageUtil
 import com.adealink.frame.util.getParamsFromUri
 import com.adealink.frame.util.getParamsFromUri
 import com.adealink.weparty.R
 import com.adealink.weparty.R
-import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.module.webview.Web
 import com.adealink.weparty.module.webview.Web
+import com.adealink.weparty.webview.WebViewDialogFragmentBuilder
+
+//通用Url参数
+const val MIN_VERSION = "min_android_version"
+const val IS_DIALOG = "is_dialog"
+const val DIALOG_TAG = "dialog_tag"
+const val ASPECT_RATIO = "aspect_ratio"
+const val TRANSPARENT = "transparent"
+const val CANCEL_TOUCH_OUTSIDE = "canceled_on_touch_outside"
+
 
 
 fun goLocalLinkPage(context: Context?, link: String?) {
 fun goLocalLinkPage(context: Context?, link: String?) {
     if (context == null || link.isNullOrEmpty()) {
     if (context == null || link.isNullOrEmpty()) {
@@ -25,7 +33,7 @@ fun goLocalLinkPage(context: Context?, link: String?) {
     try {
     try {
         // 判断版本号信息("jiehe://gami/main?min_android_version=XXX&min_ios_version=XXX")
         // 判断版本号信息("jiehe://gami/main?min_android_version=XXX&min_ios_version=XXX")
         val minAndroidVersion =
         val minAndroidVersion =
-            getParamsFromUri(link.toUri())["min_android_version"]?.toIntOrNull()
+            getParamsFromUri(link.toUri())[MIN_VERSION]?.toIntOrNull()
         if (minAndroidVersion != null) {
         if (minAndroidVersion != null) {
             val currentVersion = PackageUtil.getVersionCode()
             val currentVersion = PackageUtil.getVersionCode()
             if (currentVersion < minAndroidVersion) {
             if (currentVersion < minAndroidVersion) {
@@ -37,11 +45,6 @@ fun goLocalLinkPage(context: Context?, link: String?) {
         when {
         when {
             // 网页链接
             // 网页链接
             link.startsWith("http") || link.startsWith("https") -> handleHttpLink(context, link)
             link.startsWith("http") || link.startsWith("https") -> handleHttpLink(context, link)
-            //指定弹窗
-            link.startsWith(AppBase.deeplinkScheme) && link.contains(INTENT_DIALOG) -> handleOpenDialogLink(
-                context,
-                link
-            )
             // DeepLink
             // DeepLink
             link.startsWith(AppBase.deeplinkScheme) -> handleDeepLink(context, link)
             link.startsWith(AppBase.deeplinkScheme) -> handleDeepLink(context, link)
             else -> {
             else -> {
@@ -53,28 +56,6 @@ fun goLocalLinkPage(context: Context?, link: String?) {
     }
     }
 }
 }
 
 
-private fun handleOpenDialogLink(context: Context, link: String) {
-    //打开指定弹窗
-    val activity = context as? FragmentActivity ?: return
-    val uri = Uri.parse(link)
-    val paramsMap = uri.queryParameterNames.associateWith { uri.getQueryParameter(it) }
-    val routerPath = paramsMap["page"]?.let {
-        if (it.startsWith("/")) it else "/$it"
-    }
-    val dialogTag = paramsMap["dialog_tag"] ?: ""
-    if (!routerPath.isNullOrEmpty()) {
-        Router.getRouterInstance<BaseDialogFragment>(routerPath)?.apply {
-            arguments = Bundle().apply {
-                for ((key, value) in paramsMap) {
-                    if (value != null) {
-                        putString(key, value)
-                    }
-                }
-            }
-        }?.show(activity.supportFragmentManager, dialogTag)
-    }
-}
-
 private fun handleDeepLink(context: Context, link: String) {
 private fun handleDeepLink(context: Context, link: String) {
     // 通过DeepLink 跳转的指定页面
     // 通过DeepLink 跳转的指定页面
     val intent = Intent(Intent.ACTION_VIEW, link.toUri())
     val intent = Intent(Intent.ACTION_VIEW, link.toUri())
@@ -84,39 +65,37 @@ private fun handleDeepLink(context: Context, link: String) {
 
 
 private fun handleHttpLink(context: Context, link: String) {
 private fun handleHttpLink(context: Context, link: String) {
     val params = getParamsFromUri(link.toUri())
     val params = getParamsFromUri(link.toUri())
-    val aspectRatio = params["aspect_ratio"]?.toFloatOrNull() //高度/宽度
+    val aspectRatio = params[ASPECT_RATIO]?.toFloatOrNull() //高度/宽度
     val activity = context as? FragmentActivity
     val activity = context as? FragmentActivity
-    val transparent = params["transparent"]?.toBoolean() ?: true //是否透明,默认为true
-    val canceledOnTouchOutside =
-        params["canceled_on_touch_outside"]?.toBoolean() ?: true //是否点击外部取消,默认为true
-    if (activity != null && aspectRatio != null && aspectRatio > 0) {
+    val transparent = params[TRANSPARENT]?.toBoolean() ?: true //是否透明,默认为true
+    val canceledOnTouchOutside = params[CANCEL_TOUCH_OUTSIDE]?.toBoolean() ?: true //是否点击外部取消,默认为true
+    val isDialog = params[IS_DIALOG]?.toBoolean() ?: false
+    if (activity != null && isDialog) {
         //有比例半屏加载
         //有比例半屏加载
-        val height = (aspectRatio * DisplayUtil.getScreenWidth()).toInt()
-        val dialogTag = params["dialog_tag"] ?: ""
-        // TODO: 实现web能力
-//        WebViewDialogFragmentBuilder()
-//            .height(height)
-//            .transparent(transparent)
-//            .canceledOnTouchOutside(canceledOnTouchOutside)
-//            .dialogTag(dialogTag)
-//            .build()
-//            ?.showUrl(activity.supportFragmentManager, link)
+        val height = if (aspectRatio != null && aspectRatio > 0f) {
+            (aspectRatio * DisplayUtil.getScreenWidth()).toInt()
+        } else {
+            DisplayUtil.getScreenHeight() / 2
+        }
+        val dialogTag = params[DIALOG_TAG] ?: ""
+        WebViewDialogFragmentBuilder()
+            .height(height)
+            .transparent(transparent)
+            .canceledOnTouchOutside(canceledOnTouchOutside)
+            .dialogTag(dialogTag)
+            .build()
+            .showUrl(activity.supportFragmentManager, link)
     } else {
     } else {
         //加载一个 web 页
         //加载一个 web 页
         Router.build(context, Web.FullScreen.PATH)
         Router.build(context, Web.FullScreen.PATH)
             .putExtra(Web.Common.EXTRA_URL, link)
             .putExtra(Web.Common.EXTRA_URL, link)
+            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
             .start()
             .start()
     }
     }
 
 
 }
 }
 
 
 
 
-/**
- * 定义打开弹窗的deepLink
- */
-const val INTENT_DIALOG = "open_dialog"
-
-
 fun <T> Intent.parcelableExtra(name: String, clazz: Class<T>): T? {
 fun <T> Intent.parcelableExtra(name: String, clazz: Class<T>): T? {
     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
         getParcelableExtra<T>(name, clazz)
         getParcelableExtra<T>(name, clazz)

+ 61 - 0
app/src/main/java/com/adealink/weparty/webview/WebViewDialogFragmentBuilder.kt

@@ -0,0 +1,61 @@
+package com.adealink.weparty.webview
+
+import android.os.Bundle
+import com.adealink.weparty.module.webview.Web
+import com.adealink.weparty.module.webview.Web.HalfScreen.Companion.EXTRA_DIALOG_TAG
+import com.adealink.weparty.module.webview.Web.HalfScreen.Companion.EXTRA_HEIGHT
+import com.adealink.weparty.module.webview.Web.HalfScreen.Companion.EXTRA_TRANSPARENT
+
+class WebViewDialogFragmentBuilder {
+
+    private var heightPx = 0
+    private var transparent: Boolean = false
+    private var loadingUrl: String? = null
+    private var canceledOnTouchOutside: Boolean = true
+    private var dialogTag: String? = null
+    private var dismissCallback: (() -> Unit)? = null
+
+    fun dialogTag(dialogTag: String?): WebViewDialogFragmentBuilder {
+        this.dialogTag = dialogTag
+        return this
+    }
+
+    fun height(heightPx: Int): WebViewDialogFragmentBuilder {
+        this.heightPx = heightPx
+        return this
+    }
+
+    fun transparent(trans: Boolean): WebViewDialogFragmentBuilder {
+        this.transparent = trans
+        return this
+    }
+
+    fun loadingUrl(url: String?): WebViewDialogFragmentBuilder {
+        this.loadingUrl = url
+        return this
+    }
+
+    fun canceledOnTouchOutside(canceledOnTouchOutside: Boolean): WebViewDialogFragmentBuilder {
+        this.canceledOnTouchOutside = canceledOnTouchOutside
+        return this
+    }
+
+    fun dismissCallback(dismissCallback: () -> Unit): WebViewDialogFragmentBuilder {
+        this.dismissCallback = dismissCallback
+        return this
+    }
+
+    fun build(): WebViewDialogFragment {
+        val fragment = WebViewDialogFragment()
+        fragment.arguments = Bundle().apply {
+            putInt(EXTRA_HEIGHT, heightPx)
+            putBoolean(EXTRA_TRANSPARENT, transparent)
+            putString(Web.Common.EXTRA_LOADING_URL, loadingUrl)
+            putString(EXTRA_DIALOG_TAG, dialogTag)
+        }
+        fragment.canceledOnTouchOutside = canceledOnTouchOutside
+        fragment.setDismissCallback { dismissCallback?.invoke() }
+        return fragment
+    }
+
+}

+ 1 - 1
app/src/main/res/layout/dialog_app_update.xml

@@ -13,7 +13,7 @@
         android:background="@drawable/commonui_dialog_bg"
         android:background="@drawable/commonui_dialog_bg"
         android:paddingBottom="30dp"
         android:paddingBottom="30dp"
         app:constraint_layout_round_corner="12dp"
         app:constraint_layout_round_corner="12dp"
-        app:layout_constraintTop_toBottomOf="@id/header_iv">
+        app:layout_constraintTop_toTopOf="parent">
 
 
         <androidx.appcompat.widget.AppCompatImageView
         <androidx.appcompat.widget.AppCompatImageView
             android:layout_width="0dp"
             android:layout_width="0dp"

+ 88 - 130
app/src/main/res/layout/layout_common_dialog.xml

@@ -2,151 +2,109 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/root_view"
     android:layout_width="match_parent"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_height="match_parent"
-    android:layout_gravity="center"
-    tools:background="@color/black"
-    tools:ignore="HardcodedText">
+    tools:background="@color/black">
 
 
-    <com.adealink.frame.image.view.NetworkImageView
-        android:id="@+id/header_iv"
-        style="@style/CommonNetworkImage"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:visibility="gone"
-        app:actualImageScaleType="fitXY"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:visibility="visible" />
-
-    <androidx.constraintlayout.widget.ConstraintLayout
+    <com.adealink.weparty.commonui.widget.constrainlayout.RoundCornerConstraintLayout
         android:id="@+id/content_layout"
         android:id="@+id/content_layout"
         android:layout_width="match_parent"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_height="wrap_content"
         android:background="@drawable/commonui_dialog_bg"
         android:background="@drawable/commonui_dialog_bg"
-        app:layout_constraintTop_toBottomOf="@id/header_iv">
+        android:paddingBottom="30dp"
+        app:constraint_layout_round_corner="12dp"
+        app:layout_constraintTop_toTopOf="parent">
 
 
         <androidx.appcompat.widget.AppCompatImageView
         <androidx.appcompat.widget.AppCompatImageView
-            android:id="@+id/iv_top_bg"
-            android:layout_width="match_parent"
-            android:layout_height="140dp"
-            android:scaleType="fitXY"
-            android:visibility="visible"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintDimensionRatio="375:173"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/common_app_top_bg_ic" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/top_close_btn"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginEnd="10dp"
+            android:src="@drawable/common_close_ic"
+            app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
             app:layout_constraintTop_toTopOf="parent" />
 
 
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:layout_width="match_parent"
+        <!--标题-->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_title"
+            android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
-            android:paddingStart="24dp"
-            android:paddingTop="24dp"
-            android:paddingEnd="24dp"
-            android:paddingBottom="24dp"
-            app:layout_constraintTop_toTopOf="parent">
-
-            <com.adealink.frame.image.view.NetworkImageView
-                android:id="@+id/ivTop"
-                style="@style/CommonNetworkImage"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:scaleType="fitXY"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
+            android:layout_marginHorizontal="24dp"
+            android:layout_marginTop="30dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:lineSpacingExtra="3dp"
+            android:textColor="@color/color_FF1D2129"
+            android:textSize="16sp"
+            app:fontFamily="@font/poppins_semibold"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="这是标题" />
 
 
-            <!--标题-->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/tvTitle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="12dp"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:lineSpacingExtra="3dp"
-                android:textColor="@color/color_222222"
-                android:textSize="18sp"
-                android:textStyle="bold"
-                app:layout_constraintTop_toBottomOf="@id/ivTop"
-                app:layout_goneMarginTop="0dp"
-                tools:text="这是标题" />
-
-            <!--内容-->
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/tvMessage"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="12dp"
-                android:gravity="center"
-                android:includeFontPadding="false"
-                android:lineSpacingExtra="5dp"
-                android:textColor="@color/color_222222"
-                android:textSize="16sp"
-                android:visibility="gone"
-                app:layout_constraintTop_toBottomOf="@id/tvTitle"
-                app:layout_goneMarginTop="24dp"
-                tools:text="内容"
-                tools:visibility="visible" />
-
-            <FrameLayout
-                android:id="@+id/flSubBlock"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="24dp"
-                android:visibility="gone"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/tvMessage"
-                tools:visibility="visible">
-
-            </FrameLayout>
-
-            <!--确定-->
-            <com.adealink.weparty.commonui.widget.CommonButton
-                android:id="@+id/tvConfirm"
-                android:layout_width="0dp"
-                android:layout_height="36dp"
-                android:layout_marginHorizontal="50dp"
-                android:layout_marginTop="24dp"
-                app:button_radius="22dp"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/flSubBlock"
-                app:layout_constraintWidth_default="spread"
-                app:layout_goneMarginTop="20dp"
-                app:text="@string/commonui_confirm"
-                app:textColor="@color/white"
-                app:textSize="14sp" />
-
-            <!--取消-->
-            <com.adealink.weparty.commonui.widget.CommonButton
-                android:id="@+id/tvCancel"
-                android:layout_width="0dp"
-                android:layout_height="36dp"
-                android:layout_marginHorizontal="50dp"
-                android:layout_marginTop="16dp"
-                android:visibility="gone"
-                app:button_radius="22dp"
-                app:common_button_type="cancel"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/tvConfirm"
-                app:layout_goneMarginTop="20dp"
-                app:text="@string/commonui_cancel"
-                app:textColor="@color/color_FF4E5969"
-                app:textSize="14sp"
-                tools:visibility="visible" />
+        <!--内容-->
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_message"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="24dp"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:lineSpacingExtra="2dp"
+            android:textColor="@color/color_FF4E5969"
+            android:textSize="14sp"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_title"
+            app:layout_goneMarginTop="30dp"
+            tools:text="内容"
+            tools:visibility="visible" />
 
 
-        </androidx.constraintlayout.widget.ConstraintLayout>
+        <!--确定-->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_confirm"
+            android:layout_width="0dp"
+            android:layout_height="36dp"
+            android:layout_marginHorizontal="50dp"
+            android:layout_marginTop="16dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_message"
+            app:text="@string/commonui_confirm"
+            app:textColor="@color/white"
+            app:textSize="14sp" />
 
 
-    </androidx.constraintlayout.widget.ConstraintLayout>
+        <!--取消-->
+        <com.adealink.weparty.commonui.widget.CommonButton
+            android:id="@+id/btn_cancel"
+            android:layout_width="0dp"
+            android:layout_height="36dp"
+            android:layout_marginHorizontal="50dp"
+            android:layout_marginTop="16dp"
+            android:visibility="gone"
+            app:button_radius="22dp"
+            app:common_button_type="cancel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/btn_confirm"
+            app:layout_goneMarginTop="20dp"
+            app:text="@string/commonui_cancel"
+            app:textColor="@color/color_FF4E5969"
+            app:textSize="14sp"
+            tools:visibility="visible" />
 
 
-    <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/top_close_btn"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:layout_marginTop="10dp"
-        android:layout_marginEnd="10dp"
-        android:src="@drawable/common_close_ic"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+    </com.adealink.weparty.commonui.widget.constrainlayout.RoundCornerConstraintLayout>
 
 
 </androidx.constraintlayout.widget.ConstraintLayout>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 16 - 0
app/src/main/res/layout/layout_item_image_banner.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.adealink.frame.image.view.NetworkImageView
+        android:id="@+id/icon"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
app/src/main/res/values/colors.xml

@@ -1165,6 +1165,7 @@
     <color name="color_FF1B1919">#FF1B1919</color>
     <color name="color_FF1B1919">#FF1B1919</color>
     <color name="color_FF4E5969">#FF4E5969</color>
     <color name="color_FF4E5969">#FF4E5969</color>
     <color name="color_FF1D2129">#FF1D2129</color>
     <color name="color_FF1D2129">#FF1D2129</color>
+    <color name="color_4D1D2129">#4D1D2129</color>
     <color name="color_661D2129">#661D2129</color>
     <color name="color_661D2129">#661D2129</color>
     <color name="color_E61D2129">#E61D2129</color>
     <color name="color_E61D2129">#E61D2129</color>
     <color name="color_CC1D2129">#CC1D2129</color>
     <color name="color_CC1D2129">#CC1D2129</color>

+ 29 - 0
module/activity/src/main/java/com/adealink/weparty/activity/ActivityServiceImpl.kt

@@ -1,9 +1,18 @@
 package com.adealink.weparty.activity
 package com.adealink.weparty.activity
 
 
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.ViewModelStoreOwner
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.spi.RegisterService
 import com.adealink.frame.spi.RegisterService
 import com.adealink.weparty.App
 import com.adealink.weparty.App
+import com.adealink.weparty.activity.data.BannerReq
 import com.adealink.weparty.activity.datasource.remote.ActivityHttpService
 import com.adealink.weparty.activity.datasource.remote.ActivityHttpService
+import com.adealink.weparty.activity.viewmodel.ActivityViewModel
+import com.adealink.weparty.activity.viewmodel.ActivityViewModelFactory
 import com.adealink.weparty.module.activity.IActivityService
 import com.adealink.weparty.module.activity.IActivityService
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
 
 
 @RegisterService(IActivityService::class)
 @RegisterService(IActivityService::class)
 class ActivityServiceImpl : IActivityService {
 class ActivityServiceImpl : IActivityService {
@@ -21,4 +30,24 @@ class ActivityServiceImpl : IActivityService {
 
 
     }
     }
 
 
+    override suspend fun pullBanners(banner: Banner): Rlt<List<BannerData>> {
+        when (val rlt = activityHttpService.pullBanners(BannerReq(banner.type))) {
+            is Rlt.Failed -> {
+                return rlt
+            }
+
+            is Rlt.Success -> {
+                val banners = rlt.data.data?.banners
+                if (banners.isNullOrEmpty()) {
+                    return Rlt.Success(emptyList())
+                }
+                return Rlt.Success(banners.filter { it.isAvailable() })
+            }
+        }
+    }
+
+    override fun getActivityViewModel(owner: ViewModelStoreOwner): IActivityViewModel {
+        return ViewModelProvider(owner, ActivityViewModelFactory())[ActivityViewModel::class.java]
+    }
+
 }
 }

+ 13 - 0
module/activity/src/main/java/com/adealink/weparty/activity/data/ActivityData.kt

@@ -0,0 +1,13 @@
+package com.adealink.weparty.activity.data
+
+import com.adealink.weparty.module.activity.data.BannerData
+import com.google.gson.annotations.SerializedName
+
+data class BannerReq(
+    @SerializedName("adSlot") val adSlot: Int
+)
+
+data class BannerRes(
+    @SerializedName("list") val banners: List<BannerData>
+)
+

+ 9 - 0
module/activity/src/main/java/com/adealink/weparty/activity/datasource/remote/ActivityHttpService.kt

@@ -1,5 +1,14 @@
 package com.adealink.weparty.activity.datasource.remote
 package com.adealink.weparty.activity.datasource.remote
 
 
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.network.data.Res
+import com.adealink.weparty.activity.data.BannerReq
+import com.adealink.weparty.activity.data.BannerRes
+import retrofit2.http.Body
+import retrofit2.http.POST
+
 interface ActivityHttpService {
 interface ActivityHttpService {
 
 
+    @POST("base/banner/list")
+    suspend fun pullBanners(@Body req: BannerReq): Rlt<Res<BannerRes>>
 }
 }

+ 41 - 1
module/activity/src/main/java/com/adealink/weparty/activity/viewmodel/ActivityViewModel.kt

@@ -1,9 +1,49 @@
 package com.adealink.weparty.activity.viewmodel
 package com.adealink.weparty.activity.viewmodel
 
 
+import androidx.lifecycle.LiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtLiveData
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
+import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.weparty.App
+import com.adealink.weparty.activity.data.BannerReq
+import com.adealink.weparty.activity.datasource.remote.ActivityHttpService
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
 import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
 import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
-import com.adealink.weparty.module.playmate.viewmodel.IPlaymateViewModel
+import kotlinx.coroutines.launch
 
 
 class ActivityViewModel : BaseViewModel(), IActivityViewModel {
 class ActivityViewModel : BaseViewModel(), IActivityViewModel {
 
 
+    private val activityHttpService by lazy {
+        App.instance.networkService.getHttpService(ActivityHttpService::class.java)
+    }
+    override val bannersLD: ExtLiveData<List<BannerData>> = ExtMutableLiveData()
+
+    override fun pullBanners(banner: Banner): LiveData<Rlt<List<BannerData>>> {
+        val liveData = OnceMutableLiveData<Rlt<List<BannerData>>>()
+        viewModelScope.launch {
+            when (val rlt = activityHttpService.pullBanners(BannerReq(banner.type))) {
+                is Rlt.Failed -> {
+                    bannersLD.send(emptyList())
+                    liveData.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    val banners = rlt.data.data?.banners
+                    if (banners.isNullOrEmpty()) {
+                        bannersLD.send(emptyList())
+                        liveData.send(Rlt.Success(emptyList()))
+                        return@launch
+                    }
+                    val finalList = banners.filter { it.isAvailable() }
+                    bannersLD.send(finalList)
+                    liveData.send(Rlt.Success(finalList))
+                }
+            }
+        }
+        return liveData
+    }
+
 }
 }

+ 25 - 1
module/playmate/src/main/java/com/adealink/weparty/playmate/data/PlaymateListData.kt

@@ -2,6 +2,7 @@ package com.adealink.weparty.playmate.data
 
 
 import com.adealink.frame.network.data.PageReq
 import com.adealink.frame.network.data.PageReq
 import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
 import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
+import com.adealink.weparty.module.activity.data.BannerData
 import com.google.gson.annotations.GsonNullable
 import com.google.gson.annotations.GsonNullable
 import com.google.gson.annotations.SerializedName
 import com.google.gson.annotations.SerializedName
 
 
@@ -116,4 +117,27 @@ data class PlaymateListData(
 
 
 data class PlaymateListItemData(
 data class PlaymateListItemData(
     val data: PlaymateListData
     val data: PlaymateListData
-) : BaseListItemData
+) : BaseListItemData {
+    override fun areContentsTheSame(newItem: Any): Boolean {
+        val other = newItem as? PlaymateListItemData ?: return false
+        return data == other.data
+    }
+}
+
+data class PlaymateBannerItemData(
+    val banners: List<BannerData>
+) : BaseListItemData {
+    override fun areContentsTheSame(newItem: Any): Boolean {
+        val other = newItem as? PlaymateBannerItemData ?: return false
+        if (banners.size != other.banners.size) {
+            return false
+        }
+        banners.forEachIndexed { index, banner ->
+            val otherBanner = other.banners[index]
+            if (banner != otherBanner) {
+                return false
+            }
+        }
+        return true
+    }
+}

+ 5 - 5
module/playmate/src/main/java/com/adealink/weparty/playmate/list/PlaymateListFragment.kt

@@ -19,7 +19,7 @@ import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
 import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
-import com.adealink.weparty.commonui.recycleview.diffutil.BaseListDiffUtil
+import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
 import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
 import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
 import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.module.playmate.Playmate
 import com.adealink.weparty.module.playmate.Playmate
@@ -38,6 +38,7 @@ import com.adealink.weparty.playmate.data.StarOption
 import com.adealink.weparty.playmate.databinding.FragmentPlaymateListBinding
 import com.adealink.weparty.playmate.databinding.FragmentPlaymateListBinding
 import com.adealink.weparty.playmate.findpartner.FindPartnerFragment
 import com.adealink.weparty.playmate.findpartner.FindPartnerFragment
 import com.adealink.weparty.playmate.findpartner.data.OptionData
 import com.adealink.weparty.playmate.findpartner.data.OptionData
+import com.adealink.weparty.playmate.list.adapter.PlaymateBannerItemViewBinder
 import com.adealink.weparty.playmate.list.adapter.PlaymateListItemViewBinder
 import com.adealink.weparty.playmate.list.adapter.PlaymateListItemViewBinder
 import com.adealink.weparty.playmate.list.comp.PlaymateListFilterComp
 import com.adealink.weparty.playmate.list.comp.PlaymateListFilterComp
 import com.adealink.weparty.playmate.list.viewmodel.PlaymateListViewModel
 import com.adealink.weparty.playmate.list.viewmodel.PlaymateListViewModel
@@ -77,7 +78,7 @@ class PlaymateListFragment : BaseFragment(R.layout.fragment_playmate_list),
 
 
 
 
     private val binding by viewBinding(FragmentPlaymateListBinding::bind)
     private val binding by viewBinding(FragmentPlaymateListBinding::bind)
-    private val listAdapter by fastLazy { MultiTypeListAdapter<PlaymateListItemData>() }
+    private val listAdapter by fastLazy { MultiTypeListAdapter<BaseListItemData>() }
     private val playmateListViewModel by viewModels<PlaymateListViewModel> { PlaymateViewModelFactory() }
     private val playmateListViewModel by viewModels<PlaymateListViewModel> { PlaymateViewModelFactory() }
 
 
     private var exposureReport = object : PlaymateListEventReporter() {
     private var exposureReport = object : PlaymateListEventReporter() {
@@ -164,6 +165,7 @@ class PlaymateListFragment : BaseFragment(R.layout.fragment_playmate_list),
         })
         })
 
 
         listAdapter.register(PlaymateListItemViewBinder(this, this))
         listAdapter.register(PlaymateListItemViewBinder(this, this))
+        listAdapter.register(PlaymateBannerItemViewBinder(this))
         binding.vList.adapter = listAdapter
         binding.vList.adapter = listAdapter
         binding.vList.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
         binding.vList.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
         binding.vList.addItemDecoration(
         binding.vList.addItemDecoration(
@@ -257,9 +259,7 @@ class PlaymateListFragment : BaseFragment(R.layout.fragment_playmate_list),
                 binding.vList.show()
                 binding.vList.show()
                 binding.vErrorView.gone()
                 binding.vErrorView.gone()
             }
             }
-            listAdapter.submitList(list.map { data ->
-                PlaymateListItemData(data)
-            })
+            listAdapter.submitList(list)
         }
         }
     }
     }
 
 

+ 74 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/list/adapter/PlaymateBannerItemViewBinder.kt

@@ -0,0 +1,74 @@
+package com.adealink.weparty.playmate.list.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.lifecycle.LifecycleOwner
+import com.adealink.frame.aab.util.getCompatColor
+import com.adealink.frame.base.fastLazy
+import com.adealink.weparty.R
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.ext.dpf
+import com.adealink.weparty.commonui.ext.getActivity
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.commonui.widget.banner.indicator.CircleIndicator
+import com.adealink.weparty.module.activity.banner.adapter.ImageBannerAdapter
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.playmate.data.PlaymateBannerItemData
+import com.adealink.weparty.playmate.databinding.ItemPlaymateHomeBannerBinding
+import com.adealink.weparty.util.goLocalLinkPage
+
+class PlaymateBannerItemViewBinder(
+    val lifecycleOwner: LifecycleOwner,
+) : ItemViewBinder<PlaymateBannerItemData, PlaymateBannerItemViewBinder.ViewHolder>() {
+
+    override fun onCreateViewHolder(
+        inflater: LayoutInflater,
+        parent: ViewGroup,
+    ): ViewHolder {
+        return ViewHolder(ItemPlaymateHomeBannerBinding.inflate(inflater, parent, false)).also {
+            it.initView()
+        }
+    }
+
+    override fun onBindViewHolder(
+        holder: ViewHolder,
+        item: PlaymateBannerItemData
+    ) {
+        holder.update(item)
+    }
+
+    inner class ViewHolder(
+        rootBinding: ItemPlaymateHomeBannerBinding,
+    ) : BindingViewHolder<ItemPlaymateHomeBannerBinding>(rootBinding) {
+        private var item: PlaymateBannerItemData? = null
+
+        private val bannerAdapter by fastLazy { ImageBannerAdapter(listOf()) }
+
+        fun initView() {
+            binding.banner.apply {
+                setLoopTime(3 * 1000)
+                addBannerLifecycleObserver(lifecycleOwner)
+                setBannerRound(12.dpf())
+                indicator = CircleIndicator(context)
+                setAdapter(bannerAdapter)
+                indicator.indicatorConfig.normalWidth = 3.dp()
+                indicator.indicatorConfig.normalColor = getCompatColor(R.color.color_4D1D2129)
+                indicator.indicatorConfig.selectedWidth = 3.dp()
+                indicator.indicatorConfig.selectedColor = getCompatColor(R.color.white)
+                indicator.indicatorConfig.indicatorSpace = 3.dp()
+                setOnBannerListener { data, _ ->
+                    val bannerInfo = data as? BannerData ?: return@setOnBannerListener
+                    getActivity()?.let { activity ->
+                        goLocalLinkPage(activity, bannerInfo.getJumpUrl())
+                    }
+                }
+            }
+        }
+
+        fun update(item: PlaymateBannerItemData) {
+            this.item = item
+            bannerAdapter.setDatas(item.banners)
+        }
+    }
+}

+ 39 - 3
module/playmate/src/main/java/com/adealink/weparty/playmate/list/viewmodel/PlaymateListViewModel.kt

@@ -6,9 +6,14 @@ import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.frame.network.data.PageReq
 import com.adealink.frame.network.data.PageReq
 import com.adealink.weparty.App
 import com.adealink.weparty.App
-import com.adealink.weparty.module.order.OrderModule
+import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
+import com.adealink.weparty.module.activity.ActivityModule
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
 import com.adealink.weparty.network.data.NoMoreDataError
 import com.adealink.weparty.network.data.NoMoreDataError
+import com.adealink.weparty.playmate.data.PlaymateBannerItemData
 import com.adealink.weparty.playmate.data.PlaymateListData
 import com.adealink.weparty.playmate.data.PlaymateListData
+import com.adealink.weparty.playmate.data.PlaymateListItemData
 import com.adealink.weparty.playmate.data.PlaymateListOtherOptions
 import com.adealink.weparty.playmate.data.PlaymateListOtherOptions
 import com.adealink.weparty.playmate.data.PlaymateListReq
 import com.adealink.weparty.playmate.data.PlaymateListReq
 import com.adealink.weparty.playmate.data.PriceSort
 import com.adealink.weparty.playmate.data.PriceSort
@@ -24,8 +29,9 @@ class PlaymateListViewModel : BaseViewModel() {
         App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
         App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
     }
     }
 
 
+    private var bannerList: List<BannerData>? = null
     private val playmateList = mutableListOf<PlaymateListData>()
     private val playmateList = mutableListOf<PlaymateListData>()
-    val listLD = MutableLiveData<List<PlaymateListData>>()
+    val listLD = MutableLiveData<List<BaseListItemData>>()
     val listRltLD = ExtMutableLiveData<Rlt<Any>>()
     val listRltLD = ExtMutableLiveData<Rlt<Any>>()
 
 
     private var firstCategoryCode: String? = null
     private var firstCategoryCode: String? = null
@@ -103,6 +109,22 @@ class PlaymateListViewModel : BaseViewModel() {
             pageHandler.reset()
             pageHandler.reset()
             playmateList.clear()
             playmateList.clear()
             pullList()
             pullList()
+            pullBanner()
+        }
+    }
+
+    private fun pullBanner() {
+        viewModelScope.launch {
+            when (val rlt = ActivityModule.pullBanners(Banner.HOME)) {
+                is Rlt.Failed -> {
+                    this@PlaymateListViewModel.bannerList = null
+                }
+
+                is Rlt.Success -> {
+                    this@PlaymateListViewModel.bannerList = rlt.data
+                }
+            }
+            notifyListChanged()
         }
         }
     }
     }
 
 
@@ -153,8 +175,22 @@ class PlaymateListViewModel : BaseViewModel() {
                 pageHandler.nextPage(rlt.data.data?.next)
                 pageHandler.nextPage(rlt.data.data?.next)
                 playmateList.addAll(rlt.data.data?.list ?: emptyList())
                 playmateList.addAll(rlt.data.data?.list ?: emptyList())
                 listRltLD.send(rlt)
                 listRltLD.send(rlt)
-                listLD.send(playmateList)
+                notifyListChanged()
+            }
+        }
+    }
+
+    private fun notifyListChanged() {
+        viewModelScope.launch {
+            val itemList = mutableListOf<BaseListItemData>()
+            itemList.addAll(playmateList.map { PlaymateListItemData(it) })
+
+            //banner
+            val bannerList = this@PlaymateListViewModel.bannerList
+            if (!bannerList.isNullOrEmpty()) {
+                itemList.add(1, PlaymateBannerItemData(bannerList))
             }
             }
+            listLD.send(itemList)
         }
         }
     }
     }
 
 

+ 16 - 0
module/playmate/src/main/res/layout/item_playmate_home_banner.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <com.adealink.weparty.commonui.widget.banner.Banner
+        android:id="@+id/banner"
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        app:banner_disallow_parent_intercept="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 77 - 0
module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityComp.kt

@@ -0,0 +1,77 @@
+package com.adealink.weparty.room.activity
+
+import android.content.Intent
+import androidx.core.graphics.toColorInt
+import androidx.lifecycle.LifecycleOwner
+import com.adealink.frame.base.fastLazy
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.ext.dpf
+import com.adealink.weparty.commonui.layout.DynamicLayers
+import com.adealink.weparty.commonui.layout.IDynamicView
+import com.adealink.weparty.module.activity.ActivityModule
+import com.adealink.weparty.module.activity.banner.adapter.ImageBannerAdapter
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.module.room.base.BaseRoomComp
+import com.adealink.weparty.room.R
+import com.adealink.weparty.util.goLocalLinkPage
+
+class RoomActivityComp(
+    lifecycleOwner: LifecycleOwner,
+    private val layers: DynamicLayers<*, *>
+) : BaseRoomComp(lifecycleOwner) {
+
+    private val roomActivityView: IDynamicView<RoomActivityView> by fastLazy {
+        object : IDynamicView<RoomActivityView>(layers, R.id.id_room_banner_view) {
+            override fun onViewAdded(view: RoomActivityView) {
+                val viewBinding = view.getViewBinding()
+                val indicator = viewBinding.indicator
+                viewBinding.banner.apply {
+                    setLoopTime(6 * 1000)
+                    addBannerLifecycleObserver(lifecycleOwner)
+                    setBannerRound(12.dpf())
+                    setIndicator(indicator, false)
+                    indicator.config.apply {
+                        setIndicatorSize(4.dp())
+                        setIndicatorSpace(6.dp())
+                        setNormalWidth(4.dp())
+                        setSelectedWidth(4.dp())
+                        setNormalColor("#66FFFFFF".toColorInt())
+                        setSelectedColor("#FFFFFF".toColorInt())
+                    }
+                    setAdapter(activityAdapter)
+                    setOnBannerListener { data, _ ->
+                        val bannerInfo = data as? BannerData ?: return@setOnBannerListener
+                        goLocalLinkPage(activity, bannerInfo.getJumpUrl())
+                    }
+                }
+            }
+        }
+    }
+
+    private val roomActivityViewModel by fastLazy { ActivityModule.getActivityViewModel(requireActivity()) }
+    private val activityAdapter by fastLazy { ImageBannerAdapter(listOf()) }
+    override fun observeViewModel() {
+        roomActivityViewModel?.bannersLD?.observe(viewLifecycleOwner) {
+            updateRoomBanners(it)
+        }
+    }
+
+    private fun updateRoomBanners(banners: List<BannerData>) {
+        if (banners.isEmpty()) {
+            roomActivityView.gone()
+        } else {
+            roomActivityView.show()
+            activityAdapter.setDatas(banners)
+        }
+    }
+
+    override fun delayLoadData() {
+        roomActivityViewModel?.pullBanners(Banner.ROOM)
+    }
+
+    override fun onNewIntent(intent: Intent?) {
+        super.onNewIntent(intent)
+        loadData()
+    }
+}

+ 72 - 0
module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityDragView.kt

@@ -0,0 +1,72 @@
+package com.adealink.weparty.room.activity
+
+import android.content.Context
+import android.util.AttributeSet
+import android.util.Log
+import android.view.GestureDetector.SimpleOnGestureListener
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.animation.AccelerateDecelerateInterpolator
+import com.adealink.weparty.commonui.drag.BaseDragView
+import com.adealink.weparty.commonui.drag.DragTouchEventDelegate
+import com.adealink.weparty.commonui.drag.TAG_DRAG_VIEW
+import com.adealink.weparty.commonui.ext.pulse
+import com.adealink.weparty.commonui.gesture.GestureDetectDelegate
+import com.adealink.weparty.room.databinding.LayoutRoomActivityBinding
+
+class RoomActivityDragView @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+) : BaseDragView(context, attrs, defStyleAttr) {
+
+    private val binding = LayoutRoomActivityBinding.inflate(LayoutInflater.from(context), this,true)
+    private var isDragging = false
+
+    init {
+        val onGestureListener = object : SimpleOnGestureListener() {
+            override fun onLongPress(e: MotionEvent) {
+                Log.d(TAG_DRAG_VIEW, "onLongPress(RoomActivityDragView)")
+                isDragging = true
+                binding.banner.viewPager2?.isUserInputEnabled = false
+                binding.root.parent.requestDisallowInterceptTouchEvent(false)
+                this@RoomActivityDragView.pulse(interpolator = AccelerateDecelerateInterpolator())
+                onLongPressCallback(e)
+            }
+        }
+        binding.banner.setBannerDelegate(GestureDetectDelegate(binding.banner, onGestureListener))
+    }
+
+    fun getViewBinding(): LayoutRoomActivityBinding {
+        return binding
+    }
+
+    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
+        Log.d(TAG_DRAG_VIEW, "onInterceptTouchEvent(RoomActivityDragView), isDragging: $isDragging, ${ev?.let { MotionEvent.actionToString(it.action) }}")
+        if (isDragging) {
+            return true
+        }
+        return super.onInterceptTouchEvent(ev)
+    }
+
+    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
+        Log.d(TAG_DRAG_VIEW, "dispatchTouchEvent(RoomActivityDragView), $ev")
+        if (ev?.action == MotionEvent.ACTION_DOWN || ev?.action == MotionEvent.ACTION_UP) {
+            isDragging = false
+            binding.banner.viewPager2?.isUserInputEnabled = true
+            binding.root.parent.requestDisallowInterceptTouchEvent(true)
+        }
+        return super.dispatchTouchEvent(ev)
+    }
+
+    private fun onLongPressCallback(e: MotionEvent) {
+        (touchDelegate as? DragTouchEventDelegate)?.onLongPressCallback(e)
+    }
+
+    override fun isDraggable(): Boolean {
+        /*
+        关闭拖拽功能,后续再根据需求开放
+         */
+        return false
+    }
+}

+ 21 - 0
module/room/src/main/java/com/adealink/weparty/room/activity/RoomActivityView.kt

@@ -0,0 +1,21 @@
+package com.adealink.weparty.room.activity
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.adealink.weparty.room.databinding.LayoutRoomActivityBinding
+
+class RoomActivityView @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+    private val binding = LayoutRoomActivityBinding.inflate(LayoutInflater.from(context), this,true)
+
+    fun getViewBinding(): LayoutRoomActivityBinding {
+        return binding
+    }
+
+}

+ 17 - 12
module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterDynamicFactory.kt

@@ -4,9 +4,12 @@ import android.content.Context
 import android.view.View
 import android.view.View
 import androidx.annotation.IdRes
 import androidx.annotation.IdRes
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintLayout
+import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.layout.DynamicLayerLayoutParamsNotDefineError
 import com.adealink.weparty.commonui.layout.DynamicLayerLayoutParamsNotDefineError
 import com.adealink.weparty.commonui.layout.DynamicLayerViewNotDefineError
 import com.adealink.weparty.commonui.layout.DynamicLayerViewNotDefineError
 import com.adealink.weparty.commonui.layout.IDynamicViewFactory
 import com.adealink.weparty.commonui.layout.IDynamicViewFactory
+import com.adealink.weparty.room.R
+import com.adealink.weparty.room.activity.RoomActivityView
 
 
 /**
 /**
  * 语聊房-基础控件层级
  * 语聊房-基础控件层级
@@ -15,9 +18,9 @@ class DispatchCenterBaseLayerFactory : IDynamicViewFactory<ConstraintLayout.Layo
     @Suppress("UNCHECKED_CAST")
     @Suppress("UNCHECKED_CAST")
     override fun <V : View> createView(id: Int, context: Context): V {
     override fun <V : View> createView(id: Int, context: Context): V {
         return when (id) {
         return when (id) {
-//            R.id.id_chat_room_danmaku_view -> {
-//                DanmakuView(context) as V
-//            }
+            R.id.id_room_banner_view -> {
+                RoomActivityView(context) as V
+            }
 
 
             else -> {
             else -> {
                 throw DynamicLayerViewNotDefineError(context.resources.getResourceName(id))
                 throw DynamicLayerViewNotDefineError(context.resources.getResourceName(id))
@@ -27,15 +30,17 @@ class DispatchCenterBaseLayerFactory : IDynamicViewFactory<ConstraintLayout.Layo
 
 
     override fun getViewLayoutParam(@IdRes id: Int, context: Context): ConstraintLayout.LayoutParams {
     override fun getViewLayoutParam(@IdRes id: Int, context: Context): ConstraintLayout.LayoutParams {
         return when (id) {
         return when (id) {
-//            R.id.id_chat_room_danmaku_view -> {
-//                ConstraintLayout.LayoutParams(0, 250.dp()).apply {
-//                    topMargin = 90.dp()
-//
-//                    topToTop = R.id.mic_seat_fragment
-//                    startToStart = ConstraintLayout.LayoutParams.PARENT_ID
-//                    endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
-//                }
-//            }
+            R.id.id_room_banner_view -> {
+                ConstraintLayout.LayoutParams(
+                    65.dp(),
+                    92.dp()
+                ).apply {
+                    marginEnd = 10.dp()
+                    bottomMargin = 42.dp()
+                    bottomToTop = R.id.id_room_bottom_bar
+                    endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
+                }
+            }
 
 
             else -> {
             else -> {
                 throw DynamicLayerLayoutParamsNotDefineError(context.resources.getResourceName(id))
                 throw DynamicLayerLayoutParamsNotDefineError(context.resources.getResourceName(id))

+ 3 - 17
module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterDynamicLayer.kt

@@ -1,24 +1,10 @@
 package com.adealink.weparty.room.chatroom.page.dispatchcenter
 package com.adealink.weparty.room.chatroom.page.dispatchcenter
 
 
+import com.adealink.weparty.room.R
+
 /**
 /**
  * 语聊房-基础控件层级
  * 语聊房-基础控件层级
  */
  */
 val DISPATCH_CENTER_BASE_LAYER = intArrayOf(
 val DISPATCH_CENTER_BASE_LAYER = intArrayOf(
-//    R.id.id_chat_room_danmaku_view,
-//    R.id.id_chat_room_room_pk_view,
-//    R.id.id_chat_room_room_pk_anim_view,
-//    R.id.id_chat_room_gift_combo_view,
-//
-//    R.id.id_chat_room_gift_notice_view,
-//    R.id.id_chat_room_car_edge_flash_effect_view,
-//    R.id.id_chat_room_car_effect_view,
-//    R.id.id_chat_room_treasure_gift_view,
-//    R.id.id_chat_room_gift_flow_light_effect_view,
-//    R.id.id_chat_room_gift_static_effect_view,
-//    R.id.id_chat_room_gift_effect_view,
-//    R.id.id_chat_room_gift_banner_view,
-//    R.id.id_chat_room_reward_view,
-//    R.id.id_chat_room_gift_falling_down_view,
-//    R.id.id_chat_room_headline_view,
-//    R.id.id_chat_room_enter_effect_view,
+    R.id.id_room_banner_view
 )
 )

+ 2 - 0
module/room/src/main/java/com/adealink/weparty/room/chatroom/page/dispatchcenter/DispatchCenterRoomPageFragment.kt

@@ -20,6 +20,7 @@ import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.layout.DynamicLayers
 import com.adealink.weparty.commonui.layout.DynamicLayers
 import com.adealink.weparty.room.R
 import com.adealink.weparty.room.R
+import com.adealink.weparty.room.activity.RoomActivityComp
 import com.adealink.weparty.room.chat.ChatMessageFragment
 import com.adealink.weparty.room.chat.ChatMessageFragment
 import com.adealink.weparty.room.chatroom.page.BaseChatRoomPageFragment
 import com.adealink.weparty.room.chatroom.page.BaseChatRoomPageFragment
 import com.adealink.weparty.room.constant.logRoomTime
 import com.adealink.weparty.room.constant.logRoomTime
@@ -119,6 +120,7 @@ class DispatchCenterRoomPageFragment :
         super.initComponents()
         super.initComponents()
         Log.d(TAG_ROOM, "chat fragment initComponents")
         Log.d(TAG_ROOM, "chat fragment initComponents")
         compList.add(ThemeComp(this, binding.flTheme, APP_R.drawable.room_default_bg).attach())
         compList.add(ThemeComp(this, binding.flTheme, APP_R.drawable.room_default_bg).attach())
+        compList.add(RoomActivityComp(this, baseDynamicLayers).attach())
     }
     }
 
 
     override fun handleNewIntent(intent: Intent?) {
     override fun handleNewIntent(intent: Intent?) {

+ 34 - 0
module/room/src/main/res/layout/layout_room_activity.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_layout"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
+
+    <com.adealink.weparty.commonui.widget.banner.Banner
+        android:id="@+id/banner"
+        android:layout_width="65dp"
+        android:layout_height="80dp"
+        app:banner_indicator_normal_color="@color/color_66FFFFFF"
+        app:banner_indicator_normal_width="3dp"
+        app:banner_indicator_radius="3dp"
+        app:banner_indicator_selected_color="@color/white"
+        app:banner_indicator_selected_width="3dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.adealink.weparty.commonui.widget.banner.indicator.CircleIndicator
+        android:id="@+id/indicator"
+        android:layout_width="65dp"
+        android:layout_height="4dp"
+        android:layout_marginHorizontal="6dp"
+        android:layout_marginTop="8dp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="@id/banner"
+        app:layout_constraintStart_toStartOf="@id/banner"
+        app:layout_constraintTop_toBottomOf="@id/banner" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
module/room/src/main/res/values/ids.xml

@@ -35,6 +35,7 @@
     <item name="id_room_mic_seat" type="id" />
     <item name="id_room_mic_seat" type="id" />
     <item name="id_room_chat_message" type="id" />
     <item name="id_room_chat_message" type="id" />
     <item name="id_room_bottom_bar" type="id" />
     <item name="id_room_bottom_bar" type="id" />
+    <item name="id_room_banner_view" type="id" />
     
     
     <item name="id_mic_operate_invite" type="id" />
     <item name="id_mic_operate_invite" type="id" />
     <item name="id_mic_operate_member_info" type="id" />
     <item name="id_mic_operate_member_info" type="id" />

+ 1 - 3
module/share/src/main/java/com/adealink/weparty/share/viewmodel/ShareViewModel.kt

@@ -1,9 +1,7 @@
 package com.adealink.weparty.share.viewmodel
 package com.adealink.weparty.share.viewmodel
 
 
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
-import com.adealink.weparty.module.activity.viewmodel.IActivityViewModel
-import com.adealink.weparty.module.playmate.viewmodel.IPlaymateViewModel
 
 
-class ShareViewModel : BaseViewModel(), IActivityViewModel {
+class ShareViewModel : BaseViewModel() {
 
 
 }
 }

+ 47 - 15
module/wallet/src/main/java/com/adealink/weparty/wallet/comp/WalletActivityComp.kt

@@ -1,8 +1,20 @@
 package com.adealink.weparty.wallet.comp
 package com.adealink.weparty.wallet.comp
 
 
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.LifecycleOwner
-import com.adealink.frame.mvvm.view.ViewComponent
+import com.adealink.frame.aab.util.getCompatColor
+import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.viewmodel.activityViewModels
 import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.weparty.R
+import com.adealink.weparty.commonui.BaseViewComponent
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.ext.dpf
+import com.adealink.weparty.commonui.ext.getActivity
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.commonui.widget.banner.indicator.CircleIndicator
+import com.adealink.weparty.module.activity.banner.adapter.ImageBannerAdapter
+import com.adealink.weparty.module.activity.data.BannerData
+import com.adealink.weparty.util.goLocalLinkPage
 import com.adealink.weparty.wallet.databinding.LayoutWalletActivityBinding
 import com.adealink.weparty.wallet.databinding.LayoutWalletActivityBinding
 import com.adealink.weparty.wallet.viewmodel.WalletViewModel
 import com.adealink.weparty.wallet.viewmodel.WalletViewModel
 import com.adealink.weparty.wallet.viewmodel.WalletViewModelFactory
 import com.adealink.weparty.wallet.viewmodel.WalletViewModelFactory
@@ -10,26 +22,46 @@ import com.adealink.weparty.wallet.viewmodel.WalletViewModelFactory
 class WalletActivityComp(
 class WalletActivityComp(
     lifecycleOwner: LifecycleOwner,
     lifecycleOwner: LifecycleOwner,
     val binding: LayoutWalletActivityBinding
     val binding: LayoutWalletActivityBinding
-) : ViewComponent(lifecycleOwner) {
+) : BaseViewComponent(lifecycleOwner) {
 
 
     private val viewModel by activityViewModels<WalletViewModel> { WalletViewModelFactory() }
     private val viewModel by activityViewModels<WalletViewModel> { WalletViewModelFactory() }
-    override fun onCreate() {
-        super.onCreate()
-        initView()
-        observeViewModel()
-        loadData()
-    }
-
-    private fun initView() {
 
 
+    private val bannerAdapter by fastLazy { ImageBannerAdapter(listOf()) }
+    override fun initViews() {
+        binding.root.gone()
+        binding.banner.apply {
+            setLoopTime(3 * 1000)
+            addBannerLifecycleObserver(lifecycleOwner)
+            setBannerRound(12.dpf())
+            indicator = CircleIndicator(context)
+            setAdapter(bannerAdapter)
+            indicator.indicatorConfig.normalWidth = 3.dp()
+            indicator.indicatorConfig.normalColor = getCompatColor(R.color.color_4D1D2129)
+            indicator.indicatorConfig.selectedWidth = 3.dp()
+            indicator.indicatorConfig.selectedColor = getCompatColor(R.color.white)
+            indicator.indicatorConfig.indicatorSpace = 3.dp()
+            setOnBannerListener { data, _ ->
+                val bannerInfo = data as? BannerData ?: return@setOnBannerListener
+                getActivity()?.let { activity ->
+                    goLocalLinkPage(activity, bannerInfo.getJumpUrl())
+                }
+            }
+        }
     }
     }
 
 
-    private fun observeViewModel() {
-
+    override fun loadData() {
+        super.loadData()
+        viewModel.pullBanner().observe(viewLifecycleOwner) {
+            updateBanners(it)
+        }
     }
     }
 
 
-    private fun loadData() {
-
+    private fun updateBanners(banners: List<BannerData>) {
+        if (banners.isNullOrEmpty()) {
+            binding.root.gone()
+        } else {
+            binding.root.show()
+        }
+        bannerAdapter.setDatas(banners)
     }
     }
-
 }
 }

+ 19 - 0
module/wallet/src/main/java/com/adealink/weparty/wallet/viewmodel/WalletViewModel.kt

@@ -7,6 +7,9 @@ import com.adealink.frame.base.Rlt
 import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.weparty.App
 import com.adealink.weparty.App
+import com.adealink.weparty.module.activity.ActivityModule
+import com.adealink.weparty.module.activity.data.Banner
+import com.adealink.weparty.module.activity.data.BannerData
 import com.adealink.weparty.module.wallet.data.Currency
 import com.adealink.weparty.module.wallet.data.Currency
 import com.adealink.weparty.module.wallet.viewmodel.IWalletViewModel
 import com.adealink.weparty.module.wallet.viewmodel.IWalletViewModel
 import com.adealink.weparty.wallet.datasource.remote.WalletHttpService
 import com.adealink.weparty.wallet.datasource.remote.WalletHttpService
@@ -126,4 +129,20 @@ class WalletViewModel : BaseViewModel(), IWalletViewModel, IWalletListener {
         return liveData
         return liveData
     }
     }
 
 
+    fun pullBanner(): LiveData<List<BannerData>> {
+        val liveData = OnceMutableLiveData<List<BannerData>>()
+        viewModelScope.launch {
+            when (val rlt = ActivityModule.pullBanners(Banner.WALLET)) {
+                is Rlt.Failed -> {
+                    liveData.send(emptyList())
+                }
+
+                is Rlt.Success -> {
+                    liveData.send(rlt.data)
+                }
+            }
+        }
+        return liveData
+    }
+
 }
 }

+ 14 - 2
module/wallet/src/main/res/layout/layout_wallet_activity.xml

@@ -1,4 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
-<com.adealink.weparty.commonui.widget.banner.Banner xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_width="match_parent"
-    android:layout_height="70dp" />
+    android:layout_height="wrap_content">
+
+    <com.adealink.weparty.commonui.widget.banner.Banner
+        android:id="@+id/banner"
+        android:layout_width="match_parent"
+        android:layout_height="70dp"
+        app:banner_disallow_parent_intercept="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>