From dddd0e651c71ad71b8d81c18c223e1e0543aaff1 Mon Sep 17 00:00:00 2001 From: huangjian Date: Thu, 25 Feb 2021 15:49:52 +0800 Subject: [PATCH] add RoomEffectView.java --- .../avroom/fragment/HomePartyFragment.java | 687 ----------------- .../erban/avroom/widget/RoomEffectView.java | 690 ++++++++++++++++++ .../layout/fragment_chatroom_game_main.xml | 117 +-- .../main/res/layout/layout_room_effect.xml | 127 ++++ 4 files changed, 819 insertions(+), 802 deletions(-) create mode 100644 app/src/main/java/com/yizhuan/erban/avroom/widget/RoomEffectView.java create mode 100644 app/src/main/res/layout/layout_room_effect.xml diff --git a/app/src/main/java/com/yizhuan/erban/avroom/fragment/HomePartyFragment.java b/app/src/main/java/com/yizhuan/erban/avroom/fragment/HomePartyFragment.java index 4d1067e0e..8fab339e1 100644 --- a/app/src/main/java/com/yizhuan/erban/avroom/fragment/HomePartyFragment.java +++ b/app/src/main/java/com/yizhuan/erban/avroom/fragment/HomePartyFragment.java @@ -5,24 +5,11 @@ import android.content.Context; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.graphics.Color; -import android.graphics.Point; import android.media.MediaPlayer; import android.os.Bundle; -import android.os.SystemClock; -import android.text.Layout; -import android.text.StaticLayout; -import android.text.TextPaint; -import android.text.TextUtils; -import android.text.style.ForegroundColorSpan; -import android.util.SparseArray; -import android.view.LayoutInflater; import android.view.View; import android.view.ViewConfiguration; -import android.view.ViewGroup; import android.view.ViewStub; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -30,30 +17,18 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatImageView; import androidx.databinding.DataBindingUtil; -import com.coorchice.library.SuperTextView; import com.netease.nim.uikit.common.util.string.StringUtil; -import com.netease.nim.uikit.common.util.sys.ScreenUtil; import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder; import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage; -import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment; import com.netease.nimlib.sdk.msg.attachment.MsgAttachment; -import com.opensource.svgaplayer.SVGACallback; -import com.opensource.svgaplayer.SVGADrawable; -import com.opensource.svgaplayer.SVGADynamicEntity; -import com.opensource.svgaplayer.SVGAImageView; -import com.opensource.svgaplayer.SVGAParser; -import com.opensource.svgaplayer.SVGAVideoEntity; import com.trello.rxlifecycle3.android.FragmentEvent; import com.yizhuan.erban.R; import com.yizhuan.erban.UIHelper; import com.yizhuan.erban.avroom.activity.AVRoomActivity; import com.yizhuan.erban.avroom.activity.RoomOnlineUserActivity; -import com.yizhuan.erban.avroom.helper.AnimHelper; import com.yizhuan.erban.avroom.presenter.HomePartyPresenter; import com.yizhuan.erban.avroom.widget.GiftV2View; -import com.yizhuan.erban.avroom.widget.MessageView; import com.yizhuan.erban.base.BaseMvpActivity; -import com.yizhuan.erban.common.svga.SimpleSvgaCallback; import com.yizhuan.erban.common.widget.dialog.DialogManager; import com.yizhuan.erban.databinding.FragmentChatroomGameMainBinding; import com.yizhuan.erban.friend.view.SelectFriendActivity; @@ -61,33 +36,24 @@ import com.yizhuan.erban.treasure_box.widget.GoldBoxHelper; import com.yizhuan.erban.ui.widget.ButtonItem; import com.yizhuan.erban.ui.widget.ShareDialog; import com.yizhuan.erban.utils.RegexUtil; -import com.yizhuan.erban.utils.SpannableBuilder; import com.yizhuan.xchat_android_constants.XChatConstants; import com.yizhuan.xchat_android_core.Constants; import com.yizhuan.xchat_android_core.auth.AuthModel; -import com.yizhuan.xchat_android_core.decoration.car.bean.CarInfo; import com.yizhuan.xchat_android_core.gift.bean.GiftMultiReceiverInfo; import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo; import com.yizhuan.xchat_android_core.gift.bean.LuckyBagGifts; -import com.yizhuan.xchat_android_core.gift.bean.LuckyBagNoticeInfo; import com.yizhuan.xchat_android_core.gift.bean.MultiGiftReceiveInfo; import com.yizhuan.xchat_android_core.home.bean.BannerInfo; import com.yizhuan.xchat_android_core.home.event.FollowRoomEvent; import com.yizhuan.xchat_android_core.home.model.CollectionRoomModel; import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment; -import com.yizhuan.xchat_android_core.im.custom.bean.DatingAttachment; -import com.yizhuan.xchat_android_core.im.custom.bean.LevelUpNoticeAttachment; -import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeAttachment; import com.yizhuan.xchat_android_core.im.custom.bean.RoomInfoAttachment; -import com.yizhuan.xchat_android_core.im.custom.bean.RoomReceivedLuckyGiftAttachment; import com.yizhuan.xchat_android_core.magic.bean.MagicReceivedInfo; import com.yizhuan.xchat_android_core.magic.bean.MultiMagicReceivedInfo; import com.yizhuan.xchat_android_core.manager.AvRoomDataManager; import com.yizhuan.xchat_android_core.manager.IMNetEaseManager; import com.yizhuan.xchat_android_core.manager.RoomEvent; -import com.yizhuan.xchat_android_core.monsterhunting.SimpleAnimationListener; import com.yizhuan.xchat_android_core.praise.PraiseModel; -import com.yizhuan.xchat_android_core.room.bean.DatingNotifyInfo; import com.yizhuan.xchat_android_core.room.bean.RoomInfo; import com.yizhuan.xchat_android_core.room.game.GameEvent; import com.yizhuan.xchat_android_core.room.game.GameResultInfo; @@ -98,31 +64,19 @@ import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol; import com.yizhuan.xchat_android_core.super_admin.util.SuperAdminUtil; import com.yizhuan.xchat_android_core.user.UserModel; import com.yizhuan.xchat_android_core.user.bean.UserInfo; -import com.yizhuan.xchat_android_core.utils.StringExtensionKt; import com.yizhuan.xchat_android_library.rxbus.RxBus; -import com.yizhuan.xchat_android_library.utils.ListUtils; -import com.yizhuan.xchat_android_library.utils.LogUtil; import com.yizhuan.xchat_android_library.utils.SingleToastUtil; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; -import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; import cn.sharesdk.framework.Platform; -import io.reactivex.Observable; -import io.reactivex.ObservableOnSubscribe; -import io.reactivex.Single; import io.reactivex.SingleObserver; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; @@ -130,8 +84,6 @@ import io.reactivex.functions.Action; import nl.dionsegijn.konfetti.models.Shape; import nl.dionsegijn.konfetti.models.Size; -import static com.yizhuan.xchat_android_constants.XChatConstants.SELECT_ANIM_DURATION; - /** * 轰趴房 * Created by 2016/9/22. @@ -157,20 +109,11 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi private GiftV2View giftView; private ViewStub mVsGift2View; - private SVGAImageView mSvgaCar; - private SVGAImageView mSvgaMemberIn; - private SVGAImageView mSvgaLevelUp; - private SVGAParser mSVGAParser; - private boolean isSvgaPlaying; - private List mCarEffectList = new ArrayList<>(); - private UserInfo mUserInfo; private FragmentChatroomGameMainBinding gameMainBinding; private ShareDialog shareDialog; - private Disposable datingDisposable; - //收藏房间 private String FOLLOW_ROOM_TYPE = ""; //取消收藏房间 @@ -236,45 +179,9 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi } roomId = mView.findViewById(R.id.room_id); roomBack = mView.findViewById(R.id.room_back); - mSvgaCar = mView.findViewById(R.id.room_car_svga); - mSvgaMemberIn = mView.findViewById(R.id.room_menber_in_svga); - mSvgaLevelUp = mView.findViewById(R.id.room_level_up_svga); mVsGift2View = mView.findViewById(R.id.vs_gift_view); mIvGoodNumber = mView.findViewById(R.id.iv_good_number); tvFollowRoom = mView.findViewById(R.id.tv_follow_room); - - mSVGAParser = new SVGAParser(mContext); - - mSvgaCar.setVisibility(View.GONE); - mSvgaCar.setCallback(new SVGACallback() { - @Override - public void onPause() { - - } - - @Override - public void onFinished() { - isSvgaPlaying = false; - if (ListUtils.isListEmpty(mCarEffectList)) { - mSvgaCar.setVisibility(View.GONE); - return; - } - mCarEffectList.remove(0); - if (!ListUtils.isListEmpty(mCarEffectList)) { - playCarSvagEnterRoom(mCarEffectList.get(0)); - } - } - - @Override - public void onRepeat() { - - } - - @Override - public void onStep(int i, double v) { - - } - }); } /** @@ -299,88 +206,6 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi roomTitle.setSelected(true); } - @SuppressLint("CheckResult") - private void playCarSvga(String account, String effect, boolean isSendMsg) { - if (isSendMsg) { - UserModel.get().getUserInfoFromServer(Long.valueOf(account)) - .subscribe(userInfo -> { - //播放座驾动效 - if (userInfo != null - && userInfo.getCarInfo() != null - && userInfo.getCarInfo().isUsing() - && userInfo.getCarInfo().getStatus() == CarInfo.STATUS_USER_CAN_USE) { - if (AvRoomDataManager.get().mIsNeedGiftEffect) { - mCarEffectList.add(userInfo.getCarInfo().getEffect()); - } - // 非贵族人员,进来后要播放座驾动画 - if (userInfo.getNobleInfo() == null) { - if (!mSvgaCar.isAnimating() && !isSvgaPlaying) { - // 播放座驾动画 - playCarSvagEnterRoom(userInfo.getCarInfo().getEffect()); - } - // 公屏进入房间的提示语 - IMNetEaseManager.get() - .sendCarPlayRoomMsgBySdk(userInfo.getCarInfo(), userInfo.getUid(), userInfo.getNick()) - .subscribe(); - } - // 贵族人员,要先判断是否隐身 - if (userInfo.getNobleInfo() != null && !userInfo.getNobleInfo().isNobleEnterHide()) { - if (!mSvgaCar.isAnimating() && !isSvgaPlaying) { - // 播放座驾动画 - playCarSvagEnterRoom(userInfo.getCarInfo().getEffect()); - } - // 公屏进入房间的提示语 - IMNetEaseManager.get() - .sendCarPlayRoomMsgBySdk(userInfo.getCarInfo(), userInfo.getUid(), userInfo.getNick()) - .subscribe(); - } - } - }); - } else { - if (TextUtils.isEmpty(effect)) return; - if (AvRoomDataManager.get().mIsNeedGiftEffect) { - mCarEffectList.add(effect); - } - if (!mSvgaCar.isAnimating() && !isSvgaPlaying) { - playCarSvagEnterRoom(effect); - } - - } - } - - /** - * 真实播放svga - * - * @param effect - */ - private void playCarSvagEnterRoom(String effect) { - if (TextUtils.isEmpty(effect)) return; - if (!AvRoomDataManager.get().mIsNeedGiftEffect) return; - isSvgaPlaying = true; - try { - mSVGAParser.parse(new URL(effect), - new SVGAParser.ParseCompletion() { - @Override - public void onComplete(SVGAVideoEntity svgaVideoEntity) { - mSvgaCar.setVisibility(View.VISIBLE); - mSvgaCar.setLoops(1); - mSvgaCar.setClearsAfterStop(true); - mSvgaCar.setImageDrawable(new SVGADrawable(svgaVideoEntity)); - mSvgaCar.startAnimation(); - } - - @Override - public void onError() { - isSvgaPlaying = false; - mSvgaCar.setVisibility(View.GONE); - } - }); - } catch (MalformedURLException e) { - e.printStackTrace(); - isSvgaPlaying = false; - } - } - @Override public void onSetListener() { roomMore.setOnClickListener(this); @@ -401,34 +226,6 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi if (!AvRoomDataManager.get().haveSelfChange && AvRoomDataManager.get().mCurrentRoomInfo != null) { AvRoomDataManager.get().mIsNeedGiftEffect = AvRoomDataManager.get().mCurrentRoomInfo.isHasAnimationEffect(); } - //砸金蛋横幅通知这个订阅不能在onPause里面取消,单独写个... - IMNetEaseManager.get().getChatRoomEventObservable() - .compose(bindToLifecycle()) - .subscribe(roomEvent -> { - if (roomEvent == null) return; - int event = roomEvent.getEvent(); - switch (event) { - case RoomEvent.BOX_NOTIFY: - addBoxNotify(roomEvent.getChatRoomMessage()); - break; - case RoomEvent.BOX_NOTIFY_SVGA: - addBoxNotifyBySVGA(roomEvent.getChatRoomMessage()); - break; - case RoomEvent.RECEIVE_ROOM_LUCKY_BAG_NOTICE: - case RoomEvent.RECEIVE_SERVICE_LUCKY_BAG_NOTICE: - //全服福袋 - //厅内福袋 - addLuckyBagNotify(roomEvent.getChatRoomMessage()); - break; - case RoomEvent.DATING_PUBLISH_RESULT: - showHandAnim(((DatingAttachment) roomEvent.getChatRoomMessage().getAttachment()).getDatingNotifyInfo()); - break; - default: - break; - } - } - ); - subscribeGameEvent(); } @@ -484,9 +281,7 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi @Override public void onResume() { super.onResume(); - updateView(); - IMNetEaseManager.get().getChatRoomEventObservable() .compose(bindToLifecycle()) .subscribe(roomEvent -> { @@ -499,19 +294,7 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi } addTipMsg(); case RoomEvent.ROOM_INFO_UPDATE: - if (!isResumed()) return; updateView(); - if (event == RoomEvent.ENTER_ROOM) { - if (!SuperAdminUtil.isSuperAdmin()) { - playCarSvga(String.valueOf(AuthModel.get().getCurrentUid()), null, true); - } - } - break; - case RoomEvent.CAR_MEMBER_IN: - if (!isResumed()) return; - if (roomEvent.mRoomCarMsgAttachment != null) { - playCarSvga(null, roomEvent.mRoomCarMsgAttachment.effect, false); - } break; case RoomEvent.RECEIVE_NORMALE_GIFT: onReceiveGiftMsg(roomEvent.getGiftReceiveInfo()); @@ -534,14 +317,6 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi case RoomEvent.RECEIVED_ALL_MIC_MAGIC: onReceiveMultiMagicMsg(roomEvent.getMultiMagicReceivedInfo()); break; - case RoomEvent.RECEIVE_MEMBER_IN_NOTICE: - //进入房间 - if (!isResumed()) return; - addMemberInNotify(roomEvent.getChatRoomMessage()); - break; - case RoomEvent.RECEIVE_EXPER_LEVEL_UP_NOTICE: - addLevelUpNotify(roomEvent.getChatRoomMessage()); - break; default: break; } @@ -652,8 +427,6 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi break; case R.id.room_nums: case R.id.room_id: -// selectContent = SELECT_ONLINE_LIST; -// showListFragment(); RoomOnlineUserActivity.start(getActivity()); break; @@ -845,22 +618,11 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi @Override public void onDestroy() { - if (mSvgaCar.isAnimating()) { - mSvgaCar.clearAnimation(); - } if (giftView != null) { giftView.release(); } - EventBus.getDefault().unregister(this); - super.onDestroy(); - if (boxDisposable != null) boxDisposable.dispose(); - if (disposableLuckyGift != null) disposableLuckyGift.dispose(); - if (disposableMemberIn != null) disposableMemberIn.dispose(); - if (disposableLevelUp != null) disposableLevelUp.dispose(); - if (datingDisposable != null) datingDisposable.dispose(); - } @Override @@ -927,385 +689,6 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi giftView.onReceiveMultiMagicMsg(multiMagicReceivedInfo); } - private Animation animation; - private List messages; - private Disposable boxDisposable; - private boolean isCreate; - - private List messagesBoxSVGA; - private Disposable boxSVGADisposable; - private boolean isBoxSVGACreate; - - private Animation animationLuckyGift; - private List messagesLuckyGift; - private boolean isCreateLuckyGift; - private Disposable disposableLuckyGift; - - private List messagesMemberIn; - private boolean isCreateMemberIn; - private Disposable disposableMemberIn; - - private List messagesLevelUp; - private boolean isCreateLevelUp; - private Disposable disposableLevelUp; - - //顶部飘屏总展示时间 - private final int SHOW_TIME = 3500; - //顶部飘屏周期 - private final int PERIOD = 1000; - - /** - * 开福袋飘屏 - * - * @param chatRoomMessage - */ - private void addLuckyBagNotify(ChatRoomMessage chatRoomMessage) { - if (messagesLuckyGift == null) messagesLuckyGift = new ArrayList<>(); - if (gameMainBinding.clNotify.getVisibility() == View.GONE) { - gameMainBinding.clNotify.setVisibility(View.VISIBLE); - } - messagesLuckyGift.add(chatRoomMessage); - if (disposableLuckyGift == null || messagesLuckyGift.size() == 1) { - isCreateLuckyGift = true; - disposableLuckyGift = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(aLong -> { - if (messagesLuckyGift.size() > 0 && !isCreateLuckyGift) - messagesLuckyGift.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 - isCreateLuckyGift = false; - }) - .takeWhile(aLong -> messagesLuckyGift.size() > 0 && messagesLuckyGift.get(0) != null) - .subscribe(aLong -> showLuckyBagNotify(messagesLuckyGift.get(0))); - } - } - - private void showLuckyBagNotify(ChatRoomMessage message) { - RoomReceivedLuckyGiftAttachment attachment = (RoomReceivedLuckyGiftAttachment) message.getAttachment(); - TextView textView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.layout_room_lucky_gift_notify, null); - LuckyBagNoticeInfo noticeInfo = attachment.getLuckyBagNoticeInfo(); - if (noticeInfo == null) return; - SpannableBuilder text = new SpannableBuilder() - .append("哇偶! ", new ForegroundColorSpan(Color.WHITE)) - .append(noticeInfo.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) - .append("通过", new ForegroundColorSpan(Color.WHITE)) - .append(noticeInfo.getLuckyBagName() + " ", new ForegroundColorSpan(Color.WHITE)) - .append("开出了", new ForegroundColorSpan(Color.WHITE)) - .append(noticeInfo.getGiftName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))); - textView.setText(text.build()); - animationLuckyGift = AnimationUtils.loadAnimation(mContext, R.anim.anim_box_notify); - textView.startAnimation(animationLuckyGift); - gameMainBinding.flLuckyGiftNotify.postDelayed(() -> gameMainBinding.flLuckyGiftNotify.removeView(textView), SHOW_TIME); - - } - - /** - * 幸运池飘屏 - * - * @param chatRoomMessage - */ - private void addBoxNotify(ChatRoomMessage chatRoomMessage) { - if (messages == null) messages = new ArrayList<>(); - if (gameMainBinding.clNotify.getVisibility() == View.GONE) { - gameMainBinding.clNotify.setVisibility(View.VISIBLE); - } - messages.add(chatRoomMessage); - if (boxDisposable == null || messages.size() == 1) { - isCreate = true; - boxDisposable = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(aLong -> { - if (messages.size() > 0 && !isCreate) - messages.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 - isCreate = false; - }) - .takeWhile(aLong -> messages.size() > 0 && messages.get(0) != null) - .subscribe(aLong -> showBoxNotify(messages.get(0))); - } - } - - private void showBoxNotify(ChatRoomMessage chatRoomMessage) { - RoomBoxPrizeAttachment attachment = (RoomBoxPrizeAttachment) chatRoomMessage.getAttachment(); - TextView textView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.layout_room_box_notify, null); - SpannableBuilder text = new SpannableBuilder() - .append("厉害了! ", new ForegroundColorSpan(Color.WHITE)) - .append(attachment.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) - .append(attachment.getBoxTypeStr() + " ", new ForegroundColorSpan(Color.WHITE)) - .append(attachment.getPrizeName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))) - .append("x" + attachment.getPrizeNum(), new ForegroundColorSpan(Color.WHITE)); - textView.setText(text.build()); - animation = AnimationUtils.loadAnimation(mContext, R.anim.anim_box_notify); - gameMainBinding.flBoxNotify.addView(textView); - textView.startAnimation(animation); - gameMainBinding.flBoxNotify.postDelayed(() -> gameMainBinding.flBoxNotify.removeView(textView), SHOW_TIME); - } - - /** - * 幸运池飘屏 五级 SVGA背景的 - * - * @param chatRoomMessage - */ - private void addBoxNotifyBySVGA(ChatRoomMessage chatRoomMessage) { - if (messagesBoxSVGA == null) messagesBoxSVGA = new ArrayList<>(); - if (gameMainBinding.clNotify.getVisibility() == View.GONE) { - gameMainBinding.clNotify.setVisibility(View.VISIBLE); - } - messagesBoxSVGA.add(chatRoomMessage); - if (boxSVGADisposable == null || messagesBoxSVGA.size() == 1) { - isBoxSVGACreate = true; - boxSVGADisposable = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(aLong -> { - if (messagesBoxSVGA.size() > 0 && !isBoxSVGACreate) - messagesBoxSVGA.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 - isBoxSVGACreate = false; - }) - .takeWhile(aLong -> messagesBoxSVGA.size() > 0 && messagesBoxSVGA.get(0) != null) - .subscribe(aLong -> showBoxNotifyBySVGA(messagesBoxSVGA.get(0))); - } - } - - - private void showBoxNotifyBySVGA(ChatRoomMessage chatRoomMessage) { - RoomBoxPrizeAttachment attachment = (RoomBoxPrizeAttachment) chatRoomMessage.getAttachment(); - SpannableBuilder text = new SpannableBuilder() - .append("厉害了! ", new ForegroundColorSpan(Color.WHITE)) - .append(attachment.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) - .append(attachment.getBoxTypeStr() + " ", new ForegroundColorSpan(Color.WHITE)) - .append(attachment.getPrizeName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))) - .append("x" + attachment.getPrizeNum(), new ForegroundColorSpan(Color.WHITE)); - - SVGAImageView svgaImageView = new SVGAImageView(mContext); - svgaImageView.setLoops(1); - svgaImageView.setClearsAfterStop(true); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); - svgaImageView.setLayoutParams(params); - svgaImageView.setCallback(new SimpleSvgaCallback() { - @Override - public void onFinished() { - gameMainBinding.flSvgaBoxNotify.post(() -> gameMainBinding.flSvgaBoxNotify.removeView(svgaImageView)); - } - }); - gameMainBinding.flSvgaBoxNotify.addView(svgaImageView); - mSVGAParser.decodeFromAssets("svga/box_notify.svga", new SVGAParser.ParseCompletion() { - @Override - public void onComplete(@Nullable SVGAVideoEntity svgaVideoEntity) { - SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); - TextPaint textPaint = new TextPaint(); - textPaint.setColor(Color.WHITE);//字体颜色 - textPaint.setTextSize(24);//字体大小 - dynamicEntity.setDynamicText(new StaticLayout( - text.build(), - 0, - text.build().length(), - textPaint, - 0, - Layout.Alignment.ALIGN_CENTER, - 1.0f, - 0.0f, - false - ), "xtc_copywriting"); - SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); - svgaImageView.setImageDrawable(drawable); - svgaImageView.stepToFrame(0, true); - } - - @Override - public void onError() { - - } - }); - } - - /** - * 成员进入飘屏 - * - * @param chatRoomMessage - */ - private void addMemberInNotify(ChatRoomMessage chatRoomMessage) { - if (messagesMemberIn == null) messagesMemberIn = new ArrayList<>(); - messagesMemberIn.add(chatRoomMessage); - if (disposableMemberIn == null || messagesMemberIn.size() == 1) { - isCreateMemberIn = true; - disposableMemberIn = Observable.interval(0, 6, TimeUnit.SECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(aLong -> { - if (messagesMemberIn.size() > 0 && !isCreateMemberIn) - messagesMemberIn.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 - isCreateMemberIn = false; - }) - .takeWhile(aLong -> messagesMemberIn.size() > 0 && messagesMemberIn.get(0) != null) - .subscribe(aLong -> showMemberInNotify(messagesMemberIn.get(0))); - } - } - - private void showMemberInNotify(ChatRoomMessage chatRoomMessage) { - ChatRoomNotificationAttachment attachment = (ChatRoomNotificationAttachment) chatRoomMessage.getAttachment(); - Map remoteExtension = chatRoomMessage.getRemoteExtension(); - int experLevelSeq = (int) remoteExtension.get("experLevelSeq"); - List targetNicks = attachment.getTargetNicks(); - if (ListUtils.isListEmpty(targetNicks)) { - return; - } - int fromType = (int) remoteExtension.get("fromType"); - String fromNick = (String) remoteExtension.get("fromNick"); - - SuperTextView textView = (SuperTextView) LayoutInflater.from(mContext).inflate(R.layout.layout_member_in_notify, null); - // 内容 - MessageView.SpannableBuilder text = new MessageView.SpannableBuilder(textView) - .append(targetNicks.get(0), new ForegroundColorSpan(Color.WHITE)); - String enterText = " 进入了房间 "; - if (fromType == AVRoomActivity.FROM_TYPE_RECOMMEND) { - enterText = " 根据首页推荐进入了房间"; - } - if (fromType == AVRoomActivity.FROM_TYPE_USER) { - enterText = " 跟随 " + fromNick + "进入了房间"; - } - text.append(enterText, new ForegroundColorSpan(Color.WHITE)); - textView.setText(text.build()); - playMemberInAnim("【" + targetNicks.get(0) + "】" + enterText, memberInSvgaPath(experLevelSeq)); - } - - private String memberInSvgaPath(int level) { - String path = ""; - if (level >= 30 && level <= 39) { - path = "svga/svga_member_in_lv30.svga"; - } else if (level >= 40 && level <= 49) { - path = "svga/svga_member_in_lv40.svga"; - } else if (level >= 50 && level <= 59) { - path = "svga/svga_member_in_lv50.svga"; - } else if (level >= 60 && level <= 69) { - path = "svga/svga_member_in_lv60.svga"; - } else if (level >= 70 && level <= 79) { - path = "svga/svga_member_in_lv70.svga"; - } else if (level >= 80 && level <= 89) { - path = "svga/svga_member_in_lv80.svga"; - } else if (level >= 90) { - path = "svga/svga_member_in_lv90.svga"; - } - return path; - } - - private void playMemberInAnim(String text, String path) { - mSVGAParser.decodeFromAssets(path, new SVGAParser.ParseCompletion() { - @Override - public void onComplete(@Nullable SVGAVideoEntity svgaVideoEntity) { - mSvgaMemberIn.setVisibility(View.VISIBLE); - mSvgaMemberIn.setLoops(1); - mSvgaMemberIn.setClearsAfterStop(true); - SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); - TextPaint textPaint = new TextPaint(); - textPaint.setColor(Color.WHITE);//字体颜色 - textPaint.setTextSize(22);//字体大小 - dynamicEntity.setDynamicText(new StaticLayout( - text, - 0, - text.length(), - textPaint, - 0, - Layout.Alignment.ALIGN_NORMAL, - 1.0f, - 0.0f, - false - ), "room_text"); - SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); - mSvgaMemberIn.setImageDrawable(drawable); - mSvgaMemberIn.stepToFrame(0, true); - } - - @Override - public void onError() { - - } - }); - } - - - /** - * 升级飘屏 - * - * @param chatRoomMessage - */ - private void addLevelUpNotify(ChatRoomMessage chatRoomMessage) { - if (messagesLevelUp == null) messagesLevelUp = new ArrayList<>(); - messagesLevelUp.add(chatRoomMessage); - if (disposableLevelUp == null || messagesLevelUp.size() == 1) { - isCreateLevelUp = true; - disposableLevelUp = Observable.interval(0, 6, TimeUnit.SECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(aLong -> { - if (messagesLevelUp.size() > 0 && !isCreateLevelUp) - messagesLevelUp.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 - isCreateLevelUp = false; - }) - .takeWhile(aLong -> messagesLevelUp.size() > 0 && messagesLevelUp.get(0) != null) - .subscribe(aLong -> showLevelUpNotify(messagesLevelUp.get(0))); - } - } - - private void showLevelUpNotify(ChatRoomMessage chatRoomMessage) { - LevelUpNoticeAttachment attachment = (LevelUpNoticeAttachment) chatRoomMessage.getAttachment(); - String message = attachment.getMessage(); - String picUrl = attachment.getPicUrl(); - long roomUid = attachment.getRoomUid(); - if (picUrl == null || message == null) { - return; - } - playLevelUpAnim(message, picUrl, roomUid); - } - - private void playLevelUpAnim(String message, String picUrl, long roomUid) { - try { - mSVGAParser.decodeFromURL(new URL(picUrl), new SVGAParser.ParseCompletion() { - @Override - public void onComplete(@javax.annotation.Nullable SVGAVideoEntity svgaVideoEntity) { - if (svgaVideoEntity == null) return; - mSvgaLevelUp.setVisibility(View.VISIBLE); - mSvgaLevelUp.setLoops(1); - mSvgaLevelUp.setClearsAfterStop(true); - SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); - TextPaint textPaint = new TextPaint(); - textPaint.setColor(Color.WHITE);//字体颜色 - textPaint.setTextSize(22);//字体大小 Util.dip2px(mContext,11) -// textPaint.setShadowLayer(3, 2, 2, 0xff000000);//字体阴影,不需要可以不用设置 - dynamicEntity.setDynamicText(message, textPaint, "y_yhname"); - SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); - mSvgaLevelUp.setImageDrawable(drawable); - mSvgaLevelUp.stepToFrame(0, true); - mSvgaLevelUp.setCallback(new SVGACallback() { - @Override - public void onPause() { - - } - - @Override - public void onFinished() { - mSvgaLevelUp.setVisibility(View.GONE); - } - - @Override - public void onRepeat() { - - } - - @Override - public void onStep(int i, double v) { - - } - }); - } - - @Override - public void onError() { - - } - }); - mSvgaLevelUp.setOnClickListener(v -> - AVRoomActivity.start(mContext, roomUid)); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - @SuppressLint("CheckResult") public void showKtvBox() { GoldBoxHelper.isHideBox().subscribe(hide -> { @@ -1370,74 +753,4 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi gameMainBinding.roomNums.setText("在线" + onlineNumber); } - @SuppressLint({"SetTextI18n"}) - private void showHandAnim(final DatingNotifyInfo datingNotifyInfo) { - if (datingDisposable != null) datingDisposable.dispose(); - gameMainBinding.flSvgaDating.setOnClickListener(v -> { - //do noting - }); - gameMainBinding.ivDatingSvgaClose.setOnClickListener(v -> { - gameMainBinding.flSvgaDating.setVisibility(View.GONE); - if (datingDisposable != null) datingDisposable.dispose(); - }); - gameMainBinding.flSvgaDating.post(() -> gameMainBinding.flSvgaDating.setVisibility(View.GONE)); - datingDisposable = Single.just(datingNotifyInfo) - .compose(bindToLifecycle()) - .observeOn(AndroidSchedulers.mainThread()) - .flatMap(info -> { - if (datingNotifyInfo.getHasSelectUser() && !datingNotifyInfo.getHasHeart()) { - showHeartAnim(datingNotifyInfo.getPosition(), datingNotifyInfo.getTargetPosition()); - return Single.timer(SELECT_ANIM_DURATION, TimeUnit.MILLISECONDS).map(aLong -> info); - } - return Single.just(info); - }) - .observeOn(AndroidSchedulers.mainThread()) - .filter(info -> datingNotifyInfo.getHasHeart()) - .toObservable() - .flatMap(info -> Observable.create((ObservableOnSubscribe) emitter -> - SVGAParser.Companion.shareParser().decodeFromURL(new URL(datingNotifyInfo.getSvgaUrl()), new SVGAParser.ParseCompletion() { - - @Override - public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { - gameMainBinding.flSvgaDating.setVisibility(View.VISIBLE); - gameMainBinding.llDatingSvgaTime.setVisibility(View.GONE); - SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); - TextPaint textPaint = new TextPaint(); - textPaint.setColor(Color.WHITE); - textPaint.setTextSize(ScreenUtil.sp2px(10)); - AnimHelper.addDynamicImage(gameMainBinding.svgaDating, dynamicEntity, datingNotifyInfo.getAvatar(), "z_tx"); - AnimHelper.addDynamicImage(gameMainBinding.svgaDating, dynamicEntity, datingNotifyInfo.getTargetAvatar(), "y_tx"); - dynamicEntity.setDynamicText(StringExtensionKt.subAndReplaceDot(datingNotifyInfo.getNickname(), 5), textPaint, "z_yhname"); - dynamicEntity.setDynamicText(StringExtensionKt.subAndReplaceDot(datingNotifyInfo.getTargetNickname(), 5), textPaint, "y_yhname"); - SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); - gameMainBinding.svgaDating.setImageDrawable(drawable); - gameMainBinding.svgaDating.startAnimation(); - emitter.onNext(info); - emitter.onComplete(); - } - - @Override - public void onError() { - emitter.onError(new Throwable("svga解析失败")); - } - }))) - .flatMap(info -> Observable.intervalRange(1, info.getSvgaSecond(), 1, 1, TimeUnit.SECONDS)) - .observeOn(AndroidSchedulers.mainThread()) - .doAfterTerminate(() -> gameMainBinding.flSvgaDating.setVisibility(View.GONE)) - .subscribe(aLong -> { - long residueTime = datingNotifyInfo.getSvgaSecond() - aLong; - gameMainBinding.tvDatingSecond.setText(residueTime + "S"); - if (residueTime == 5) {//剩余5秒开始显示倒计时 - gameMainBinding.llDatingSvgaTime.setVisibility(View.VISIBLE); - } - }); - } - - public void showHeartAnim(int position, int targetPosition) { - SparseArray micViewPoint = AvRoomDataManager.get().mMicPointMap; - AnimHelper.showDatingSelectUserAnim(getContext(), - (ViewGroup) gameMainBinding.getRoot(), - micViewPoint.get(position), - micViewPoint.get(targetPosition)); - } } \ No newline at end of file diff --git a/app/src/main/java/com/yizhuan/erban/avroom/widget/RoomEffectView.java b/app/src/main/java/com/yizhuan/erban/avroom/widget/RoomEffectView.java new file mode 100644 index 000000000..67286363e --- /dev/null +++ b/app/src/main/java/com/yizhuan/erban/avroom/widget/RoomEffectView.java @@ -0,0 +1,690 @@ +package com.yizhuan.erban.avroom.widget; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Point; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; + +import com.coorchice.library.SuperTextView; +import com.netease.nim.uikit.common.util.sys.ScreenUtil; +import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage; +import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment; +import com.opensource.svgaplayer.SVGACallback; +import com.opensource.svgaplayer.SVGADrawable; +import com.opensource.svgaplayer.SVGADynamicEntity; +import com.opensource.svgaplayer.SVGAImageView; +import com.opensource.svgaplayer.SVGAParser; +import com.opensource.svgaplayer.SVGAVideoEntity; +import com.yizhuan.erban.R; +import com.yizhuan.erban.avroom.activity.AVRoomActivity; +import com.yizhuan.erban.avroom.helper.AnimHelper; +import com.yizhuan.erban.common.svga.SimpleSvgaCallback; +import com.yizhuan.erban.databinding.LayoutRoomEffectBinding; +import com.yizhuan.erban.utils.SpannableBuilder; +import com.yizhuan.xchat_android_core.auth.AuthModel; +import com.yizhuan.xchat_android_core.decoration.car.bean.CarInfo; +import com.yizhuan.xchat_android_core.gift.bean.LuckyBagNoticeInfo; +import com.yizhuan.xchat_android_core.im.custom.bean.DatingAttachment; +import com.yizhuan.xchat_android_core.im.custom.bean.LevelUpNoticeAttachment; +import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeAttachment; +import com.yizhuan.xchat_android_core.im.custom.bean.RoomReceivedLuckyGiftAttachment; +import com.yizhuan.xchat_android_core.manager.AvRoomDataManager; +import com.yizhuan.xchat_android_core.manager.IMNetEaseManager; +import com.yizhuan.xchat_android_core.manager.RoomEvent; +import com.yizhuan.xchat_android_core.room.bean.DatingNotifyInfo; +import com.yizhuan.xchat_android_core.super_admin.util.SuperAdminUtil; +import com.yizhuan.xchat_android_core.user.UserModel; +import com.yizhuan.xchat_android_core.utils.StringExtensionKt; +import com.yizhuan.xchat_android_library.utils.ListUtils; + +import org.jetbrains.annotations.NotNull; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.Single; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; + +import static com.yizhuan.xchat_android_constants.XChatConstants.SELECT_ANIM_DURATION; + +/** + * 房间特效View(座驾,心动场景,飘屏等) + */ +public class RoomEffectView extends FrameLayout { + + private boolean isSvgaPlaying; + private final List mCarEffectList = new ArrayList<>(); + + private Animation animation; + private List messages; + private Disposable boxDisposable; + private boolean isCreate; + + private List messagesBoxSVGA; + private Disposable boxSVGADisposable; + private boolean isBoxSVGACreate; + + private Animation animationLuckyGift; + private List messagesLuckyGift; + private boolean isCreateLuckyGift; + private Disposable disposableLuckyGift; + + private List messagesMemberIn; + private boolean isCreateMemberIn; + private Disposable disposableMemberIn; + + private List messagesLevelUp; + private boolean isCreateLevelUp; + private Disposable disposableLevelUp; + + //顶部飘屏总展示时间 + private final int SHOW_TIME = 3500; + //顶部飘屏周期 + private final int PERIOD = 1000; + + private final LayoutRoomEffectBinding binding; + private final Context mContext; + private final Disposable imDisposable; + private Disposable datingDisposable; + + public RoomEffectView(@NonNull Context context) { + this(context, null); + } + + public RoomEffectView(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public RoomEffectView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mContext = context; + binding = LayoutRoomEffectBinding.inflate(LayoutInflater.from(context), this, true); + imDisposable = IMNetEaseManager.get().getChatRoomEventObservable() + .subscribe(roomEvent -> { + if (roomEvent == null) return; + int event = roomEvent.getEvent(); + switch (event) { + case RoomEvent.BOX_NOTIFY: + addBoxNotify(roomEvent.getChatRoomMessage()); + break; + case RoomEvent.BOX_NOTIFY_SVGA: + addBoxNotifyBySVGA(roomEvent.getChatRoomMessage()); + break; + case RoomEvent.RECEIVE_ROOM_LUCKY_BAG_NOTICE: + case RoomEvent.RECEIVE_SERVICE_LUCKY_BAG_NOTICE: + //全服福袋 + //厅内福袋 + addLuckyBagNotify(roomEvent.getChatRoomMessage()); + break; + case RoomEvent.DATING_PUBLISH_RESULT: + showHandAnim(((DatingAttachment) roomEvent.getChatRoomMessage().getAttachment()).getDatingNotifyInfo()); + break; + case RoomEvent.RECEIVE_MEMBER_IN_NOTICE: + //进入房间 + addMemberInNotify(roomEvent.getChatRoomMessage()); + break; + case RoomEvent.RECEIVE_EXPER_LEVEL_UP_NOTICE: + addLevelUpNotify(roomEvent.getChatRoomMessage()); + break; + case RoomEvent.ENTER_ROOM: + if (!SuperAdminUtil.isSuperAdmin()) { + playCarSvga(String.valueOf(AuthModel.get().getCurrentUid()), null, true); + } + break; + case RoomEvent.CAR_MEMBER_IN: + if (roomEvent.mRoomCarMsgAttachment != null) { + playCarSvga(null, roomEvent.mRoomCarMsgAttachment.effect, false); + } + break; + default: + break; + } + } + ); + + binding.roomCarSvga.setCallback(new SimpleSvgaCallback() { + + @Override + public void onFinished() { + isSvgaPlaying = false; + if (ListUtils.isListEmpty(mCarEffectList)) { + binding.roomCarSvga.setVisibility(View.GONE); + return; + } + mCarEffectList.remove(0); + if (!ListUtils.isListEmpty(mCarEffectList)) { + playCarSvagEnterRoom(mCarEffectList.get(0)); + } + } + + }); + } + + + /** + * 开福袋飘屏 + * + * @param chatRoomMessage + */ + private void addLuckyBagNotify(ChatRoomMessage chatRoomMessage) { + if (messagesLuckyGift == null) messagesLuckyGift = new ArrayList<>(); + if (binding.clNotify.getVisibility() == View.GONE) { + binding.clNotify.setVisibility(View.VISIBLE); + } + messagesLuckyGift.add(chatRoomMessage); + if (disposableLuckyGift == null || messagesLuckyGift.size() == 1) { + isCreateLuckyGift = true; + disposableLuckyGift = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(aLong -> { + if (messagesLuckyGift.size() > 0 && !isCreateLuckyGift) + messagesLuckyGift.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 + isCreateLuckyGift = false; + }) + .takeWhile(aLong -> messagesLuckyGift.size() > 0 && messagesLuckyGift.get(0) != null) + .subscribe(aLong -> showLuckyBagNotify(messagesLuckyGift.get(0))); + } + } + + private void showLuckyBagNotify(ChatRoomMessage message) { + RoomReceivedLuckyGiftAttachment attachment = (RoomReceivedLuckyGiftAttachment) message.getAttachment(); + TextView textView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.layout_room_lucky_gift_notify, null); + LuckyBagNoticeInfo noticeInfo = attachment.getLuckyBagNoticeInfo(); + if (noticeInfo == null) return; + SpannableBuilder text = new SpannableBuilder() + .append("哇偶! ", new ForegroundColorSpan(Color.WHITE)) + .append(noticeInfo.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) + .append("通过", new ForegroundColorSpan(Color.WHITE)) + .append(noticeInfo.getLuckyBagName() + " ", new ForegroundColorSpan(Color.WHITE)) + .append("开出了", new ForegroundColorSpan(Color.WHITE)) + .append(noticeInfo.getGiftName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))); + textView.setText(text.build()); + animationLuckyGift = AnimationUtils.loadAnimation(mContext, R.anim.anim_box_notify); + textView.startAnimation(animationLuckyGift); + binding.flLuckyGiftNotify.postDelayed(() -> binding.flLuckyGiftNotify.removeView(textView), SHOW_TIME); + + } + + /** + * 幸运池飘屏 + * + * @param chatRoomMessage + */ + private void addBoxNotify(ChatRoomMessage chatRoomMessage) { + if (messages == null) messages = new ArrayList<>(); + if (binding.clNotify.getVisibility() == View.GONE) { + binding.clNotify.setVisibility(View.VISIBLE); + } + messages.add(chatRoomMessage); + if (boxDisposable == null || messages.size() == 1) { + isCreate = true; + boxDisposable = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(aLong -> { + if (messages.size() > 0 && !isCreate) + messages.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 + isCreate = false; + }) + .takeWhile(aLong -> messages.size() > 0 && messages.get(0) != null) + .subscribe(aLong -> showBoxNotify(messages.get(0))); + } + } + + private void showBoxNotify(ChatRoomMessage chatRoomMessage) { + RoomBoxPrizeAttachment attachment = (RoomBoxPrizeAttachment) chatRoomMessage.getAttachment(); + TextView textView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.layout_room_box_notify, null); + SpannableBuilder text = new SpannableBuilder() + .append("厉害了! ", new ForegroundColorSpan(Color.WHITE)) + .append(attachment.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) + .append(attachment.getBoxTypeStr() + " ", new ForegroundColorSpan(Color.WHITE)) + .append(attachment.getPrizeName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))) + .append("x" + attachment.getPrizeNum(), new ForegroundColorSpan(Color.WHITE)); + textView.setText(text.build()); + animation = AnimationUtils.loadAnimation(mContext, R.anim.anim_box_notify); + binding.flBoxNotify.addView(textView); + textView.startAnimation(animation); + binding.flBoxNotify.postDelayed(() -> binding.flBoxNotify.removeView(textView), SHOW_TIME); + } + + /** + * 幸运池飘屏 五级 SVGA背景的 + * + * @param chatRoomMessage + */ + private void addBoxNotifyBySVGA(ChatRoomMessage chatRoomMessage) { + if (messagesBoxSVGA == null) messagesBoxSVGA = new ArrayList<>(); + if (binding.clNotify.getVisibility() == View.GONE) { + binding.clNotify.setVisibility(View.VISIBLE); + } + messagesBoxSVGA.add(chatRoomMessage); + if (boxSVGADisposable == null || messagesBoxSVGA.size() == 1) { + isBoxSVGACreate = true; + boxSVGADisposable = Observable.interval(0, PERIOD, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(aLong -> { + if (messagesBoxSVGA.size() > 0 && !isBoxSVGACreate) + messagesBoxSVGA.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 + isBoxSVGACreate = false; + }) + .takeWhile(aLong -> messagesBoxSVGA.size() > 0 && messagesBoxSVGA.get(0) != null) + .subscribe(aLong -> showBoxNotifyBySVGA(messagesBoxSVGA.get(0))); + } + } + + + private void showBoxNotifyBySVGA(ChatRoomMessage chatRoomMessage) { + RoomBoxPrizeAttachment attachment = (RoomBoxPrizeAttachment) chatRoomMessage.getAttachment(); + SpannableBuilder text = new SpannableBuilder() + .append("厉害了! ", new ForegroundColorSpan(Color.WHITE)) + .append(attachment.getNick() + " ", new ForegroundColorSpan(getResources().getColor(R.color.notice_nick))) + .append(attachment.getBoxTypeStr() + " ", new ForegroundColorSpan(Color.WHITE)) + .append(attachment.getPrizeName(), new ForegroundColorSpan(getResources().getColor(R.color.notice_gift))) + .append("x" + attachment.getPrizeNum(), new ForegroundColorSpan(Color.WHITE)); + + SVGAImageView svgaImageView = new SVGAImageView(mContext); + svgaImageView.setLoops(1); + svgaImageView.setClearsAfterStop(true); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); + svgaImageView.setLayoutParams(params); + svgaImageView.setCallback(new SimpleSvgaCallback() { + @Override + public void onFinished() { + binding.flSvgaBoxNotify.post(() -> binding.flSvgaBoxNotify.removeView(svgaImageView)); + } + }); + binding.flSvgaBoxNotify.addView(svgaImageView); + SVGAParser.Companion.shareParser().decodeFromAssets("svga/box_notify.svga", new SVGAParser.ParseCompletion() { + @Override + public void onComplete(@Nullable SVGAVideoEntity svgaVideoEntity) { + SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); + TextPaint textPaint = new TextPaint(); + textPaint.setColor(Color.WHITE);//字体颜色 + textPaint.setTextSize(24);//字体大小 + dynamicEntity.setDynamicText(new StaticLayout( + text.build(), + 0, + text.build().length(), + textPaint, + 0, + Layout.Alignment.ALIGN_CENTER, + 1.0f, + 0.0f, + false + ), "xtc_copywriting"); + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); + svgaImageView.setImageDrawable(drawable); + svgaImageView.stepToFrame(0, true); + } + + @Override + public void onError() { + + } + }); + } + + /** + * 成员进入飘屏 + * + * @param chatRoomMessage + */ + private void addMemberInNotify(ChatRoomMessage chatRoomMessage) { + if (messagesMemberIn == null) messagesMemberIn = new ArrayList<>(); + messagesMemberIn.add(chatRoomMessage); + if (disposableMemberIn == null || messagesMemberIn.size() == 1) { + isCreateMemberIn = true; + disposableMemberIn = Observable.interval(0, 6, TimeUnit.SECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(aLong -> { + if (messagesMemberIn.size() > 0 && !isCreateMemberIn) + messagesMemberIn.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 + isCreateMemberIn = false; + }) + .takeWhile(aLong -> messagesMemberIn.size() > 0 && messagesMemberIn.get(0) != null) + .subscribe(aLong -> showMemberInNotify(messagesMemberIn.get(0))); + } + } + + private void showMemberInNotify(ChatRoomMessage chatRoomMessage) { + ChatRoomNotificationAttachment attachment = (ChatRoomNotificationAttachment) chatRoomMessage.getAttachment(); + Map remoteExtension = chatRoomMessage.getRemoteExtension(); + int experLevelSeq = (int) remoteExtension.get("experLevelSeq"); + List targetNicks = attachment.getTargetNicks(); + if (ListUtils.isListEmpty(targetNicks)) { + return; + } + int fromType = (int) remoteExtension.get("fromType"); + String fromNick = (String) remoteExtension.get("fromNick"); + + SuperTextView textView = (SuperTextView) LayoutInflater.from(mContext).inflate(R.layout.layout_member_in_notify, null); + // 内容 + MessageView.SpannableBuilder text = new MessageView.SpannableBuilder(textView) + .append(targetNicks.get(0), new ForegroundColorSpan(Color.WHITE)); + String enterText = " 进入了房间 "; + if (fromType == AVRoomActivity.FROM_TYPE_RECOMMEND) { + enterText = " 根据首页推荐进入了房间"; + } + if (fromType == AVRoomActivity.FROM_TYPE_USER) { + enterText = " 跟随 " + fromNick + "进入了房间"; + } + text.append(enterText, new ForegroundColorSpan(Color.WHITE)); + textView.setText(text.build()); + playMemberInAnim("【" + targetNicks.get(0) + "】" + enterText, memberInSvgaPath(experLevelSeq)); + } + + private String memberInSvgaPath(int level) { + String path = ""; + if (level >= 30 && level <= 39) { + path = "svga/svga_member_in_lv30.svga"; + } else if (level >= 40 && level <= 49) { + path = "svga/svga_member_in_lv40.svga"; + } else if (level >= 50 && level <= 59) { + path = "svga/svga_member_in_lv50.svga"; + } else if (level >= 60 && level <= 69) { + path = "svga/svga_member_in_lv60.svga"; + } else if (level >= 70 && level <= 79) { + path = "svga/svga_member_in_lv70.svga"; + } else if (level >= 80 && level <= 89) { + path = "svga/svga_member_in_lv80.svga"; + } else if (level >= 90) { + path = "svga/svga_member_in_lv90.svga"; + } + return path; + } + + private void playMemberInAnim(String text, String path) { + SVGAParser.Companion.shareParser().decodeFromAssets(path, new SVGAParser.ParseCompletion() { + @Override + public void onComplete(@Nullable SVGAVideoEntity svgaVideoEntity) { + binding.roomMenberInSvga.setVisibility(View.VISIBLE); + binding.roomMenberInSvga.setLoops(1); + binding.roomMenberInSvga.setClearsAfterStop(true); + SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); + TextPaint textPaint = new TextPaint(); + textPaint.setColor(Color.WHITE);//字体颜色 + textPaint.setTextSize(22);//字体大小 + dynamicEntity.setDynamicText(new StaticLayout( + text, + 0, + text.length(), + textPaint, + 0, + Layout.Alignment.ALIGN_NORMAL, + 1.0f, + 0.0f, + false + ), "room_text"); + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); + binding.roomMenberInSvga.setImageDrawable(drawable); + binding.roomMenberInSvga.stepToFrame(0, true); + } + + @Override + public void onError() { + + } + }); + } + + + /** + * 升级飘屏 + * + * @param chatRoomMessage + */ + private void addLevelUpNotify(ChatRoomMessage chatRoomMessage) { + if (messagesLevelUp == null) messagesLevelUp = new ArrayList<>(); + messagesLevelUp.add(chatRoomMessage); + if (disposableLevelUp == null || messagesLevelUp.size() == 1) { + isCreateLevelUp = true; + disposableLevelUp = Observable.interval(0, 6, TimeUnit.SECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(aLong -> { + if (messagesLevelUp.size() > 0 && !isCreateLevelUp) + messagesLevelUp.remove(0);//如果不是新创建的Observable发送的数据,需要移除第一个 + isCreateLevelUp = false; + }) + .takeWhile(aLong -> messagesLevelUp.size() > 0 && messagesLevelUp.get(0) != null) + .subscribe(aLong -> showLevelUpNotify(messagesLevelUp.get(0))); + } + } + + private void showLevelUpNotify(ChatRoomMessage chatRoomMessage) { + LevelUpNoticeAttachment attachment = (LevelUpNoticeAttachment) chatRoomMessage.getAttachment(); + String message = attachment.getMessage(); + String picUrl = attachment.getPicUrl(); + long roomUid = attachment.getRoomUid(); + if (picUrl == null || message == null) { + return; + } + playLevelUpAnim(message, picUrl, roomUid); + } + + private void playLevelUpAnim(String message, String picUrl, long roomUid) { + try { + SVGAParser.Companion.shareParser().decodeFromURL(new URL(picUrl), new SVGAParser.ParseCompletion() { + @Override + public void onComplete(@javax.annotation.Nullable SVGAVideoEntity svgaVideoEntity) { + if (svgaVideoEntity == null) return; + binding.roomLevelUpSvga.setVisibility(View.VISIBLE); + binding.roomLevelUpSvga.setLoops(1); + binding.roomLevelUpSvga.setClearsAfterStop(true); + SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); + TextPaint textPaint = new TextPaint(); + textPaint.setColor(Color.WHITE);//字体颜色 + textPaint.setTextSize(22);//字体大小 Util.dip2px(mContext,11) +// textPaint.setShadowLayer(3, 2, 2, 0xff000000);//字体阴影,不需要可以不用设置 + dynamicEntity.setDynamicText(message, textPaint, "y_yhname"); + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); + binding.roomLevelUpSvga.setImageDrawable(drawable); + binding.roomLevelUpSvga.stepToFrame(0, true); + binding.roomLevelUpSvga.setCallback(new SimpleSvgaCallback() { + @Override + public void onFinished() { + binding.roomLevelUpSvga.setVisibility(View.GONE); + } + }); + } + + @Override + public void onError() { + + } + }); + binding.roomLevelUpSvga.setOnClickListener(v -> + AVRoomActivity.start(mContext, roomUid)); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + + @SuppressLint({"SetTextI18n"}) + private void showHandAnim(final DatingNotifyInfo datingNotifyInfo) { + if (datingDisposable != null) datingDisposable.dispose(); + binding.flSvgaDating.setOnClickListener(v -> { + //do noting + }); + binding.ivDatingSvgaClose.setOnClickListener(v -> { + binding.flSvgaDating.setVisibility(View.GONE); + if (datingDisposable != null) datingDisposable.dispose(); + }); + binding.flSvgaDating.post(() -> binding.flSvgaDating.setVisibility(View.GONE)); + datingDisposable = Single.just(datingNotifyInfo) + .observeOn(AndroidSchedulers.mainThread()) + .flatMap(info -> { + if (datingNotifyInfo.getHasSelectUser() && !datingNotifyInfo.getHasHeart()) { + showHeartAnim(datingNotifyInfo.getPosition(), datingNotifyInfo.getTargetPosition()); + return Single.timer(SELECT_ANIM_DURATION, TimeUnit.MILLISECONDS).map(aLong -> info); + } + return Single.just(info); + }) + .observeOn(AndroidSchedulers.mainThread()) + .filter(info -> datingNotifyInfo.getHasHeart()) + .toObservable() + .flatMap(info -> Observable.create((ObservableOnSubscribe) emitter -> + SVGAParser.Companion.shareParser().decodeFromURL(new URL(datingNotifyInfo.getSvgaUrl()), new SVGAParser.ParseCompletion() { + + @Override + public void onComplete(@NotNull SVGAVideoEntity svgaVideoEntity) { + binding.flSvgaDating.setVisibility(View.VISIBLE); + binding.llDatingSvgaTime.setVisibility(View.GONE); + SVGADynamicEntity dynamicEntity = new SVGADynamicEntity(); + TextPaint textPaint = new TextPaint(); + textPaint.setColor(Color.WHITE); + textPaint.setTextSize(ScreenUtil.sp2px(10)); + AnimHelper.addDynamicImage(binding.svgaDating, dynamicEntity, datingNotifyInfo.getAvatar(), "z_tx"); + AnimHelper.addDynamicImage(binding.svgaDating, dynamicEntity, datingNotifyInfo.getTargetAvatar(), "y_tx"); + dynamicEntity.setDynamicText(StringExtensionKt.subAndReplaceDot(datingNotifyInfo.getNickname(), 5), textPaint, "z_yhname"); + dynamicEntity.setDynamicText(StringExtensionKt.subAndReplaceDot(datingNotifyInfo.getTargetNickname(), 5), textPaint, "y_yhname"); + SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity); + binding.svgaDating.setImageDrawable(drawable); + binding.svgaDating.startAnimation(); + emitter.onNext(info); + emitter.onComplete(); + } + + @Override + public void onError() { + emitter.onError(new Throwable("svga解析失败")); + } + }))) + .flatMap(info -> Observable.intervalRange(1, info.getSvgaSecond(), 1, 1, TimeUnit.SECONDS)) + .observeOn(AndroidSchedulers.mainThread()) + .doAfterTerminate(() -> binding.flSvgaDating.setVisibility(View.GONE)) + .subscribe(aLong -> { + long residueTime = datingNotifyInfo.getSvgaSecond() - aLong; + binding.tvDatingSecond.setText(residueTime + "S"); + if (residueTime == 5) {//剩余5秒开始显示倒计时 + binding.llDatingSvgaTime.setVisibility(View.VISIBLE); + } + }); + } + + public void showHeartAnim(int position, int targetPosition) { + SparseArray micViewPoint = AvRoomDataManager.get().mMicPointMap; + AnimHelper.showDatingSelectUserAnim(getContext(), + (ViewGroup) binding.getRoot(), + micViewPoint.get(position), + micViewPoint.get(targetPosition)); + } + + @SuppressLint("CheckResult") + private void playCarSvga(String account, String effect, boolean isSendMsg) { + if (isSendMsg) { + UserModel.get().getUserInfoFromServer(Long.valueOf(account)) + .subscribe(userInfo -> { + //播放座驾动效 + if (userInfo != null + && userInfo.getCarInfo() != null + && userInfo.getCarInfo().isUsing() + && userInfo.getCarInfo().getStatus() == CarInfo.STATUS_USER_CAN_USE) { + if (AvRoomDataManager.get().mIsNeedGiftEffect) { + mCarEffectList.add(userInfo.getCarInfo().getEffect()); + } + // 非贵族人员,进来后要播放座驾动画 + if (userInfo.getNobleInfo() == null) { + if (!binding.roomCarSvga.isAnimating() && !isSvgaPlaying) { + // 播放座驾动画 + playCarSvagEnterRoom(userInfo.getCarInfo().getEffect()); + } + // 公屏进入房间的提示语 + IMNetEaseManager.get() + .sendCarPlayRoomMsgBySdk(userInfo.getCarInfo(), userInfo.getUid(), userInfo.getNick()) + .subscribe(); + } + // 贵族人员,要先判断是否隐身 + if (userInfo.getNobleInfo() != null && !userInfo.getNobleInfo().isNobleEnterHide()) { + if (!binding.roomCarSvga.isAnimating() && !isSvgaPlaying) { + // 播放座驾动画 + playCarSvagEnterRoom(userInfo.getCarInfo().getEffect()); + } + // 公屏进入房间的提示语 + IMNetEaseManager.get() + .sendCarPlayRoomMsgBySdk(userInfo.getCarInfo(), userInfo.getUid(), userInfo.getNick()) + .subscribe(); + } + } + }); + } else { + if (TextUtils.isEmpty(effect)) return; + if (AvRoomDataManager.get().mIsNeedGiftEffect) { + mCarEffectList.add(effect); + } + if (!binding.roomCarSvga.isAnimating() && !isSvgaPlaying) { + playCarSvagEnterRoom(effect); + } + + } + } + + /** + * 真实播放svga + * + * @param effect + */ + private void playCarSvagEnterRoom(String effect) { + if (TextUtils.isEmpty(effect)) return; + if (!AvRoomDataManager.get().mIsNeedGiftEffect) return; + isSvgaPlaying = true; + try { + SVGAParser.Companion.shareParser().decodeFromURL(new URL(effect), + new SVGAParser.ParseCompletion() { + @Override + public void onComplete(SVGAVideoEntity svgaVideoEntity) { + binding.roomCarSvga.setVisibility(View.VISIBLE); + binding.roomCarSvga.setLoops(1); + binding.roomCarSvga.setClearsAfterStop(true); + binding.roomCarSvga.setImageDrawable(new SVGADrawable(svgaVideoEntity)); + binding.roomCarSvga.startAnimation(); + } + + @Override + public void onError() { + isSvgaPlaying = false; + binding.roomCarSvga.setVisibility(View.GONE); + } + }); + } catch (MalformedURLException e) { + e.printStackTrace(); + isSvgaPlaying = false; + } + } + + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (boxDisposable != null) boxDisposable.dispose(); + if (disposableLuckyGift != null) disposableLuckyGift.dispose(); + if (disposableMemberIn != null) disposableMemberIn.dispose(); + if (disposableLevelUp != null) disposableLevelUp.dispose(); + if (datingDisposable != null) datingDisposable.dispose(); + if (imDisposable != null) imDisposable.dispose(); + } +} diff --git a/app/src/main/res/layout/fragment_chatroom_game_main.xml b/app/src/main/res/layout/fragment_chatroom_game_main.xml index 82783417c..81654eb72 100644 --- a/app/src/main/res/layout/fragment_chatroom_game_main.xml +++ b/app/src/main/res/layout/fragment_chatroom_game_main.xml @@ -185,21 +185,6 @@ android:src="@drawable/icon_room_treasure_box" tools:contentDescription="ktv开宝箱" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="match_parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/layout_room_effect.xml b/app/src/main/res/layout/layout_room_effect.xml new file mode 100644 index 000000000..35a575fea --- /dev/null +++ b/app/src/main/res/layout/layout_room_effect.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file