From a4c2fdb8592884a9f0331f65e83851766db3f38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=B0=8F=E6=B1=9F?= <461355754@qq.com> Date: Wed, 3 Dec 2025 10:33:15 +0800 Subject: [PATCH] =?UTF-8?q?1=EF=BC=9A=E4=BF=AE=E6=94=B9=E7=88=B5=E4=BD=8D?= =?UTF-8?q?=E8=BF=9B=E5=9C=BA=E5=BE=88=E6=85=A2=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xscm/moduleutil/widget/CustomViewPager.kt | 41 ++++ .../activity/room/activity/RoomActivity.kt | 179 ++++++++++++------ .../activity/SingerVerificationActivity.java | 5 + .../activity/ui/main/BosomFriendFragment.kt | 2 +- .../main/res/layout/fragment_bosom_friend.xml | 2 +- .../main/res/layout/fragment_user_hompage.xml | 2 +- .../main/res/layout/fragment_vocal_range.xml | 3 +- 7 files changed, 172 insertions(+), 62 deletions(-) create mode 100644 BaseModule/src/main/java/com/xscm/moduleutil/widget/CustomViewPager.kt diff --git a/BaseModule/src/main/java/com/xscm/moduleutil/widget/CustomViewPager.kt b/BaseModule/src/main/java/com/xscm/moduleutil/widget/CustomViewPager.kt new file mode 100644 index 00000000..5062b21a --- /dev/null +++ b/BaseModule/src/main/java/com/xscm/moduleutil/widget/CustomViewPager.kt @@ -0,0 +1,41 @@ +package com.xscm.moduleutil.widget +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.viewpager.widget.ViewPager +/** + * 项目名称:羽声语音 + * 时间:2025/12/3 9:30 + * 用途: + */ + + +class CustomViewPager(context: Context, attrs: AttributeSet?) : ViewPager(context, attrs) { + + private var initialX = 0f + private var initialY = 0f + + override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { + when (ev.action) { + MotionEvent.ACTION_DOWN -> { + // 记录初始触摸点 + initialX = ev.x + initialY = ev.y + parent.requestDisallowInterceptTouchEvent(true) // 请求父容器不要拦截事件 + } + MotionEvent.ACTION_MOVE -> { + val deltaX = Math.abs(ev.x - initialX) + val deltaY = Math.abs(ev.y - initialY) + + // 如果水平滑动距离大于垂直滑动距离,才认为是水平滑动,ViewPager才拦截事件 + if (deltaX > deltaY && deltaX > 30) { // 30是阈值,可以根据需要调整 + return super.onInterceptTouchEvent(ev) + } + // 否则,不拦截,让子视图处理 + parent.requestDisallowInterceptTouchEvent(true) + return false + } + } + return super.onInterceptTouchEvent(ev) + } +} diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt b/MainModule/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt index 5b1e0baf..55ffd277 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/room/activity/RoomActivity.kt @@ -1,6 +1,10 @@ package com.xscm.modulemain.activity.room.activity import android.Manifest +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.AnimatorSet +import android.animation.ValueAnimator import android.annotation.SuppressLint import android.app.ActivityManager import android.app.AlertDialog @@ -31,6 +35,7 @@ import android.view.View import android.view.View.GONE import android.view.ViewGroup import android.view.WindowManager +import android.view.animation.AccelerateInterpolator import android.view.animation.Animation import android.view.animation.DecelerateInterpolator import android.view.animation.TranslateAnimation @@ -347,6 +352,9 @@ class RoomActivity : BaseMvpActivity(), // 初始化礼物管理器 GiftDisplayManager.getInstance().setupDisplayView(mBinding?.giftContainer) + // 预加载飘屏视图,避免首次显示时的延迟 + preloadFloatingViews() + initPublicScreenFragment() } @@ -2004,7 +2012,12 @@ class RoomActivity : BaseMvpActivity(), private var currentMqttView: View? = null // 正在播放 var decorView: ViewGroup? = null //礼物的 - + // 添加视图池,用于复用飘屏视图 + private val floatingViewPool = mutableListOf() + // 使用Handler替代post,提供更精确的控制 + private val floatingHandler = Handler(Looper.getMainLooper()) + // 添加预加载标志 + private var isPreloaded = false private fun handleMsgType1001(roomMessageEvent: RoomMessageEvent) { if (roomMessageEvent.text.fromUserInfo.enter_image?.isNotEmpty() == true) { @@ -2017,42 +2030,78 @@ class RoomActivity : BaseMvpActivity(), // mBinding!!.roomTop.tvNum.text = number.toString() + "" } + // 添加预加载方法 + private fun preloadFloatingViews() { + if (isPreloaded) return + try { + // 预创建2-3个视图以备使用 + for (i in 0..2) { + val view = LayoutInflater.from(this).inflate(R.layout.item_noble_piaoping, null) + view.visibility = View.GONE + floatingViewPool.add(view) + } + isPreloaded = true + } catch (e: Exception) { + LogUtils.e("预加载飘屏视图失败", e) + } + } + private fun showFloatingMessage(userInfo: UserInfo) { try { + // 确保已预加载视图 + preloadFloatingViews() + // 清理之前的视图(如果存在) if (currentMqttView?.getParent() != null) { val parent = currentMqttView?.getParent() as ViewGroup parent.removeView(currentMqttView) + // 将旧视图放回池中 + currentMqttView?.visibility = View.GONE + floatingViewPool.add(currentMqttView!!) } if (decorView == null) { decorView = getWindow().getDecorView() as ViewGroup? } - currentMqttView = LayoutInflater.from(this).inflate(R.layout.item_noble_piaoping, null) - val layoutParams = FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT - ) - layoutParams.topMargin = DisplayUtil.dip2px(this, 300f) - layoutParams.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL - currentMqttView?.setLayoutParams(layoutParams) - decorView?.addView(currentMqttView) - currentMqttView?.let { updateFloatingViewData(it, userInfo) } + // 使用Handler而不是post,提供更精确的控制 + floatingHandler.post { + // 尝试从池中获取视图 + currentMqttView = if (floatingViewPool.isNotEmpty()) { + val view = floatingViewPool.removeAt(0) + view.visibility = View.VISIBLE + view + } else { + // 如果池为空,创建新视图 + LayoutInflater.from(this).inflate(R.layout.item_noble_piaoping, null) + } - currentMqttView?.let { - resetAndStartMqttAnimation(it, Runnable { - // 清理当前视图 - if (currentMqttView?.getParent() != null) { - val parent = currentMqttView?.getParent() as ViewGroup - parent.removeView(currentMqttView) - } - currentMqttView = null + val layoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.WRAP_CONTENT + ) + layoutParams.topMargin = DisplayUtil.dip2px(this, 300f) + layoutParams.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL + currentMqttView?.setLayoutParams(layoutParams) + decorView?.addView(currentMqttView) + currentMqttView?.let { updateFloatingViewData(it, userInfo) } - }) + currentMqttView?.let { + resetAndStartMqttAnimation(it, Runnable { + // 清理当前视图 + if (currentMqttView?.getParent() != null) { + val parent = currentMqttView?.getParent() as ViewGroup + parent.removeView(currentMqttView) + } + // 将视图放回池中 + currentMqttView?.visibility = View.GONE + floatingViewPool.add(currentMqttView!!) + currentMqttView = null + }) + } } } catch (e: java.lang.Exception) { - + LogUtils.e("飘屏显示异常", e) } } @@ -2061,57 +2110,71 @@ class RoomActivity : BaseMvpActivity(), val screenWidth = getScreenWidth() // 设置初始位置:在屏幕右侧外部(完全不可见) view.setTranslationX(screenWidth.toFloat()) + view.alpha = 0f // 初始设为透明,避免闪烁 + // 使用属性动画替代补间动画,提高性能 + val enterAnim = ValueAnimator.ofFloat(screenWidth.toFloat(), ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat()) + enterAnim.duration = 1000 // 减少进入动画时长到800ms + enterAnim.interpolator = DecelerateInterpolator() - val enterAnim = TranslateAnimation( - Animation.ABSOLUTE, screenWidth.toFloat(), - Animation.ABSOLUTE, ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(), - Animation.ABSOLUTE, 0f, - Animation.ABSOLUTE, 0f - ) - enterAnim.setDuration(1500) - enterAnim.setInterpolator(DecelerateInterpolator(2.0f)) - enterAnim.setAnimationListener(object : Animation.AnimationListener { - override fun onAnimationStart(animation: Animation?) { - } + // 添加透明度动画,使显示更平滑 + val alphaAnim = ValueAnimator.ofFloat(0f, 1f) + alphaAnim.duration =1000 // 透明度动画300ms - override fun onAnimationEnd(animation: Animation?) { - // 停留后退出 - CommonAppContext.postDelayed(Runnable { - val exitAnim = TranslateAnimation( - Animation.ABSOLUTE, + enterAnim.addUpdateListener { animation -> + view.translationX = animation.animatedValue as Float + } + + alphaAnim.addUpdateListener { animation -> + view.alpha = animation.animatedValue as Float + } + + // 使用AnimatorSet同时执行两个动画 + val animatorSet = AnimatorSet() + animatorSet.playTogether(enterAnim, alphaAnim) + + animatorSet.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + // 停留后退出,减少停留时间 + floatingHandler.postDelayed({ + // 使用属性动画实现退出动画 + val exitAnim = ValueAnimator.ofFloat( ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(), - Animation.ABSOLUTE, - -screenWidth.toFloat(), - Animation.ABSOLUTE, - 0f, - Animation.ABSOLUTE, - 0f + -screenWidth.toFloat() ) - exitAnim.setDuration(3000) - exitAnim.setInterpolator(DecelerateInterpolator(2f)) - exitAnim.setAnimationListener(object : Animation.AnimationListener { - override fun onAnimationStart(animation: Animation?) { - } + exitAnim.duration = 1000 // 减少退出动画时长到800ms + exitAnim.interpolator = AccelerateInterpolator() - override fun onAnimationEnd(animation: Animation?) { + // 添加透明度动画,使消失更平滑 + val fadeOutAnim = ValueAnimator.ofFloat(1f, 0f) + fadeOutAnim.duration = 1000 // 透明度动画300ms + + exitAnim.addUpdateListener { animation -> + view.translationX = animation.animatedValue as Float + } + + fadeOutAnim.addUpdateListener { animation -> + view.alpha = animation.animatedValue as Float + } + + val exitAnimatorSet = AnimatorSet() + exitAnimatorSet.playTogether(exitAnim, fadeOutAnim) + + exitAnimatorSet.addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { // 移除视图并处理下一个 onAnimationEnd.run() } - - override fun onAnimationRepeat(animation: Animation?) { - } }) - view.startAnimation(exitAnim) - }, 5000) // 停留1秒 - } - override fun onAnimationRepeat(animation: Animation?) { + exitAnimatorSet.start() + }, 3000) // 减少停留时间到2秒 } }) - view.startAnimation(enterAnim) + + animatorSet.start() } catch (e: java.lang.Exception) { - LogUtils.e("MQTT动画启动失败", e) + LogUtils.e("爵位进场动画失败", e) onAnimationEnd.run() } } diff --git a/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/SingerVerificationActivity.java b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/SingerVerificationActivity.java index 60969a0a..5ae7fa01 100644 --- a/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/SingerVerificationActivity.java +++ b/MainModule/src/main/java/com/xscm/modulemain/activity/user/activity/SingerVerificationActivity.java @@ -124,6 +124,9 @@ public class SingerVerificationActivity extends BaseMvpActivity()) mBinding.rvMyRelationship.adapter = adapter diff --git a/MainModule/src/main/res/layout/fragment_bosom_friend.xml b/MainModule/src/main/res/layout/fragment_bosom_friend.xml index 02b33dbe..9cf50680 100644 --- a/MainModule/src/main/res/layout/fragment_bosom_friend.xml +++ b/MainModule/src/main/res/layout/fragment_bosom_friend.xml @@ -34,7 +34,7 @@ - + tools:text="用户22333333" + app:isShine="false"/>