feat: 联机送礼功能

This commit is contained in:
max
2024-09-09 18:39:22 +08:00
parent d949cfa7ff
commit e3c5f10d02
26 changed files with 1152 additions and 167 deletions

Binary file not shown.

View File

@@ -22,9 +22,7 @@ import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope
@@ -59,9 +57,7 @@ import com.chwl.app.event.OpenRoomIntroEvent
import com.chwl.app.friend.view.SelectFriendActivity
import com.chwl.app.home.adapter.RoomActAdapter
import com.chwl.app.music.widget.MusicPlayerView
import com.chwl.app.public_chat.ui.message.HeadlineViewModel
import com.chwl.app.room_chat.activity.RoomMsgActivity
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.ui.webview.DialogWebViewActivity
import com.chwl.app.ui.widget.ButtonItem
@@ -69,7 +65,6 @@ import com.chwl.app.ui.widget.GiftDialog
import com.chwl.app.ui.widget.GiftDialog.OnGiftDialogBtnClickListener
import com.chwl.app.ui.widget.GiftDialog.SenGiftCallback
import com.chwl.app.ui.widget.UserInfoDialog
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.app.ui.widget.dynamicface.DynamicFaceDialog
import com.chwl.app.ui.widget.magicindicator.MagicIndicator
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
@@ -78,13 +73,13 @@ import com.chwl.app.ui.widget.rollviewpager.RollPagerView
import com.chwl.app.ui.widget.rollviewpager.Util
import com.chwl.app.ui.widget.rollviewpager.hintview.ColorPointHintView
import com.chwl.app.utils.KeyBoardUtils
import com.chwl.app.vip.dialog.SelectPayTypeDialog
import com.chwl.core.Constants
import com.chwl.core.UriProvider
import com.chwl.core.auth.AuthModel
import com.chwl.core.bean.RoomMicInfo
import com.chwl.core.gift.GiftModel
import com.chwl.core.gift.bean.GiftInfo
import com.chwl.core.gift.event.GiftComboEvent
import com.chwl.core.gift.event.RoomFreeGiftEvent
import com.chwl.core.helper.AtProxy
import com.chwl.core.home.bean.BannerInfo
@@ -118,7 +113,6 @@ import com.chwl.core.support.room.RoomWidget
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.BaseInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.utils.net.BalanceNotEnoughExeption
import com.chwl.core.utils.net.VipLevelNotEnoughException
import com.chwl.library.common.util.LimitClickUtils
import com.chwl.library.net.rxnet.utils.RxNetWorkUtils
@@ -135,7 +129,6 @@ import com.tbruyelle.rxpermissions2.RxPermissions
import com.trello.rxlifecycle3.android.FragmentEvent
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -870,6 +863,9 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
for (i in micMemberInfos.indices) {
targetUids.add(micMemberInfos[i].account.toLong())
}
EventBus.getDefault().post(GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_BEGIN))
GiftModel.get()
.sendRoomGift(
giftInfo.giftId,
@@ -891,11 +887,16 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
dialogManager.showOkDialog(message)
}
}
.subscribe { _, throwable ->
.subscribe { gift, throwable ->
if (throwable != null) {
toast(throwable.message)
callback.onFail()
EventBus.getDefault().post(GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_CANCEL))
} else {
giftDialog?.hide()
val giftComboEvent = GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_END)
giftComboEvent.giftNumber = gift.data.giftNum
EventBus.getDefault().post(giftComboEvent)
callback.onSuccess()
}
}
@@ -1485,4 +1486,22 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
protected open fun onInitMusicPlayerView(view: MusicPlayerView) {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onGiftComboEvent(event: GiftComboEvent) {
when (event.action) {
GiftComboEvent.Action.ACT_GIFT_START-> {
giftDialog?.sendGift()
}
GiftComboEvent.Action.ACT_GIFT_SHOW-> {
giftDialog?.show()
}
else -> {}
}
}
}

View File

@@ -6,6 +6,7 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewConfiguration;
@@ -18,10 +19,15 @@ import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import com.chwl.app.BuildConfig;
import com.chwl.app.avroom.activity.RoomTitleEditActivity;
import com.chwl.core.utils.ComboUtil;
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
import com.chwl.app.ui.widget.GiftComboButtonView;
import com.chwl.app.ui.widget.GiftDialog;
import com.chwl.app.ui.widget.UserInfoDialog;
import com.chwl.core.gift.event.GiftComboEvent;
import com.chwl.core.gift.toolbox.GiftToolbox;
import com.chwl.library.utils.JavaUtil;
import com.example.lib_utils.UiUtils;
import com.netease.nim.uikit.common.util.string.StringUtil;
@@ -243,13 +249,22 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
case RoomEvent.ROOM_INFO_UPDATE:
updateView(AvRoomDataManager.get().mCurrentRoomInfo);
break;
case RoomEvent.RECEIVE_NORMALE_GIFT:
case RoomEvent.RECEIVE_NORMALE_GIFT://普通
if (BuildConfig.DEBUG){
Log.e(this.getClass().getSimpleName()+" RoomEventObservable", "普通 : "+roomEvent.getGiftReceiveInfo());
}
onReceiveGiftMsg(roomEvent.getGiftReceiveInfo());
break;
case RoomEvent.RECEIVE_MUTLT_NORMALEI_GIFT://普通多人
if (BuildConfig.DEBUG){
Log.e(this.getClass().getSimpleName()+" RoomEventObservable", "普通多人 : "+roomEvent.getGiftMultiReceiverInfo());
}
onReceiveMultiGiftMsg(roomEvent.getGiftMultiReceiverInfo());
break;
case RoomEvent.RECEIVE_ALL_MIC__NORMALEI_GIFT://普通全麦
if (BuildConfig.DEBUG){
Log.e(this.getClass().getSimpleName()+" RoomEventObservable", "普通全麦 : "+roomEvent.getMultiGiftReceiveInfo());
}
onReceiveAllMicGiftMsg(roomEvent.getMultiGiftReceiveInfo());
break;
//福袋礼物
@@ -495,6 +510,7 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
giftView.release();
}
EventBus.getDefault().unregister(this);
gameMainBinding.giftComboBtn.cancel();
super.onDestroy();
}
@@ -508,10 +524,10 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
updateOnlineNumberView(onlineNumber);
}
/**
* 普通多人
*
* @param giftMultiReceiverInfo
*/
private void onReceiveMultiGiftMsg(GiftMultiReceiverInfo giftMultiReceiverInfo) {
if (giftMultiReceiverInfo == null || !isResumed()) return;
@@ -519,12 +535,12 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveGiftToMultiMsg(giftMultiReceiverInfo);
giftMultiReceiverInfo.isMulti = true;
gameMainBinding.giftComboLayout.onRoomCustomMsg(giftMultiReceiverInfo);
}
/**
* 普通全麦
*
* @param multiGiftReceiveInfo
*/
private void onReceiveAllMicGiftMsg(MultiGiftReceiveInfo multiGiftReceiveInfo) {
if (multiGiftReceiveInfo == null || !isResumed()) return;
@@ -532,14 +548,20 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveMultiGiftMsg(multiGiftReceiveInfo);
gameMainBinding.giftComboLayout.onRoomCustomMsg(GiftToolbox.transformToGiftMultiReceiverInfo(multiGiftReceiveInfo));
}
/**
* 普通
*/
private void onReceiveGiftMsg(GiftReceiveInfo giftReceiveInfo) {
if (giftReceiveInfo == null || !isResumed()) return;
if (giftView == null) {
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveGiftMsg(giftReceiveInfo);
gameMainBinding.giftComboLayout.onRoomCustomMsg(GiftToolbox.transformToGiftMultiReceiverInfo(giftReceiveInfo));
}
private void onReceiveMagicMsg(MagicReceivedInfo magicReceivedInfo) {
@@ -611,4 +633,48 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
dialogFragment.show(requireActivity().getSupportFragmentManager(), "roomTitle");
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onGiftComboEvent(GiftComboEvent event) {
if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_BEGIN) {
if (gameMainBinding.giftComboBtn.isInCombo()){
gameMainBinding.giftComboBtn.waitStart();
}
} else if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_END) {
showComboBtn(event.getGiftNumber());
}else if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_CANCEL) {
if (gameMainBinding.giftComboBtn.isInCombo()) {
gameMainBinding.giftComboBtn.cancel();
}
}
}
private void showComboBtn(int number) {
if (gameMainBinding.giftComboBtn.getOnGiftComboEndListener() == null) {
gameMainBinding.giftComboBtn.setOnClickListener(v -> {
ComboUtil.INSTANCE.setPoint(gameMainBinding.giftComboBtn);
EventBus.getDefault().post(new GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_START));
gameMainBinding.giftComboBtn.onBtnDown();
});
gameMainBinding.giftComboBtn.setOnGiftComboEndListener(new GiftComboButtonView.OnGiftComboEndListener() {
@Override
public void onGiftComboEnd() {
gameMainBinding.giftComboBtn.showView(false);
EventBus.getDefault().post(new GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_SHOW));
}
});
}
gameMainBinding.giftComboBtn.showView(true);
gameMainBinding.giftComboBtn.start();
gameMainBinding.giftComboBtn.updateNumber(number);
}
}

