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
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<RoomPresenter?, ActivityRoomBinding?>(),
// 初始化礼物管理器
GiftDisplayManager.getInstance().setupDisplayView(mBinding?.giftContainer)
// 预加载飘屏视图,避免首次显示时的延迟
preloadFloatingViews()
initPublicScreenFragment()
}
@@ -2004,7 +2012,12 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
private var currentMqttView: View? = 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) {
if (roomMessageEvent.text.fromUserInfo.enter_image?.isNotEmpty() == true) {
@@ -2017,42 +2030,78 @@ class RoomActivity : BaseMvpActivity<RoomPresenter?, ActivityRoomBinding?>(),
// 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<RoomPresenter?, ActivityRoomBinding?>(),
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()
}
}

View File

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

View File

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

View File

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

View File

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

View File

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