1:修改爵位进场很慢的情况

This commit is contained in:
2025-12-03 10:33:15 +08:00
parent 8d35790413
commit a4c2fdb859
7 changed files with 172 additions and 62 deletions

View File

@@ -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)
}
}

View File

@@ -1,6 +1,10 @@
package com.xscm.modulemain.activity.room.activity package com.xscm.modulemain.activity.room.activity
import android.Manifest 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.annotation.SuppressLint
import android.app.ActivityManager import android.app.ActivityManager
import android.app.AlertDialog import android.app.AlertDialog
@@ -31,6 +35,7 @@ import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.view.animation.AccelerateInterpolator
import android.view.animation.Animation import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.view.animation.TranslateAnimation import android.view.animation.TranslateAnimation
@@ -347,6 +352,9 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
// 初始化礼物管理器 // 初始化礼物管理器
GiftDisplayManager.getInstance().setupDisplayView(mBinding?.giftContainer) GiftDisplayManager.getInstance().setupDisplayView(mBinding?.giftContainer)
// 预加载飘屏视图,避免首次显示时的延迟
preloadFloatingViews()
initPublicScreenFragment() initPublicScreenFragment()
} }
@@ -2004,7 +2012,12 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
private var currentMqttView: View? = null // 正在播放 private var currentMqttView: View? = null // 正在播放
var decorView: ViewGroup? = null //礼物的 var decorView: ViewGroup? = null //礼物的
// 添加视图池,用于复用飘屏视图
private val floatingViewPool = mutableListOf<View>()
// 使用Handler替代post提供更精确的控制
private val floatingHandler = Handler(Looper.getMainLooper())
// 添加预加载标志
private var isPreloaded = false
private fun handleMsgType1001(roomMessageEvent: RoomMessageEvent) { private fun handleMsgType1001(roomMessageEvent: RoomMessageEvent) {
if (roomMessageEvent.text.fromUserInfo.enter_image?.isNotEmpty() == true) { if (roomMessageEvent.text.fromUserInfo.enter_image?.isNotEmpty() == true) {
@@ -2017,19 +2030,52 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
// mBinding!!.roomTop.tvNum.text = number.toString() + "" // 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) { private fun showFloatingMessage(userInfo: UserInfo) {
try { try {
// 确保已预加载视图
preloadFloatingViews()
// 清理之前的视图(如果存在) // 清理之前的视图(如果存在)
if (currentMqttView?.getParent() != null) { if (currentMqttView?.getParent() != null) {
val parent = currentMqttView?.getParent() as ViewGroup val parent = currentMqttView?.getParent() as ViewGroup
parent.removeView(currentMqttView) parent.removeView(currentMqttView)
// 将旧视图放回池中
currentMqttView?.visibility = View.GONE
floatingViewPool.add(currentMqttView!!)
} }
if (decorView == null) { if (decorView == null) {
decorView = getWindow().getDecorView() as ViewGroup? decorView = getWindow().getDecorView() as ViewGroup?
} }
currentMqttView = LayoutInflater.from(this).inflate(R.layout.item_noble_piaoping, null) // 使用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)
}
val layoutParams = FrameLayout.LayoutParams( val layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT FrameLayout.LayoutParams.WRAP_CONTENT
@@ -2047,12 +2093,15 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
val parent = currentMqttView?.getParent() as ViewGroup val parent = currentMqttView?.getParent() as ViewGroup
parent.removeView(currentMqttView) parent.removeView(currentMqttView)
} }
// 将视图放回池中
currentMqttView?.visibility = View.GONE
floatingViewPool.add(currentMqttView!!)
currentMqttView = null currentMqttView = null
}) })
} }
}
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
LogUtils.e("飘屏显示异常", e)
} }
} }
@@ -2061,57 +2110,71 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
val screenWidth = getScreenWidth() val screenWidth = getScreenWidth()
// 设置初始位置:在屏幕右侧外部(完全不可见) // 设置初始位置:在屏幕右侧外部(完全不可见)
view.setTranslationX(screenWidth.toFloat()) 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(), val alphaAnim = ValueAnimator.ofFloat(0f, 1f)
Animation.ABSOLUTE, ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(), alphaAnim.duration =1000 // 透明度动画300ms
Animation.ABSOLUTE, 0f,
Animation.ABSOLUTE, 0f enterAnim.addUpdateListener { animation ->
) view.translationX = animation.animatedValue as Float
enterAnim.setDuration(1500)
enterAnim.setInterpolator(DecelerateInterpolator(2.0f))
enterAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
} }
override fun onAnimationEnd(animation: Animation?) { alphaAnim.addUpdateListener { animation ->
// 停留后退出 view.alpha = animation.animatedValue as Float
CommonAppContext.postDelayed(Runnable { }
val exitAnim = TranslateAnimation(
Animation.ABSOLUTE, // 使用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(), ((screenWidth - SystemUtils.getWidth(316)) / 2).toFloat(),
Animation.ABSOLUTE, -screenWidth.toFloat()
-screenWidth.toFloat(),
Animation.ABSOLUTE,
0f,
Animation.ABSOLUTE,
0f
) )
exitAnim.setDuration(3000) exitAnim.duration = 1000 // 减少退出动画时长到800ms
exitAnim.setInterpolator(DecelerateInterpolator(2f)) exitAnim.interpolator = AccelerateInterpolator()
exitAnim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) { // 添加透明度动画,使消失更平滑
val fadeOutAnim = ValueAnimator.ofFloat(1f, 0f)
fadeOutAnim.duration = 1000 // 透明度动画300ms
exitAnim.addUpdateListener { animation ->
view.translationX = animation.animatedValue as Float
} }
override fun onAnimationEnd(animation: Animation?) { 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() onAnimationEnd.run()
} }
})
override fun onAnimationRepeat(animation: Animation?) { exitAnimatorSet.start()
}, 3000) // 减少停留时间到2秒
} }
}) })
view.startAnimation(exitAnim)
}, 5000) // 停留1秒
}
override fun onAnimationRepeat(animation: Animation?) { animatorSet.start()
}
})
view.startAnimation(enterAnim)
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
LogUtils.e("MQTT动画启动失败", e) LogUtils.e("爵位进场动画失败", e)
onAnimationEnd.run() onAnimationEnd.run()
} }
} }