View File

@@ -23,6 +23,8 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.chwl.core.utils.ComboUtil;
import com.chwl.core.auth.AuthModel;
import com.example.lib_utils.UiUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
@@ -255,6 +257,13 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
}
Point senderPoint = micViewPoint.get(senderPosition);
Point receivePoint = micViewPoint.get(receivePosition);
if (giftReceiveInfo.getUid() == AuthModel.get().getCurrentUid()){
if (ComboUtil.INSTANCE.isChangePoint()) {
senderPoint = ComboUtil.INSTANCE.getPoint();
}
}
//设置动画结束的位置
if (receivePoint == null || isGameRoomMoreThan6People()) { //这种情况就是接收者已经不在麦上
//礼物送到中间的位置

View File

@@ -0,0 +1,62 @@
package com.chwl.app.ui.utils
import com.opensource.svgaplayer.utils.Pools
import java.lang.ref.SoftReference
import java.util.LinkedList
class SoftPool <T:Any> (private var max:Int) : Pools.Pool<T> {
init {
if (max <= 0){
max = 8
}
}
private var mPool = LinkedList<SoftReference<T>>()
fun acquire(getItemEmpty:()->T):T{
return acquire()?:getItemEmpty()
}
override fun acquire(): T? {
if (mPool.size == 0){
return null
}
while (true){
val item = mPool.poll()?:return null
if (item.get() != null) {
return item.get()
}
}
}
override fun release(instance: T): Boolean {
if (mPool.size > max) {
if (getRealSize() > max) {
return false
}
}
mPool.addFirst(SoftReference(instance))
return true
}
private fun getRealSize() : Int{
val iterator = mPool.listIterator()
while (iterator.hasNext()) {
val item = iterator.next().get()
if (item == null) iterator.remove()
}
return mPool.size
}
fun clear(){
mPool.clear()
}
}

View File

@@ -0,0 +1,295 @@
package com.chwl.app.ui.widget
import android.content.Context
import android.graphics.Canvas
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader
import android.util.AttributeSet
import android.view.View
import androidx.annotation.Keep
import com.chwl.app.R
import com.chwl.library.utils.SizeUtils
class ColorfulRingProgressView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
private var mPercent = 0f
private var mStrokeWidth = 0f
private var mStartAngle = 0f
private var mFgColorStart = 0xffb900
private var mFgColorEnd = 0xffb900
private var widthDiff = 3
private var mBgColor = -0xa0a0b
private var mShader: LinearGradient? = null
private var mOval = RectF()
private val progressPaint = Paint()
private var mNegative = false //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E3B5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>100-0<><30>
private val circlePaint = Paint()
private var progressChangeListener: OnProgressChangeListener? = null
init {
val a = context.theme.obtainStyledAttributes(attrs, R.styleable.ColorfulRingProgressView, 0, 0)
try {
mFgColorEnd = a.getColor(R.styleable.ColorfulRingProgressView_fgColorEnd, 0xffb900)
mFgColorStart = a.getColor(R.styleable.ColorfulRingProgressView_fgColorStart, 0xffb900)
mPercent = a.getFloat(R.styleable.ColorfulRingProgressView_currentPercent, 75f)
mStartAngle = a.getFloat(R.styleable.ColorfulRingProgressView_ringProgress_startAngle, 0f) + 270
mStrokeWidth = a.getDimensionPixelSize(R.styleable.ColorfulRingProgressView_circleStrokeWidth, 21).toFloat()
widthDiff = a.getDimensionPixelSize(R.styleable.ColorfulRingProgressView_circle_width_diff, 3)
mBgColor = a.getColor(R.styleable.ColorfulRingProgressView_circle_bg_color, -0xa0a0b)
mNegative = a.getBoolean(R.styleable.ColorfulRingProgressView_crp_negative, false)
} finally {
a.recycle()
}
progressPaint.isAntiAlias = true
progressPaint.style = Paint.Style.STROKE
progressPaint.strokeWidth = mStrokeWidth
progressPaint.strokeCap = Paint.Cap.ROUND
circlePaint.style = Paint.Style.STROKE
circlePaint.isAntiAlias = true
circlePaint.color = mBgColor
circlePaint.strokeWidth = mStrokeWidth + widthDiff
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(
(mOval.right + mOval.left) / 2,
(mOval.bottom + mOval.top) / 2,
(mOval.bottom - mOval.top) / 2,
circlePaint
)
progressPaint.setShader(mShader)
if (mNegative) {
canvas.drawArc(mOval, mStartAngle + (100 - mPercent) * 3.6f, 360 - (100 - mPercent) * 3.6f, false, progressPaint)
} else {
canvas.drawArc(mOval, mStartAngle, mPercent * 3.6f, false, progressPaint)
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
updateOval()
mShader = LinearGradient(
mOval.left, mOval.top,
mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR
)
}
@set:Keep
var percent: Float
get() = mPercent
set(mPercent) {
this.mPercent = mPercent
postInvalidate()
if (progressChangeListener != null) {
progressChangeListener?.onProgressChange(mPercent)
}
}
fun setProgressChangeListener(progressChangeListener: OnProgressChangeListener?) {
this.progressChangeListener = progressChangeListener
}
var strokeWidth: Float
get() = mStrokeWidth
set(mStrokeWidth) {
this.mStrokeWidth = mStrokeWidth
progressPaint.strokeWidth = mStrokeWidth
updateOval()
refreshTheLayout()
}
private fun updateOval() {
val xp = paddingLeft + paddingRight
val yp = paddingBottom + paddingTop
mOval = RectF(
paddingLeft + mStrokeWidth, paddingTop + mStrokeWidth,
paddingLeft + (width - xp) - mStrokeWidth,
paddingTop + (height - yp) - mStrokeWidth
)
}
fun setStrokeWidthDp(dp: Float) {
this.mStrokeWidth = SizeUtils.dp2px(context,dp).toFloat()
progressPaint.strokeWidth = mStrokeWidth
updateOval()
refreshTheLayout()
}
private fun refreshTheLayout() {
invalidate()
requestLayout()
}
var fgColorStart: Int
get() = mFgColorStart
set(mFgColorStart) {
this.mFgColorStart = mFgColorStart
mShader = LinearGradient(
mOval.left, mOval.top,
mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR
)
refreshTheLayout()
}
var fgColorEnd: Int
get() = mFgColorEnd
set(mFgColorEnd) {
this.mFgColorEnd = mFgColorEnd
mShader = LinearGradient(
mOval.left, mOval.top,
mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR
)
refreshTheLayout()
}
var startAngle: Float
get() = mStartAngle
set(mStartAngle) {
this.mStartAngle = mStartAngle + 270
refreshTheLayout()
}
fun interface OnProgressChangeListener {
fun onProgressChange(mPercent: Float)
}
}

View File

@@ -0,0 +1,171 @@
package com.chwl.app.ui.widget
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.chwl.app.databinding.ViewGiftComboButtonBinding
import com.chwl.core.utils.ComboUtil
import com.opensource.svgaplayer.SVGACallback
class GiftComboButtonView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : FrameLayout(context, attrs) {
var onGiftComboEndListener: OnGiftComboEndListener? = null
private var comboNum = 0
private var comboCount = 0
private val objectAnimator: ObjectAnimator by lazy {
ObjectAnimator.ofFloat(mBinding.pvBg, "percent", 100F, 0F).apply {
duration = DOWN_COUNT_TIME
}
}
private val mBinding = ViewGiftComboButtonBinding.inflate(LayoutInflater.from(context), this)
private val vibrator by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
(context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator
} else {
context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}
}
init {
mBinding.ivBtn.isLongClickable = false
mBinding.pvBg.setProgressChangeListener{
if(it == 0f){
isGone = true
comboNum = 0
comboCount = 0
ComboUtil.comboCount = comboCount+1
mBinding.tvNum.text = ""
onGiftComboEndListener?.onGiftComboEnd()
}
}
}
fun onBtnDown(){
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(100L, VibrationEffect.DEFAULT_AMPLITUDE))
}else{
vibrator.vibrate(100)
}
} catch (_: Exception) { }
// mBinding.ivBtn.animate().cancel()
// mBinding.ivBtn.animate()
// .scaleX(0.875f)
// .scaleY(0.875f)
// .setDuration(50)
// .withEndAction {
// onBtnUp()
// }
// .start()
// mBinding.pvBg.animate().cancel()
// mBinding.pvBg.animate()
// .scaleX(0.875f)
// .scaleY(0.875f)
// .setDuration(50)
// .start()
// mBinding.ivBg.animate().cancel()
// mBinding.ivBg.alpha = 0f
// mBinding.ivBg.scaleX = 1f
// mBinding.ivBg.scaleY = 1f
mBinding.svga.stopAnimation()
mBinding.svga.startAnimation()
}
private fun onBtnUp(){
mBinding.ivBtn.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(50)
.withEndAction { }
.start()
mBinding.pvBg.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(50)
.start()
mBinding.ivBg.alpha = 1f
mBinding.ivBg.animate()
.alpha(0f)
.scaleX(1.3f)
.scaleY(1.3f)
.start()
}
fun getComboNum():Int{
return comboNum
}
fun isInCombo():Boolean{
return comboNum > 0
}
fun cancel() {
objectAnimator.cancel()
mBinding.pvBg.percent = 0f
}
fun start() {
objectAnimator.start()
}
fun waitStart() {
mBinding.pvBg.percent = 100f
objectAnimator.pause()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
cancel()
objectAnimator.removeAllListeners()
objectAnimator.removeAllUpdateListeners()
}
/**
* 用于更新按钮上的文字
*/
@SuppressLint("SetTextI18n")
fun updateNumber(num: Int) {
comboNum += num
comboCount++
mBinding.tvNum.text = "x$comboCount"
ComboUtil.comboCount = comboCount+1
}
fun interface OnGiftComboEndListener {
fun onGiftComboEnd()
}
companion object {
/**
* 倒计时时间,毫秒为单位
*/
const val DOWN_COUNT_TIME = 5 * 1000L
}
fun showView(isVis : Boolean){
if (isVis) {
if (!isVisible) isVisible = true
}else{
if (isVisible) isVisible = false
}
}
}