View File

@@ -124,6 +124,9 @@ public class SingerVerificationActivity extends BaseMvpActivity<SingerVerificati
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
if (!isRecording && !isPlaying) { if (!isRecording && !isPlaying) {
// 长按时改变按钮图案为类似试听后的图案
mBinding.recordButton.setImageResource(R.mipmap.but_tz);
// 如果之前已经录制过内容,则继续录制 // 如果之前已经录制过内容,则继续录制
if (hasRecordedBefore && recordingFile != null && recordingFile.exists()) { if (hasRecordedBefore && recordingFile != null && recordingFile.exists()) {
isAppendRecording = true; isAppendRecording = true;
@@ -138,6 +141,8 @@ public class SingerVerificationActivity extends BaseMvpActivity<SingerVerificati
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
if (isRecording) { if (isRecording) {
stopRecording(); stopRecording();
// 手指离开后恢复默认图案
mBinding.recordButton.setImageResource(R.mipmap.but_ly);
} }
return true; return true;
default: default:

View File

@@ -116,7 +116,7 @@ class BosomFriendFragment : BaseMvpFragment<UserHomepagePresenter?, FragmentBoso
mBinding.rvMyRelationship.layoutManager = mBinding.rvMyRelationship.layoutManager =
androidx.recyclerview.widget.LinearLayoutManager(context) androidx.recyclerview.widget.LinearLayoutManager(context)
mBinding.rvMyRelationship.isNestedScrollingEnabled=false
// 初始化适配器 // 初始化适配器
val adapter = BosomFriendAdapter(mutableListOf<MultiItemEntity>()) val adapter = BosomFriendAdapter(mutableListOf<MultiItemEntity>())
mBinding.rvMyRelationship.adapter = adapter mBinding.rvMyRelationship.adapter = adapter

View File

@@ -34,7 +34,7 @@
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:fillViewport="true"> android:fillViewport="true">
<LinearLayout <LinearLayout

View File

@@ -69,7 +69,7 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager <com.xscm.moduleutil.widget.CustomViewPager
android:id="@+id/view_pager" android:id="@+id/view_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@@ -95,7 +95,8 @@
android:textSize="@dimen/sp_16" android:textSize="@dimen/sp_16"
app:layout_constraintStart_toEndOf="@+id/riv_user_head" app:layout_constraintStart_toEndOf="@+id/riv_user_head"
app:layout_constraintTop_toTopOf="@+id/riv_user_head" app:layout_constraintTop_toTopOf="@+id/riv_user_head"
tools:text="用户22333333" /> tools:text="用户22333333"
app:isShine="false"/>
<TextView <TextView
android:id="@+id/beautiful_view" android:id="@+id/beautiful_view"