View File

@@ -10,19 +10,20 @@ import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.util.Pools.Pool
import androidx.core.util.Pools.SimplePool
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.cursoradapter.widget.SimpleCursorAdapter.ViewBinder
import androidx.room.util.query
import androidx.viewbinding.ViewBinding
import com.chwl.app.R
import com.chwl.app.databinding.ItemGiftComboViewBinding
import com.chwl.app.application.GlobalHandleManager
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.ui.utils.SoftPool
import com.chwl.core.gift.bean.GiftComboInfo
import com.opensource.svgaplayer.utils.Pools
import com.chwl.core.gift.bean.GiftMultiReceiverInfo
import com.chwl.core.utils.LogUtils
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.UiUtils
import java.util.LinkedList
class GiftComboLayout @JvmOverloads constructor(
@@ -30,12 +31,12 @@ class GiftComboLayout @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes), View.OnClickListener {
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes){
private val showingList = LinkedList<GiftComboInfo>()
private val waitingList = LinkedList<GiftComboInfo>()
private val comboMap = linkedMapOf<GiftComboInfo, ItemGiftComboViewBinding>()
private val cacheView = SimplePool<ItemGiftComboViewBinding>(2)
private val comboMap = linkedMapOf<GiftComboInfo, View>()
private val cacheView = SoftPool<View>(2)
private val inflater = LayoutInflater.from(context)
private val handle = Handler(Looper.getMainLooper()) {
@@ -46,45 +47,46 @@ class GiftComboLayout @JvmOverloads constructor(
}
init {
orientation = VERTICAL
if(isInEditMode){
inflater.inflate(R.layout.item_gift_combo_view, this, true)
inflater.inflate(R.layout.item_gift_combo_view, this, true)
}
orientation = VERTICAL
}
/**
* 创建
*/
private fun getComboChildView(): ItemGiftComboViewBinding {
val acquire = cacheView.acquire()
if (acquire == null){
val viewbinding = ItemGiftComboViewBinding.inflate(inflater)
viewbinding.root.apply {
createViewHolder(this)
isVisible = true
}
cacheView.release(viewbinding)
return viewbinding
}else{
return acquire
private fun getComboChildView(): View {
return cacheView.acquire {
inflater.inflate(R.layout.item_gift_combo_view, this, false)
}.apply {
createViewHolder(this)
isVisible = true
}
}
/**
* add data
*/
fun add(giftComboInfo: GiftComboInfo?) {
LogUtils.d(" ComboView add --start")
//没有绑定之前不能添加
if (!isAttachedToWindow) {
LogUtils.d(" ComboView add isAttachedToWindow --end")
return
}
if (giftComboInfo == null) {
LogUtils.d(" ComboView add giftComboInfo == null --end")
return
}
var addToWaiting = true
for (comboInfo in showingList) {
if(comboInfo == giftComboInfo){
if(comboInfo.sentUserid == giftComboInfo.sentUserid && comboInfo.giftId == giftComboInfo.giftId){
LogUtils.d(" ComboView add showingList "+giftComboInfo.sentUserid)
comboInfo.giftNumber = giftComboInfo.giftNumber
updateNum(comboInfo)
addToWaiting = false
@@ -92,7 +94,8 @@ class GiftComboLayout @JvmOverloads constructor(
}
for (comboInfo in waitingList) {
if(comboInfo == giftComboInfo){
if(comboInfo.sentUserid == giftComboInfo.sentUserid && comboInfo.giftId == giftComboInfo.giftId){
LogUtils.d(" ComboView add waitingList "+giftComboInfo.sentUserid)
comboInfo.giftNumber = giftComboInfo.giftNumber
addToWaiting = false
}
@@ -103,35 +106,117 @@ class GiftComboLayout @JvmOverloads constructor(
}
showNext()
LogUtils.d(" ComboView add --end")
}
/**
* 更新数量
*/
private fun updateNum(giftComboInfo: GiftComboInfo) {
LogUtils.d(" ComboView updateNum --start")
val view = comboMap[giftComboInfo] ?: return
val viewHolder = getViewHolder(view)
viewHolder?.refreshNum(giftComboInfo, true)
handle.removeMessages(1, giftComboInfo)
handle.sendMessageDelayed(Message.obtain(handle, 1, giftComboInfo), COMBO_STAY_TIME * 1000L)
LogUtils.d(" ComboView updateNum --end")
}
/**
* 显示下一个
*/
private fun showNext() {
LogUtils.d(" ComboView showNext --start")
if(waitingList.isEmpty()){
LogUtils.d(" ComboView showNext isEmpty --end")
return
}
val comboChildView = getComboChildView()
addView(comboChildView.root,0)
addView(comboChildView,0)
val giftComboInfo = waitingList.remove()
showingList.add(giftComboInfo)
comboMap[giftComboInfo] = comboChildView
showUi(giftComboInfo)
viewAnimationIn(comboChildView.root)
val viewHolder = getViewHolder(comboChildView)
viewHolder?.showUi(giftComboInfo)
viewAnimationIn(comboChildView)
handle.sendMessageDelayed(Message.obtain(handle, 1, giftComboInfo), COMBO_STAY_TIME * 1000L)
if(showingList.size > MAX_SHOWING){
handle.removeMessages(1, showingList[0])
viewOut(showingList.remove(), true)
LogUtils.d(" ComboView showNext MAX_SHOWING --end")
return
}
LogUtils.d(" ComboView showNext --end")
}
/**
* 移除动画
*/
private fun viewOut(giftComboInfo: GiftComboInfo?, isDirectRemove: Boolean) {
LogUtils.d(" ComboView viewOut --start")
giftComboInfo ?: return
val comboView = comboMap.remove(giftComboInfo) ?: return
LogUtils.d(" ComboView viewOut init runnable")
val runnable = {
LogUtils.d(" ComboView viewOut init runnable -- start")
val viewHolder = getViewHolder(comboView)
viewHolder?.clear()
if(!isDirectRemove){
showingList.remove(giftComboInfo)
}
removeView(comboView)
cacheView.release(comboView)
showNext()
LogUtils.d(" ComboView viewOut init runnable -- end")
}
if(isDirectRemove){
comboView.isGone = true
comboView.post(runnable)
LogUtils.d(" ComboView viewOut -- isDirectRemove ")
}else{
val animOut = AnimationUtils.loadAnimation(context, R.anim.alpha_out)
animOut.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
LogUtils.d(" ComboView viewOut -- onAnimationEnd ")
GlobalHandleManager.get().activity.runOnUiThread {
LogUtils.d(" ComboView viewOut -- onAnimationEnd -- runOnUiThread")
LogUtils.d(" ComboView viewOut init runnable -- start")
val viewHolder = getViewHolder(comboView)
viewHolder?.clear()
if(!isDirectRemove){
showingList.remove(giftComboInfo)
}
removeView(comboView)
cacheView.release(comboView)
showNext()
LogUtils.d(" ComboView viewOut init runnable -- end")
}
}
override fun onAnimationRepeat(animation: Animation?) {
}
})
comboView.startAnimation(animOut)
LogUtils.d(" ComboView viewOut -- animOut ")
}
LogUtils.d(" ComboView viewOut --end")
}
/**
* 飞入动画
*/
@@ -140,126 +225,139 @@ class GiftComboLayout @JvmOverloads constructor(
view.startAnimation(AnimationUtils.loadAnimation(context, R.anim.right_to_left))
}
/**
* 移除动画
*/
private fun viewOut(giftComboInfo: GiftComboInfo?, isDirectRemove: Boolean) {
giftComboInfo ?: return
val comboView = comboMap.remove(giftComboInfo) ?: return
val runnable = {
val viewHolder = getViewHolder(comboView)
viewHolder?.clear()
if(!isDirectRemove){
showingList.remove(giftComboInfo)
}
removeView(comboView)
cacheView.release(comboView)
showNext()
}
if(isDirectRemove){
comboView.isGone = true
comboView.post(runnable)
}else{
val animOut = AnimationUtils.loadAnimation(context, R.anim.alpha_out)
animOut.setAnimationListener(object :SimpleAnimatorListener(){
override fun onAnimationEnd(animation: Animation) {
comboView.post(runnable)
}
})
comboView.startAnimation(animOut)
}
}
/**
* 更新数量
*/
private fun updateNum(giftComboInfo: GiftComboInfo) {
val view = comboMap[giftComboInfo] ?: return
val viewHolder = getViewHolder(view)
viewHolder?.refreshNum(giftComboInfo, true)
handle.removeMessages(1, giftComboInfo)
handle.sendMessageDelayed(Message.obtain(handle, 1, giftComboInfo), COMBO_STAY_TIME * 1000L)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if(isInEditMode) return
// RoomMsgManager.addCustomMsgListener(this)
}
override fun onRoomCustomMsg(attach: BaseAttach<*>) {
if(attach is NormalGiftAttach){
val receiveInfo = attach.data ?: return
val comboInfo = GiftComboInfo().apply {
senderUid = receiveInfo.uid
senderName = receiveInfo.nick
senderAvatar = receiveInfo.avatar
receiverName = receiveInfo.targetNicks?.getOrNull(0)
receiverCount = receiveInfo.receiverCount
giftCount = receiveInfo.giftComboCount
giftUrl = receiveInfo.gift?.giftUrl
}
add(comboInfo)
// override fun onRoomCustomMsg(attach: BaseAttach<*>) {
// if(attach is NormalGiftAttach){
// val receiveInfo = attach.data ?: return
// val comboInfo = GiftComboInfo().apply {
// senderUid = receiveInfo.uid
// senderName = receiveInfo.nick
// senderAvatar = receiveInfo.avatar
// receiverName = receiveInfo.targetNicks?.getOrNull(0)
// receiverCount = receiveInfo.receiverCount
// giftCount = receiveInfo.giftComboCount
// giftUrl = receiveInfo.gift?.giftUrl
// }
// add(comboInfo)
// }
// }
fun onRoomCustomMsg(giftInfo: GiftMultiReceiverInfo?) {
if (giftInfo==null) return
val comboInfo = GiftComboInfo().apply {
giftId = giftInfo.giftId
sentUserid = giftInfo.uid
sentUserName = giftInfo.nick
sentAvatar = giftInfo.avatar
receiverUserName = giftInfo.targetUsers?.getOrNull(0)?.nick?:""
receiverNumber = giftInfo.targetUsers?.size?:1
giftNumber = (giftInfo.comboCount * giftInfo.giftNum)
giftImgUrl = giftInfo.gift?.giftUrl?:""
comboCount = giftInfo.comboCount
isMulti = giftInfo.isMulti
}
}
@SuppressLint("SetTextI18n")
fun setNextUi(giftComboInfo: GiftComboInfo) {
refreshNum(giftComboInfo)
tvNick.text = giftComboInfo.senderName
tvReceiverNick.text = giftComboInfo.receiverNick
tvNumber.text = "x${giftComboInfo.giftCount}"
ivGift.load(giftComboInfo.giftUrl)
ivAvatar.load(giftComboInfo.senderAvatar)
ivAvatar.tag = giftComboInfo
}
/**
* 用于刷新数量
*/
@SuppressLint("SetTextI18n")
fun reSetNum(giftComboInfo: GiftComboInfo, isAnim: Boolean = false) {
val num = giftComboInfo.giftCount
if(num == 0){
tvNumber.isVisible = false
return
}
val old = tvNumber.tag as? Int
//兼容上一个比下一个数还要大
if (old != null && old > num) {
return
}
tvNumber.isVisible = true
tvNumber.tag = num
tvNumber.text = "x$num"
if (isAnim) {
tvNumber.animate().cancel()
tvNumber.scaleX = 1.3f
tvNumber.scaleY = 1.3f
tvNumber.animate()
.scaleX(1f)
.scaleY(1f)
.start()
}
}
fun reSetUi() {
tvNumber.animate().cancel()
tvNumber.tag = 0
ivAvatar.tag = null
add(comboInfo)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
handle.removeCallbacksAndMessages(null)
// RoomMsgManager.removeCustomMsgListener(this)
}
private fun createViewHolder(view: View) {
getViewHolder(view) ?: ViewHolder(view)
}
private fun getViewHolder(view: View): ViewHolder? {
return view.tag as? ViewHolder
}
private inner class ViewHolder(view: View) {
var tvNumber: TextView = view.findViewById(R.id.giftComboNumber)
var ivGift: ImageView = view.findViewById(R.id.giftImg)
var tvNick: TextView = view.findViewById(R.id.sentUserName)
var tvReceiverNick: TextView = view.findViewById(R.id.receiverUserName)
var ivAvatar: ImageView = view.findViewById(R.id.sentUserAvatar)
var ivLayoutBg: ImageView = view.findViewById(R.id.layoutBg)
init {
view.tag = this
}
@SuppressLint("SetTextI18n")
fun showUi(giftComboInfo: GiftComboInfo) {
if (UiUtils.isRtl(context)){
ivLayoutBg.scaleX = -1f
}
refreshNum(giftComboInfo)
tvNick.text = giftComboInfo.sentUserName
if (giftComboInfo.receiverNumber == 1) {
tvReceiverNick.text = giftComboInfo.receiverUserName
} else {
if (giftComboInfo.isMulti) {
tvReceiverNick.text =
"${giftComboInfo.receiverNumber}" + ResUtil.getString(R.string.guys)
} else {
tvReceiverNick.text = ResUtil.getString(R.string.All_room)
}
}
tvNumber.text =
"x${giftComboInfo.giftNumber * giftComboInfo.receiverNumber * giftComboInfo.comboCount}"
ImageLoadUtils.loadImage(ivGift, giftComboInfo.giftImgUrl)
ImageLoadUtils.loadImage(ivAvatar, giftComboInfo.sentAvatar)
ivAvatar.tag = giftComboInfo
}
/**
* 用于刷新数量
*/
@SuppressLint("SetTextI18n")
fun refreshNum(giftComboInfo: GiftComboInfo, isAnim: Boolean = false) {
val num = giftComboInfo.giftNumber * giftComboInfo.receiverNumber * giftComboInfo.comboCount
if(num == 0){
tvNumber.isVisible = false
return
}
val old = tvNumber.tag as? Int
//兼容上一个比下一个数还要大
if (old != null && old > num) {
return
}
tvNumber.isVisible = true
tvNumber.tag = num
tvNumber.text = "x$num"
if (isAnim) {
tvNumber.animate().cancel()
tvNumber.scaleX = 1.3f
tvNumber.scaleY = 1.3f
tvNumber.animate()
.scaleX(1f)
.scaleY(1f)
.start()
}
}
/**
* 清空UI数据
*/
fun clear() {
tvNumber.animate().cancel()
tvNumber.tag = 0
ivAvatar.tag = null
}
}
companion object {
/**
@@ -275,11 +373,11 @@ class GiftComboLayout @JvmOverloads constructor(
// override fun onClick(v: View) {
// val giftComboInfo = v.tag as? GiftComboInfo ?: return
// val sendUid = giftComboInfo.sentUserid
// val sendUid = giftComboInfo.senderUid
// if (sendUid == 0L) {
// return
// }
//// RoomUserInfoDialog.show(sendUid)
// RoomUserInfoDialog.show(sendUid)
// }
}

View File

@@ -602,8 +602,10 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
private List<GiftTab> updateTabs() {
List<GiftTab> tabInfoList = new ArrayList<>();
for (TagsInfo info: GiftModel.get().getTabList()) {
tabInfoList.add(new GiftTab(swithGiftTypeToTabType(info), info.tagName(), info.tagName()));
if (GiftModel.get().getTabList() != null) {
for (TagsInfo info: GiftModel.get().getTabList()) {
tabInfoList.add(new GiftTab(swithGiftTypeToTabType(info), info.tagName(), info.tagName()));
}
}
return tabInfoList;
}
@@ -1775,4 +1777,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
void onFail();
}
public void sendGift(){
sendGiftButton.performClick();
}
}

View File

@@ -168,6 +168,26 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.chwl.app.ui.widget.GiftComboLayout
android:id="@+id/giftComboLayout"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.chwl.app.ui.widget.GiftComboButtonView
android:id="@+id/giftComboBtn"
android:visibility="gone"
tools:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_width="100dp"
tools:layout_height="100dp"
tools:background="@color/appColor"
android:layout_gravity="end|bottom"
android:layout_marginEnd="16dp"
android:layout_marginBottom="26dp"/>
</FrameLayout>
</layout>

View File

@@ -6,18 +6,19 @@
android:layout_height="48dp"
android:clipToPadding="false"
android:clipChildren="false"
tools:background="@color/appColor"
android:layout_marginStart="16dp">
<ImageView
android:id="@+id/layoutBg"
android:layout_width="wrap_content"
android:layout_height="38dp"
android:background="@mipmap/bg_item_gift_combo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintStart_toStartOf="parent" />
<ImageView
<com.chwl.app.common.widget.CircleImageView
android:id="@+id/sentUserAvatar"
android:layout_width="30dp"
android:layout_height="30dp"
@@ -77,23 +78,23 @@
<ImageView
android:id="@+id/giftImg"
android:layout_width="38dp"
android:layout_height="38dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="6dp"
app:layout_constraintBottom_toBottomOf="@+id/sentUserAvatar"
app:layout_constraintStart_toEndOf="@+id/barrier"
app:layout_constraintTop_toTopOf="@id/sentUserAvatar" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/barrier"/>
<TextView
<com.coorchice.library.SuperTextView
android:id="@+id/giftComboNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:shadowColor="#ffff9900"
android:shadowColor="#ff9900"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="3.0"
android:includeFontPadding="false"
android:textColor="#ffe07b"
android:textStyle="bold"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="@+id/sentUserAvatar"

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<merge 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/vg_button"
android:layout_width="wrap_content"
android:layout_height="306dp"
android:clickable="true"
android:layout_gravity="end|bottom"
android:focusable="true"
tools:parentTag="android.widget.FrameLayout">
<FrameLayout
android:layout_gravity="bottom|end"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.chwl.library.widget.SVGAView
android:id="@+id/svga"
android:layout_width="136dp"
android:layout_height="306dp"
android:layout_gravity="bottom|center"
app:autoPlay="true"
app:loopCount="1"
app:fillMode="Backward"
app:layout_constraintTop_toTopOf="parent"
app:source="svga/Combo_Boom.svga" />
<ImageView
android:id="@+id/iv_bg"
android:layout_width="57dp"
android:layout_height="57dp"
android:layout_marginBottom="26dp"
android:layout_gravity="bottom|center"
android:alpha="0"
android:src="@color/transparent"/>
<ImageView
android:id="@+id/iv_btn"
android:layout_width="57dp"
android:layout_height="57dp"
android:layout_marginBottom="26dp"
android:layout_gravity="bottom|center" />
<com.chwl.app.ui.widget.ColorfulRingProgressView
android:id="@+id/pv_bg"
android:layout_width="57dp"
android:layout_height="57dp"
android:layout_gravity="bottom|center"
app:circleStrokeWidth="5dp"
android:layout_marginBottom="26dp"
app:circle_bg_color="@color/transparent"
app:circle_width_diff="0dp"
app:currentPercent="50"
app:fgColorEnd="#04d5c6"
app:fgColorStart="#04d5c6" />
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Combo"
android:shadowColor="#ff9900"
android:shadowDx="0"
android:textSize="13sp"
android:shadowDy="1"
android:layout_marginBottom="48dp"
android:shadowRadius="3.0"
android:includeFontPadding="false"
android:textColor="#ffe07b"
android:textStyle="bold"
android:gravity="center"
android:layout_gravity="bottom|center" />
</FrameLayout>
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:rotation="-45"
android:layout_marginBottom="89dp"
android:layout_marginEnd="118dp"
android:shadowColor="#ff9900"
android:shadowDx="0"
android:shadowDy="1"
android:shadowRadius="3.0"
android:includeFontPadding="false"
android:textColor="#ffe07b"
android:textStyle="bold"
android:textSize="30sp"
tools:text="X15" />
</merge>

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -436,4 +436,15 @@
<attr name="shadowTop" format="boolean" />
</declare-styleable>
<declare-styleable name="ColorfulRingProgressView">
<attr name="fgColorStart" format="color" />
<attr name="fgColorEnd" format="color" />
<attr name="circleStrokeWidth" format="dimension" />
<attr name="currentPercent" format="float" />
<attr name="ringProgress_startAngle" format="float" />
<attr name="circle_width_diff" format="dimension" />
<attr name="circle_bg_color" format="color" />
<attr name="crp_negative" format="boolean" />
</declare-styleable>
</resources>

View File

@@ -5333,6 +5333,8 @@ You cannot join again within 24 hours after leaving</string>
<string name="vip_center_7">Renew</string>
<string name="vip_center_8">Not obtained VIP</string>
<string name="vip_center_9">VIP %s is only through activity</string>
<string name="guys">guys</string>
<string name="All_room">All room</string>
</resources>

View File

@@ -16,6 +16,7 @@ import com.chwl.core.gift.bean.GiftPanelInfo;
import com.chwl.core.gift.bean.TagsInfo;
import com.chwl.core.home.bean.TabInfo;
import com.chwl.core.pay.event.UpdateWalletInfoEvent;
import com.chwl.core.utils.ComboUtil;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
@@ -439,6 +440,7 @@ public class GiftModel extends BaseModel implements IGiftModel {
if (giftId != giftMultiReceiverInfo.getGiftId()) {
return Single.error(RxHelper.createThrowable(serviceResult));
}
giftMultiReceiverInfo.setComboCount(ComboUtil.INSTANCE.getComboCount());
switch (sendType) {
case GiftSendType.TYPE_ANCHOR:
case GiftSendType.TYPE_MIC:
@@ -493,6 +495,8 @@ public class GiftModel extends BaseModel implements IGiftModel {
SingleToastUtil.showToast(serviceResult.getMessage());
return Single.error(new RadishNotEnoughException(serviceResult.getMessage()));
}
return Single.error(RxHelper.createThrowable(serviceResult));
}
});

View File

@@ -5,8 +5,11 @@ public class GiftComboInfo {
public String sentUserName;
public String sentAvatar;
public String giftImgUrl;
public int giftId;
public int giftNumber;
public int receiverNumber;
public String receiverUserName;
public int comboCount;
public boolean isMulti;
}

View File

@@ -20,6 +20,7 @@ public class GiftMultiReceiverInfo implements Serializable {
private List<GiftReceiver> targetUsers;
private int giftId;
private int giftNum;
private int comboCount;
private GiftInfo gift;
private List<GiftInfo> displayGift;
private List<IndexGiftValue> giftValueVos;
@@ -28,4 +29,5 @@ public class GiftMultiReceiverInfo implements Serializable {
private List<Long> targetUids;
private LuckyGiftList luckyGiftList;
private WalletInfo userPurse;
public boolean isMulti;
}

View File

@@ -17,6 +17,7 @@ public class GiftReceiveInfo implements Serializable {
private long targetUid;
private int giftId;
private int giftNum;
private int comboCount;
private String targetNick;
private String targetAvatar;
private String nick;

View File

@@ -18,6 +18,7 @@ public class MultiGiftReceiveInfo implements Serializable {
private List<GiftReceiver> targetUsers;
private int giftId;
private int giftNum;
private int comboCount;
private String nick;
private String avatar;
private GiftInfo gift;

View File

@@ -0,0 +1,43 @@
package com.chwl.core.gift.event;
import lombok.Data;
//处理 礼物联机相关消息
@Data
public class GiftComboEvent {
private int action ;
private int giftNumber;
public int getGiftNumber() {
return giftNumber;
}
public void setGiftNumber(int giftNumber) {
this.giftNumber = giftNumber;
}
public GiftComboEvent() {
}
public GiftComboEvent(int action) {
this.action = action;
}
public int getAction() {
return action;
}
public void setAction(int action) {
this.action = action;
}
public @interface Action{
int ACT_GIFT_BEGIN = 1; //准备送礼
int ACT_GIFT_END = 2; //送礼完毕 显示连击按钮
int ACT_GIFT_START = 3; // 连击按钮点击 发送礼物
int ACT_GIFT_SHOW = 4; // 连击按钮消失 通知显示礼物弹窗
int ACT_GIFT_CANCEL = 5; // 连击按钮消失
}
}

View File

@@ -1,6 +1,7 @@
package com.chwl.core.gift.toolbox;
import android.text.TextUtils;
import android.util.Log;
import com.chwl.core.gift.bean.GiftType;
import com.google.gson.Gson;
@@ -103,24 +104,57 @@ public class GiftToolbox {
//礼物值
giftReceiveInfo.setGiftValueVos(giftMultiReceiverInfo.getGiftValueVos());
giftReceiveInfo.setCurrentTime(giftMultiReceiverInfo.getCurrentTime());
giftReceiveInfo.setComboCount(giftMultiReceiverInfo.getComboCount());
return giftReceiveInfo;
}
public static GiftMultiReceiverInfo transformToGiftMultiReceiverInfo(MultiGiftReceiveInfo multiGiftReceiveInfo) {
GiftMultiReceiverInfo giftMultiReceiverInfo = null;
try {
giftMultiReceiverInfo = new GiftMultiReceiverInfo();
giftMultiReceiverInfo.setUid(multiGiftReceiveInfo.getUid());
giftMultiReceiverInfo.setAvatar(multiGiftReceiveInfo.getAvatar());
giftMultiReceiverInfo.setNick(multiGiftReceiveInfo.getNick());
giftMultiReceiverInfo.setGiftId(multiGiftReceiveInfo.getGiftId());
giftMultiReceiverInfo.setGiftNum(multiGiftReceiveInfo.getGiftNum());
giftMultiReceiverInfo.setGift(multiGiftReceiveInfo.getGift());
giftMultiReceiverInfo.setLuckyBagGifts(multiGiftReceiveInfo.getLuckyBagGifts());
giftMultiReceiverInfo.setDisplayGift(multiGiftReceiveInfo.getDisplayGift());
giftMultiReceiverInfo.setTargetUsers(multiGiftReceiveInfo.getTargetUsers());
List<Long> targetUids = new ArrayList<>();
if (multiGiftReceiveInfo.getTargetUsers() != null){
for (GiftReceiver targetUser : multiGiftReceiveInfo.getTargetUsers()) {
targetUids.add(targetUser.getUid());
}
}
giftMultiReceiverInfo.setTargetUids(targetUids);
//礼物值
giftMultiReceiverInfo.setGiftValueVos(multiGiftReceiveInfo.getGiftValueVos());
giftMultiReceiverInfo.setCurrentTime(multiGiftReceiveInfo.getCurrentTime());
giftMultiReceiverInfo.setComboCount(multiGiftReceiveInfo.getComboCount());
} catch (Exception e) {
Log.e("error", ""+e.getMessage());
}
return giftMultiReceiverInfo;
}
public static GiftMultiReceiverInfo transformToGiftMultiReceiverInfo(GiftReceiveInfo giftReceiveInfo) {
GiftMultiReceiverInfo giftMultiReceiverInfo = new GiftMultiReceiverInfo();
giftMultiReceiverInfo.setUid(giftReceiveInfo.getUid());
giftMultiReceiverInfo.setNick(giftReceiveInfo.getNick());
giftMultiReceiverInfo.setAvatar(giftMultiReceiverInfo.getAvatar());
giftMultiReceiverInfo.setAvatar(giftReceiveInfo.getAvatar());
giftMultiReceiverInfo.setGift(giftReceiveInfo.getGift());
giftMultiReceiverInfo.setGiftId(giftReceiveInfo.getGiftId());
giftMultiReceiverInfo.setGiftNum(giftMultiReceiverInfo.getGiftNum());
giftMultiReceiverInfo.setGiftNum(giftReceiveInfo.getGiftNum());
giftMultiReceiverInfo.setLuckyBagGifts(giftReceiveInfo.getLuckyBagGifts());
giftMultiReceiverInfo.setDisplayGift(giftReceiveInfo.getDisplayGift());
giftMultiReceiverInfo.setComboCount(giftReceiveInfo.getComboCount());
List<GiftReceiver> targetUsers = new ArrayList<>();
GiftReceiver receiver = new GiftReceiver();
receiver.setUid(giftReceiveInfo.getTargetUid());
receiver.setNick(giftReceiveInfo.getTargetNick());
receiver.setAvatar(giftMultiReceiverInfo.getAvatar());
receiver.setAvatar(giftReceiveInfo.getTargetAvatar());
targetUsers.add(receiver);
giftMultiReceiverInfo.setTargetUsers(targetUsers);
return giftMultiReceiverInfo;
@@ -144,9 +178,12 @@ public class GiftToolbox {
giftReceiveInfo.setDisplayGift(giftMultiReceiverInfo.getDisplayGift());
giftReceiveInfo.setGiftValueVos(giftMultiReceiverInfo.getGiftValueVos());
giftReceiveInfo.setCurrentTime(giftMultiReceiverInfo.getCurrentTime());
giftReceiveInfo.setComboCount(giftMultiReceiverInfo.getComboCount());
return giftReceiveInfo;
}
/**
* 转换 ServiceResult<GiftMultiReceiverInfo> 成 ServiceResult<GiftReceiveInfo>
*/

View File

@@ -50,6 +50,7 @@ public class GiftAttachment extends CustomAttachment {
giftReceiveInfo.setNick(data.getString("nick"));
giftReceiveInfo.setTargetUid(data.getLong("targetUid"));
giftReceiveInfo.setGiftNum(data.getIntValue("giftNum"));
giftReceiveInfo.setComboCount(data.getIntValue("comboCount"));
giftReceiveInfo.setTargetNick(data.getString("targetNick"));
giftReceiveInfo.setTargetAvatar(data.getString("targetAvatar"));
if (data.containsKey("isRoomAlbum")) {
@@ -92,6 +93,7 @@ public class GiftAttachment extends CustomAttachment {
object.put("nick", giftReceiveInfo.getNick());
object.put("targetUid", giftReceiveInfo.getTargetUid());
object.put("giftNum", giftReceiveInfo.getGiftNum());
object.put("comboCount", giftReceiveInfo.getComboCount());
object.put("targetNick", giftReceiveInfo.getTargetNick());
object.put("targetAvatar", giftReceiveInfo.getTargetAvatar());
object.put("giftInfo", giftReceiveInfo.getGift());

View File

@@ -46,6 +46,7 @@ public class GiftBatchAttachment extends CustomAttachment {
new TypeReference<List<GiftReceiver>>() {
}));
giftMultiReceiverInfo.setGiftNum(data.getIntValue("giftNum"));
giftMultiReceiverInfo.setComboCount(data.getIntValue("comboCount"));
JSONObject giftJson = null;
if (data.containsKey("gift")) {
giftJson = data.getJSONObject("gift");
@@ -81,6 +82,7 @@ public class GiftBatchAttachment extends CustomAttachment {
object.put("nick", giftMultiReceiverInfo.getNick());
object.put("targetUsers", giftMultiReceiverInfo.getTargetUsers());
object.put("giftNum", giftMultiReceiverInfo.getGiftNum());
object.put("comboCount", giftMultiReceiverInfo.getComboCount());
object.put("gift", giftMultiReceiverInfo.getGift());
//礼物值
if (giftMultiReceiverInfo.getGiftValueVos() != null) {

View File

@@ -40,6 +40,7 @@ public class MultiGiftAttachment extends CustomAttachment {
multiGiftReceiveInfo.setAvatar(data.getString("avatar"));
multiGiftReceiveInfo.setNick(data.getString("nick"));
multiGiftReceiveInfo.setGiftNum(data.getIntValue("giftNum"));
multiGiftReceiveInfo.setComboCount(data.getIntValue("comboCount"));
JSONArray jsonArray = data.getJSONArray("targetUids");
List<Long> targetUids = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
@@ -75,6 +76,7 @@ public class MultiGiftAttachment extends CustomAttachment {
object.put("avatar", multiGiftReceiveInfo.getAvatar());
object.put("nick", multiGiftReceiveInfo.getNick());
object.put("giftNum", multiGiftReceiveInfo.getGiftNum());
object.put("comboCount", multiGiftReceiveInfo.getComboCount());
object.put("gift", multiGiftReceiveInfo.getGift());
JSONArray jsonArray = new JSONArray();

View File

@@ -0,0 +1,31 @@
package com.chwl.core.utils
import android.graphics.Point
import android.view.View
import com.chwl.library.utils.ScreenUtils
import com.example.lib_utils.UiUtils.isRtl
object ComboUtil {
var comboCount = 1
var point = Point(0,0)
fun setPoint(child: View) {
if (point.x>0 || point.y>0) return
val density: Float = child.context.resources.displayMetrics.density
val giftWidth = (80 * density + 0.5).toInt()
val location = IntArray(2)
child.getLocationInWindow(location)
val x: Int
if (isRtl(child.context)) {
location[0] = ScreenUtils.getScreenWidth(child.context) - location[0]
x = (location[0] - child.width / 2) - giftWidth / 2
} else {
x = (location[0] + child.width / 2) - giftWidth / 2
}
val y = (location[1] + child.height / 3) - giftWidth / 2
point = Point(x, y)
LogUtils.d("ComboUtil x= $x y= $y")
}
fun isChangePoint() = comboCount > 2
}