8 Commits

Author SHA1 Message Date
Max
cd962493c6 fix:调整飘屏的未登录判断逻辑 2024-04-19 11:43:35 +08:00
Max
b65c25d168 feat:补充公屏过滤功能 2024-03-25 19:54:13 +08:00
Max
50ce4d135d 测试 2024-03-25 11:39:51 +08:00
Max
bafd68a265 fix:修复SVGA飘屏不能展示问题 2024-03-25 10:56:34 +08:00
Max
f26f399df0 feat:初步搭建新的飘窗架构
feat:移植部分piko的通用飘屏、公屏代码(待完善)
2024-03-22 20:06:29 +08:00
Max
c0bbabaa1c feat:新增渠道:fir 2024-03-18 18:42:58 +08:00
Max
c97b521d4c feat:移除AVRoomActivity中的全服礼物飘屏逻辑到BaseActivity 2024-03-18 14:05:29 +08:00
Max
469ee07eeb feat:同步peko完成礼物飘窗UI优化(同步peko:去掉普通礼物飘窗) 2024-03-18 09:53:59 +08:00
67 changed files with 2483 additions and 1177 deletions

View File

@@ -185,6 +185,11 @@ android {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
fir {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
mlq {
ndk {
abiFilters 'x86'

View File

@@ -2,15 +2,12 @@ package com.nnbc123.app.avroom.activity;
import static android.view.View.VISIBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ALL_SERVICE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_LUCKY_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ROOM_PK;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_ROOM_PK_NOTIFY;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
@@ -60,15 +57,12 @@ import com.nnbc123.app.common.widget.CircleImageView;
import com.nnbc123.app.common.widget.CustomImageSpan;
import com.nnbc123.app.common.widget.dialog.DialogManager;
import com.nnbc123.app.home.dialog.HelloMessageDialog;
import com.nnbc123.app.notify.room.RoomNotify;
import com.nnbc123.app.ui.patriarch.help.LimitEnterRoomHelper;
import com.nnbc123.app.ui.user.UserInfoActivity;
import com.nnbc123.app.ui.utils.ImageLoadUtils;
import com.nnbc123.app.ui.webview.CommonWebViewActivity;
import com.nnbc123.app.ui.widget.NobleOpenNoticeView;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelOneDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelThreeDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelTwoDialog;
import com.nnbc123.app.ui.widget.dialog.MonsterDialog;
import com.nnbc123.app.ui.widget.marqueeview.Utils;
import com.nnbc123.app.utils.UserUtils;
@@ -92,7 +86,6 @@ import com.nnbc123.core.monsterhunting.bean.MonsterHuntingResult;
import com.nnbc123.core.monsterhunting.bean.MonsterInfo;
import com.nnbc123.core.monsterhunting.bean.MonsterProtocol;
import com.nnbc123.core.monsterhunting.manager.MonsterDataManager;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.noble.NobleInfo;
import com.nnbc123.core.noble.NobleResourceType;
import com.nnbc123.core.noble.NobleUtil;
@@ -119,7 +112,6 @@ import com.nnbc123.core.utils.LogUtils;
import com.nnbc123.core.utils.StringUtils;
import com.nnbc123.library.base.factory.CreatePresenter;
import com.nnbc123.library.rxbus.RxBus;
import com.nnbc123.library.utils.JavaUtil;
import com.nnbc123.library.utils.SingleToastUtil;
import com.nnbc123.library.utils.UIUtils;
import com.opensource.svgaplayer.SVGADrawable;
@@ -137,7 +129,6 @@ import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -197,8 +188,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
/*********************************显示全服礼物***************************************/
private GiftBroadcastObserver giftObserver;
private Dialog giftDialog;
private LinkedList<AllServiceGiftProtocol.DataBean> giftList;
private boolean isResume = true;
@Nullable
private SingleRoomTipDialog singleRoomTipDialog;
@@ -424,7 +413,7 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
mVsNobleOpen = findViewById(R.id.vs_noble_open_notice);
vsTaskTips = findViewById(R.id.vs_task_tips);
viewpager = findViewById(R.id.fragment_container);
new RoomNotify(this).start();
IMNetEaseManager.get().getChatRoomEventObservable()
.compose(bindToLifecycle())
.subscribe(this::onRoomEventReceive);
@@ -501,9 +490,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
super.onResume();
AvRoomDataManager.get().roomNoDestory = true;
registerGiftBroadcastMessage(true);
if (giftList != null) {
giftList.clear();
}
isResume = true;
}
@@ -904,12 +890,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
monsterDialog.dismiss();
monsterDialog = null;
}
if (giftDialog != null && giftDialog.isShowing()) {
giftDialog.setOnDismissListener(null);
giftDialog.dismiss();
giftDialog = null;
}
if (limitEnterRoomHelper != null) {
limitEnterRoomHelper.release();
}
@@ -1190,30 +1170,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
if (baseProtocol == null) return;
switch (baseProtocol.getFirst()) {
case CUSTOM_MSG_HEADER_TYPE_GIFT:
if (!isValid()) return;
if (giftList == null) {
giftList = new LinkedList<>();
}
int second2 = baseProtocol.getSecond();
AllServiceGiftProtocol.DataBean data = JSON.parseObject(String.valueOf(baseProtocol.getData()), AllServiceGiftProtocol.DataBean.class);
if (data == null || data.getGiftUrl() == null || data.isCeremonyGift())
return;
giftList.add(data);
if (second2 == CUSTOM_MSG_ALL_SERVICE_GIFT) {
if (giftDialog != null && giftDialog.isShowing()) {
// 如果当前以及有礼物弹窗在展示,则需要等到他 dismiss 后再显示下一个
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
return;
} else {
giftDialog.dismiss();
}
} else {
showGiftDialog();
}
}
break;
case CUSTOM_MSG_LUCKY_GIFT:
if (baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY) {
RoomReceivedLuckyGiftAttachment attachment = new RoomReceivedLuckyGiftAttachment(CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY);
@@ -1236,39 +1192,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
}
}
private void showGiftDialog() {
if (giftList.size() == 0) return;
giftDialog = generateAllServiceGiftDialog(this, giftList.peekFirst());
giftDialog.setOnDismissListener(dialog -> {
giftList.pollFirst();
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
if (isValid()) {
showGiftDialog();
} else {
giftList.clear();
}
}
});
giftDialog.show();
}
private AllServiceGiftDialog generateAllServiceGiftDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
switch (JavaUtil.str2int(dataBean.getLevelNum())) {
default:
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_1:
return new AllServiceGiftLevelOneDialog(context, dataBean);
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_2:
return new AllServiceGiftLevelTwoDialog(context, dataBean);
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_3:
return new AllServiceGiftLevelThreeDialog(context, dataBean);
}
}
@Override
protected void onPause() {
super.onPause();

View File

@@ -125,59 +125,6 @@ public class GiftEffectView extends RelativeLayout implements SVGACallback {
giftInfo = giftEffectInfo.getGift();
}
if (giftInfo != null) {
int totalCoin = giftInfo.getGoldPrice() * giftEffectInfo.getGiftNum() * giftEffectInfo.getTargetUsers().size();
if (totalCoin >= 520 &&
giftEffectInfo.getGiftReceiveType() != GiftEffectInfo.GIFT_RECEIVE_TYPE_LUCKY
&& !AvRoomDataManager.get().isSelfGamePlaying()) {//礼物栏
ImageLoadUtils.loadImage(benefactorAvatar.getContext(), giftEffectInfo.getAvatar(), benefactorAvatar);
ImageLoadUtils.loadImage(giftImg.getContext(), giftInfo.getGiftUrl(), giftImg);
benefactorNick.setText(giftEffectInfo.getNick());
giftNumber.setText("X" + giftEffectInfo.getGiftNum());
giftName.setText(giftInfo.getGiftName());
container.setVisibility(VISIBLE);
if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_SINGLE) {
GiftReceiver giftReceiver = giftEffectInfo.getTargetUsers().get(0);
ImageLoadUtils.loadAvatar(receiverAvatar.getContext(), giftReceiver.getAvatar(), receiverAvatar);
receiverNick.setText(giftReceiver.getNick());
} else if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_ALL) {
receiverAvatar.setImageResource(R.mipmap.app_logo);
receiverNick.setText("全麦");
} else if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_MULTI) {
receiverAvatar.setImageResource(R.mipmap.app_logo);
StringBuilder sb = new StringBuilder();
for (GiftReceiver targetUser : giftEffectInfo.getTargetUsers()) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByAccount(targetUser.getUid() + "");
if (roomQueueInfo == null) continue;
sb.append(roomQueueInfo.mRoomMicInfo.getPosition() + 1).append("").append(",");
}
if (sb.length() > 0) {
sb.replace(sb.lastIndexOf(","), sb.length(), "");
}
receiverNick.setText(sb.toString());
}
Animation operatingAnim = AnimationUtils.loadAnimation(getContext(), R.anim.light_bg_rotate_anim);
LinearInterpolator lin = new LinearInterpolator();
operatingAnim.setInterpolator(lin);
giftLightBg.setAnimation(operatingAnim);
final Point center = new Point();
center.x = ResolutionUtils.getScreenWidth(getContext()) / 2;
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(container, "translationX", -UIUtil.dip2px(getContext(), 400), center.x - container.getWidth() / 2).setDuration(500);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(container, "alpha", 0.0F, 1.0F).setDuration(500);
objectAnimator1.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator1.start();
if (totalCoin < 4999) {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_1);
} else if (totalCoin < 9999) {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_2);
} else {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_3);
}
}
effectHandler.sendEmptyMessageDelayed(0, 6000);
if (giftInfo.getOtherViewType() == 1 && !TextUtils.isEmpty(giftInfo.getViewUrl())) {
drawVAPEffect(giftInfo.getViewUrl());

View File

@@ -5,6 +5,7 @@ import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_GIFT_C
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_KITCHEN;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_PRIVILEGE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_RED_PACKAGE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ROOM_TEMPLATE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_BOX_ME;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_FANS_TEAM_JOIN;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_GIFT_COMPOUND;
@@ -123,6 +124,7 @@ import com.nnbc123.core.im.custom.bean.RoomReceivedLuckyGiftAttachment;
import com.nnbc123.core.im.custom.bean.RoomTipAttachment;
import com.nnbc123.core.im.custom.bean.TarotAttachment;
import com.nnbc123.core.im.custom.bean.TarotMsgBean;
import com.nnbc123.core.im.custom.bean.TemplateMessageAttachment;
import com.nnbc123.core.im.custom.bean.UnLockGiftAttachment;
import com.nnbc123.core.im.custom.bean.VipMessageAttachment;
import com.nnbc123.core.im.custom.bean.WelcomeAttachment;
@@ -232,6 +234,7 @@ public class MessageView extends FrameLayout {
private OnClick onClick;
private OnMsgLongClickListener onLongClickListener;
private TemplateMessageAdapter templateMessageAdapter;
public MessageView(Context context) {
this(context, null);
@@ -414,6 +417,17 @@ public class MessageView extends FrameLayout {
}
private TemplateMessageAdapter getTemplateMessageAdapter() {
if (templateMessageAdapter == null) {
templateMessageAdapter = new TemplateMessageAdapter(uid -> {
if (clickConsumer != null) {
Single.just(String.valueOf(uid)).subscribe(clickConsumer);
}
});
}
return templateMessageAdapter;
}
public void onCurrentRoomReceiveNewMsg(List<ChatRoomMessage> messages) {
if (messages == null) return;
if (messages.size() == 1) {
@@ -596,6 +610,20 @@ public class MessageView extends FrameLayout {
return this;
}
/**
* @param drawable -icon url
* @return -返回一個spannableStringBuilder
*/
public SpannableBuilder appendImg(String drawable, Object what) {
if (TextUtils.isEmpty(drawable)) return this;
int start = builder.length();
builder.append("-");
CustomImageSpan imageSpan = new CustomImageSpan(new ColorDrawable(Color.TRANSPARENT), textView, drawable);
builder.setSpan(imageSpan, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
builder.setSpan(what, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return this;
}
/**
* @param drawable -icon url
* @param width 宽
@@ -653,6 +681,16 @@ public class MessageView extends FrameLayout {
return this;
}
public SpannableBuilder append(String drawable, int width, int height, Object what) {
if (TextUtils.isEmpty(drawable)) return this;
int start = builder.length();
builder.append("-");
CustomImageSpan imageSpan = new CustomImageSpan(new ColorDrawable(Color.TRANSPARENT), textView, drawable, width, height);
builder.setSpan(imageSpan, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
builder.setSpan(what, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return this;
}
/**
* @param imgUrl -icon url
* @param height 高
@@ -667,6 +705,16 @@ public class MessageView extends FrameLayout {
return this;
}
public SpannableBuilder append(String imgUrl, int height, Object what) {
if (TextUtils.isEmpty(imgUrl)) return this;
int start = builder.length();
builder.append("-");
builder.setSpan(new CustomAutoWidthImageSpan(new ColorDrawable(Color.TRANSPARENT), textView, imgUrl, height)
, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
builder.setSpan(what, start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return this;
}
/**
* @param drawable -icon
* @param width 宽
@@ -1023,6 +1071,13 @@ public class MessageView extends FrameLayout {
} else if (second == CustomAttachment.CUSTOM_MSG_GIFT_DRESS) {
setDressGiftMsg(tvContent, (DressUpGiftAttachment) attachment, chatRoomMessage);
}
} else if (first == CUSTOM_MSG_ROOM_TEMPLATE) {
TemplateMessageAttachment templateMessageAttachment = (TemplateMessageAttachment) chatRoomMessage.getAttachment();
if (templateMessageAttachment != null) {
getTemplateMessageAdapter().convert(tvContent, templateMessageAttachment.getTemplateMessage());
} else {
getTemplateMessageAdapter().convert(tvContent, null);
}
} else {
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));

View File

@@ -0,0 +1,180 @@
package com.nnbc123.app.avroom.widget
import android.content.Context
import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.text.style.ForegroundColorSpan
import android.view.View
import android.widget.TextView
import com.chuhai.utils.UiUtils
import com.nnbc123.app.common.widget.OriginalDrawStatusClickSpan
import com.nnbc123.app.utils.CommonJumpHelper
import com.nnbc123.app.utils.SpannableBuilder
import com.nnbc123.core.home.bean.BannerInfo
import com.nnbc123.core.im.custom.bean.TemplateMessage
import com.nnbc123.core.im.custom.bean.TemplateMessage.TemplateNode
import com.nnbc123.core.im.custom.bean.TemplateMessage.Content
/**
* Created by Max on 2024/2/22 17:20
* Desc:模版消息适配器
**/
class TemplateMessageAdapter(val listener: Listener?) {
/**
* 解析为文本子节点只支持TEXT类型
*/
fun parse(context: Context, attachment: TemplateMessage?): SpannableStringBuilder? {
val builder = SpannableBuilder()
if (attachment == null) {
return null
}
val nodeList = attachment.getNodeList()
nodeList.forEach {
if (it is TemplateNode.NormalNode) {
val textColor = parseColor(it.textColor)
if (textColor != null) {
builder.append(it.text, ForegroundColorSpan(textColor))
} else {
builder.append(it.text)
}
} else if (it is TemplateNode.SpecialNode) {
when (it.content.type) {
Content.TEXT -> {
val text = it.content.text?.getFirstText()
if (!text.isNullOrEmpty()) {
val textColor = parseColor(it.content.textColor)
val clickSpan = createClickSpan(context, it.content, listener)
val list = ArrayList<Any>()
if (textColor != null) {
list.add(ForegroundColorSpan(textColor))
}
if (clickSpan != null) {
list.add(clickSpan)
}
builder.append(text, *list.toArray())
}
}
}
}
}
return builder.build()
}
fun convert(textView: TextView, attachment: TemplateMessage?) {
if (attachment == null) {
textView.text = ""
return
}
val nodeList = attachment.getNodeList()
val textBuilder = MessageView.SpannableBuilder(textView)
nodeList.forEach {
if (it is TemplateNode.NormalNode) {
val textColor = parseColor(it.textColor)
if (textColor != null) {
textBuilder.append(it.text, ForegroundColorSpan(textColor))
} else {
textBuilder.append(it.text)
}
} else if (it is TemplateNode.SpecialNode) {
when (it.content.type) {
Content.TEXT -> {
val text = it.content.text?.getFirstText()
if (!text.isNullOrEmpty()) {
val textColor = parseColor(it.content.textColor)
val clickSpan = createClickSpan(textView.context, it.content, listener)
val list = ArrayList<Any>()
if (textColor != null) {
list.add(ForegroundColorSpan(textColor))
}
if (clickSpan != null) {
list.add(clickSpan)
}
textBuilder.append(text, *list.toArray())
}
}
TemplateMessage.Content.IMAGE -> {
val image = it.content.image
val width = it.content.width ?: 0
val height = it.content.height ?: 0
val clickSpan = createClickSpan(textView.context, it.content, listener)
if (height > 0 && width == 0) {
if (clickSpan != null) {
textBuilder.append(
image,
UiUtils.dip2px(height.toFloat()),
clickSpan
)
} else {
textBuilder.append(image, UiUtils.dip2px(height.toFloat()))
}
} else if (height > 0 && width > 0) {
if (clickSpan != null) {
textBuilder.append(
image,
UiUtils.dip2px(width.toFloat()),
UiUtils.dip2px(height.toFloat()), clickSpan
)
} else {
textBuilder.append(
image,
UiUtils.dip2px(width.toFloat()),
UiUtils.dip2px(height.toFloat())
)
}
} else {
if (clickSpan != null) {
textBuilder.appendImg(image, clickSpan)
} else {
textBuilder.appendImg(image)
}
}
}
}
}
}
textView.text = textBuilder.build()
textView.setOnClickListener(null)
textView.movementMethod = LinkMovementMethod()
}
private fun createClickSpan(
context: Context,
content: TemplateMessage.Content,
listener: Listener?
): OriginalDrawStatusClickSpan? {
val skipType = content.getSkipType()
val skipUri = content.getSkipUri()
if (skipType > 0 && !skipUri.isNullOrEmpty()) {
return object : OriginalDrawStatusClickSpan() {
override fun onClick(widget: View) {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
listener?.onShowUserCard(skipUri)
} else {
CommonJumpHelper.bannerJump(context, content)
}
}
}
} else {
return null
}
}
fun parseColor(color: String?): Int? {
if (color == null) {
return null
}
try {
return Color.parseColor(color)
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return null
}
interface Listener {
fun onShowUserCard(uid: String)
}
}

View File

@@ -4,6 +4,7 @@ import static com.nnbc123.core.Constants.DEBUG_MAX_UID;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_HEAD_NOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_SUB_OPENNOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_SUB_RENEWNOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ALL_SERVICE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_RED_PACKAGE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_RED_PACKAGE_RECEIVE_ALL_DIAMOND;
@@ -13,6 +14,7 @@ import static com.nnbc123.library.utils.UIUtils.getActivityByContext;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -28,6 +30,7 @@ import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
@@ -62,6 +65,7 @@ import com.nnbc123.app.common.widget.StatusLayout;
import com.nnbc123.app.common.widget.dialog.DialogManager;
import com.nnbc123.app.common.widget.dialog.DialogUiHelper;
import com.nnbc123.app.mentoring_relationship.dialog.GrabApprenticesNoticeDialog;
import com.nnbc123.app.notify.global.GlobalNotify;
import com.nnbc123.app.ui.im.avtivity.NimP2PMessageActivity;
import com.nnbc123.app.ui.login.AddUserInfoActivity;
import com.nnbc123.app.ui.login.LoginCodeActivity;
@@ -69,7 +73,7 @@ import com.nnbc123.app.ui.login.LoginPhoneActivity;
import com.nnbc123.app.ui.pay.ChargeActivity;
import com.nnbc123.app.ui.setting.ResetPasswordActivity;
import com.nnbc123.app.ui.widget.DefaultToolBar;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelCeremonyDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceVipLevelUPDialog;
import com.nnbc123.app.ui.widget.dialog.GameInviteDialog;
import com.nnbc123.app.ui.widget.dialog.OpenNobleGlobalNoticeDialog;
@@ -114,6 +118,7 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import io.reactivex.Observable;
@@ -145,6 +150,8 @@ public abstract class BaseActivity extends RxAppCompatActivity
private OpenNobleGlobalNoticeDialog mNoticeDialog;
private boolean isShowingChargeDialog;
private Dialog giftDialog;
private LinkedList<AllServiceGiftProtocol.DataBean> giftList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -159,6 +166,7 @@ public abstract class BaseActivity extends RxAppCompatActivity
onReceiveChatRoomEvent(roomEvent);
}));
registerNimBroadcastMessage(true);
GlobalNotify.INSTANCE.bindActivity(this);
}
protected void onReceiveChatRoomEvent(RoomEvent roomEvent) {
@@ -340,7 +348,14 @@ public abstract class BaseActivity extends RxAppCompatActivity
mNoticeDialog.dismiss();
mNoticeDialog = null;
}
if (giftDialog != null && giftDialog.isShowing()) {
giftDialog.setOnDismissListener(null);
giftDialog.dismiss();
giftDialog = null;
}
if (giftList != null) {
giftList.clear();
}
super.onDestroy();
LogUtil.i(this.getClass().getName(), "onDestroy");
/* ImageLoadUtils.clearMemory(this);*/
@@ -508,7 +523,6 @@ public abstract class BaseActivity extends RxAppCompatActivity
.compose(bindUntilEvent(ActivityEvent.PAUSE))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onRoomEventReceived);
}
@Override
@@ -930,15 +944,53 @@ public abstract class BaseActivity extends RxAppCompatActivity
UserUtils.getUserInfo() == null)
return;
AllServiceGiftProtocol.DataBean data = JSON.parseObject(String.valueOf(baseProtocol.getData()), AllServiceGiftProtocol.DataBean.class);
if (data == null || data.getGiftUrl() == null || !data.isCeremonyGift())
if (data == null || data.getGiftUrl() == null)
return;
new AllServiceGiftLevelCeremonyDialog(context, data).show();
if (giftList == null) {
giftList = new LinkedList<>();
}
int second2 = baseProtocol.getSecond();
if (second2 == CUSTOM_MSG_ALL_SERVICE_GIFT) {
giftList.add(data);
if (giftDialog != null && giftDialog.isShowing()) {
// 如果当前以及有礼物弹窗在展示,则需要等到他 dismiss 后再显示下一个
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
return;
} else {
giftDialog.dismiss();
}
} else {
showGiftDialog();
}
}
break;
default:
break;
}
}
private void showGiftDialog() {
if (giftList.size() == 0) return;
giftDialog = generateAllServiceGiftDialog(this, giftList.peekFirst());
giftDialog.setOnDismissListener(dialog -> {
giftList.pollFirst();
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
if (isValid()) {
showGiftDialog();
} else {
giftList.clear();
}
}
});
giftDialog.show();
}
private AllServiceGiftLevelDialog generateAllServiceGiftDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
return new AllServiceGiftLevelDialog(context, dataBean);
}
public void onGrabApprenticesEvent(GrabApprenticesEvent event) {
if (!isTopActivity()) return;
if (dialog != null && dialog.isAdded()) {

View File

@@ -180,12 +180,12 @@ class PartyFragment : BaseBindingFragment<HomePartyFragmentBinding>() {
viewModel.bannerLiveData.observe(this) {
BannerHelper.setBanner(mBinding.rollView, it) { _, data ->
var roomId: Long? = null
if (data.skipType == BannerInfo.SKIP_TYPE_ROUTER) {
if (JavaUtil.str2int(data.routerType) == RouterType.ROOM) {
roomId = JavaUtil.str2long(data.routerValue)
if (data.getSkipType() == BannerInfo.SKIP_TYPE_ROUTER) {
if (JavaUtil.str2int(data.getRouterType()) == RouterType.ROOM) {
roomId = JavaUtil.str2long(data.getRouterValue())
}
} else if (data.skipType == BannerInfo.SKIP_TYP_CHAT_ROOM) {
roomId = JavaUtil.str2long(data.skipUri)
} else if (data.getSkipType() == BannerInfo.SKIP_TYP_CHAT_ROOM) {
roomId = JavaUtil.str2long(data.getSkipUri())
}
if (roomId != null) {
StatisticManager.Instance()

View File

@@ -0,0 +1,143 @@
package com.nnbc123.app.notify.global
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.alibaba.fastjson.JSON
import com.chuhai.utils.log.ILog
import com.google.gson.Gson
import com.gyf.immersionbar.ImmersionBar
import com.netease.nimlib.sdk.NIMSDK
import com.netease.nimlib.sdk.Observer
import com.netease.nimlib.sdk.msg.model.BroadcastMessage
import com.nnbc123.app.MiddleActivity
import com.nnbc123.app.NimMiddleActivity
import com.nnbc123.app.avroom.activity.AVRoomActivity
import com.nnbc123.app.other.activity.SplashActivity
import com.nnbc123.app.room_chat.activity.NimRoomP2PMessageActivity
import com.nnbc123.app.room_chat.activity.RoomMsgActivity
import com.nnbc123.app.support.float.FloatWindowEngine
import com.nnbc123.app.support.float.SimpleFloatWindow
import com.nnbc123.app.support.float.SimpleQueue
import com.nnbc123.app.treasure_box.activity.TreasureBoxActivity
import com.nnbc123.app.ui.login.AddUserInfoActivity
import com.nnbc123.app.ui.login.LoginCodeActivity
import com.nnbc123.app.ui.login.LoginPhoneActivity
import com.nnbc123.app.ui.setting.ResetPasswordActivity
import com.nnbc123.app.ui.setting.SettingActivity
import com.nnbc123.app.utils.UserUtils
import com.nnbc123.core.auth.AuthModel
import com.nnbc123.core.bean.BaseProtocol
import com.nnbc123.core.im.custom.bean.CustomAttachment
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyMsgBean
import kotlinx.coroutines.cancel
/**
* Created by Max on 2024/3/20 19:30
* Desc:
**/
object GlobalNotify : Observer<BroadcastMessage>, ILog {
private val blackActivityList = listOf(
SplashActivity::class.java,
LoginPhoneActivity::class.java,
LoginCodeActivity::class.java,
ResetPasswordActivity::class.java,
AddUserInfoActivity::class.java,
MiddleActivity::class.java,
NimMiddleActivity::class.java,
// 房间页面单独处理
AVRoomActivity::class.java,
// 该Activity用了透明主题且顶部区域还能看到房间页面那就在房间页面展示飘屏即可
TreasureBoxActivity::class.java,
// 该Activity用了透明主题且顶部区域还能看到房间页面那就在房间页面展示飘屏即可
NimRoomP2PMessageActivity::class.java,
// 该Activity用了透明主题且顶部区域还能看到房间页面那就在房间页面展示飘屏即可
RoomMsgActivity::class.java,
SettingActivity::class.java
)
val queue = SimpleQueue()
init {
start()
}
fun start() {
NIMSDK.getMsgServiceObserve().observeBroadcastMessage(this, true)
}
fun stop() {
NIMSDK.getMsgServiceObserve().observeBroadcastMessage(this, false)
}
fun bindActivity(activity: FragmentActivity) {
logD("bindActivity() activity:${activity}")
if (!filter(activity)) {
logD("bindActivity() 被过滤掉")
return
}
logD("bindActivity() activity:${activity}")
activity.lifecycleScope.launchWhenStarted {
logD("bindActivity() launchWhenStarted activity:${activity}")
bindActivityImpl(activity)
this.cancel()
}
}
private fun filter(activity: FragmentActivity): Boolean {
if (blackActivityList.firstOrNull { it == activity::class.java } != null) {
return false
}
if (AuthModel.get().currentUid == 0L) {
return false
}
return true
}
private fun bindActivityImpl(activity: FragmentActivity) {
val widget = SimpleFloatWindow(activity)
widget.bindActivity(activity)
widget.adapter = NotifyAdapter()
val statusHeight = ImmersionBar.getStatusBarHeight(activity)
widget.getView().setPadding(0, statusHeight, 0, 0)
val engine = FloatWindowEngine(widget, queue)
engine.bindLifecycle(activity.lifecycle)
engine.start()
}
override fun onEvent(message: BroadcastMessage?) {
if (message == null) {
return
}
try {
val contentJsonStr: String = message.content
val jsonObject = JSON.parseObject(contentJsonStr) ?: return
if (jsonObject.containsKey("body")) {
val body = jsonObject.getString("body")
if (body.isNullOrEmpty()) {
return
}
val baseProtocol: BaseProtocol<*> = try {
JSON.parseObject(body, BaseProtocol::class.java)
} catch (e: java.lang.Exception) {
null
} ?: return
onReceivedNimBroadcastMessage(baseProtocol)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun onReceivedNimBroadcastMessage(protocol: BaseProtocol<*>) {
if (protocol.first == CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY) {
if (protocol.second == CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL) {
val data = Gson().fromJson<RoomTemplateNotifyMsgBean>(
protocol.data.toString(),
RoomTemplateNotifyMsgBean::class.java
)
queue.addLast(data)
}
}
}
}

View File

@@ -0,0 +1,30 @@
package com.nnbc123.app.notify.global
import android.content.Context
import com.nnbc123.app.support.float.FloatView
import com.nnbc123.app.support.float.FloatViewAdapter
import com.nnbc123.app.support.float.FloatWindow
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyMsgBean
/**
* Created by Max on 2024/3/22 16:05
* Desc:
**/
class NotifyAdapter : FloatViewAdapter {
override fun onCreateFloatView(context: Context, item: Any): FloatView? {
if (item is RoomTemplateNotifyMsgBean) {
if (item.resourceType == "IMAGE") {
return TemplateImageNotifyView(context)
} else if (item.resourceType == "SVGA") {
return TemplateSvgaNotifyView(context)
}
} else if (item is String) {
return TestNotifyView(context)
}
return null
}
override fun onBindFloatView(window: FloatWindow, floatView: FloatView, item: Any) {
floatView.onAttached(window, item)
}
}

View File

@@ -0,0 +1,115 @@
package com.nnbc123.app.notify.global
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
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.TextView
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.netease.nim.uikit.support.glide.GlideApp
import com.nnbc123.app.R
import com.nnbc123.app.avroom.widget.TemplateMessageAdapter
import com.nnbc123.app.support.float.BaseFloatView
import com.nnbc123.app.utils.CommonJumpHelper
import com.nnbc123.core.home.bean.BannerInfo
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyMsgBean
/**
* Created by Max on 2024/3/22 17:26
* Desc:
**/
class TemplateImageNotifyView(context: Context) : BaseFloatView(context) {
private val templateMessageAdapter = TemplateMessageAdapter(null)
init {
LayoutInflater.from(context).inflate(R.layout.layout_template_notify_image, this, true)
}
override fun onBind(item: Any) {
val data = item as? RoomTemplateNotifyMsgBean
if (data == null) {
requestRemoveSelf()
return
}
if (data.resourceType != "IMAGE") {
requestRemoveSelf()
return
}
val resourceContent = data.resourceContent
if (resourceContent.isNullOrEmpty()) {
requestRemoveSelf()
return
}
val textView = rootView.findViewById<TextView>(R.id.tv_text)
val textSize = data.fontSize?.toFloat() ?: 12f
val textColor =
templateMessageAdapter.parseColor(data.textColor) ?: Color.WHITE
textView.textSize = textSize
textView.setTextColor(textColor)
val bgView = rootView.findViewById<ImageView>(R.id.iv_bg)
GlideApp.with(bgView)
.load(resourceContent).into(object : CustomTarget<Drawable>() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable>?
) {
templateMessageAdapter.convert(textView, data)
bgView.setImageDrawable(resource)
startEnterAnim()
val skipType = data.skipType
if (skipType != null) {
val clickAction = View.OnClickListener {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
//
} else {
CommonJumpHelper.bannerJump(context, skipType, data.skipContent)
}
}
rootView.setOnClickListener(clickAction)
textView.setOnClickListener(clickAction)
}
startDelayRemove(5000)
}
override fun onLoadCleared(placeholder: Drawable?) {
requestRemoveSelf()
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
requestRemoveSelf()
}
})
}
private fun startEnterAnim() {
val inAnimation = AnimationUtils.loadAnimation(context, R.anim.anim_right_in)
this.startAnimation(inAnimation)
}
private fun startDelayRemove(delayMillis: Long) {
postDelayed({
val outAnimation = AnimationUtils.loadAnimation(context, R.anim.anim_left_out)
outAnimation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
requestRemoveSelf()
}
override fun onAnimationRepeat(animation: Animation?) {
}
})
this.startAnimation(outAnimation)
}, delayMillis)
}
}

View File

@@ -0,0 +1,120 @@
package com.nnbc123.app.notify.global
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
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.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.netease.nim.uikit.support.glide.GlideApp
import com.nnbc123.app.R
import com.nnbc123.app.avroom.widget.TemplateMessageAdapter
import com.nnbc123.app.common.svga.SimpleSvgaCallback
import com.nnbc123.app.support.float.BaseFloatView
import com.nnbc123.app.utils.CommonJumpHelper
import com.nnbc123.core.home.bean.BannerInfo
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyMsgBean
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 java.net.URL
/**
* Created by Max on 2024/3/22 17:26
* Desc:
**/
class TemplateSvgaNotifyView(context: Context) : BaseFloatView(context) {
private val templateMessageAdapter = TemplateMessageAdapter(null)
private val svgaView = SVGAImageView(context)
init {
svgaView.loops = 1
svgaView.clearsAfterDetached = true
addView(svgaView, LayoutParams(LayoutParams.MATCH_PARENT, 0))
}
override fun onBind(item: Any) {
val data = item as? RoomTemplateNotifyMsgBean
if (data == null) {
requestRemoveSelf()
return
}
if (data.resourceType != "SVGA") {
requestRemoveSelf()
return
}
val resourceContent = data.resourceContent
if (resourceContent.isNullOrEmpty()) {
requestRemoveSelf()
return
}
val params = svgaView.layoutParams as ConstraintLayout.LayoutParams
params.dimensionRatio = data.getDimensionRatio() ?: "75:11"
svgaView.layoutParams = params
svgaView.callback = object : SimpleSvgaCallback() {
override fun onFinished() {
requestRemoveSelf()
}
}
SVGAParser.shareParser().decodeFromURL(
URL(resourceContent),
object : SVGAParser.ParseCompletion {
override fun onComplete(videoItem: SVGAVideoEntity) {
val text = templateMessageAdapter.parse(context, data) ?: ""
val textKey = data.getSvgaTextKey()
val textSize = data.fontSize?.toFloat() ?: 24f
val textColor =
templateMessageAdapter.parseColor(data.textColor) ?: Color.WHITE
val dynamicEntity = SVGADynamicEntity()
val textPaint = TextPaint()
textPaint.color = textColor //字體顏色
textPaint.textSize = textSize //字體大小
dynamicEntity.setDynamicText(
StaticLayout(
text,
0,
text.length,
textPaint,
0,
Layout.Alignment.ALIGN_CENTER,
1.0f,
0.0f,
false
), textKey
)
val skipType = data.skipType
if (skipType != null) {
svgaView.setOnClickListener {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
//
} else {
CommonJumpHelper.bannerJump(context, skipType, data.skipContent)
}
}
}
val drawable = SVGADrawable(videoItem, dynamicEntity)
svgaView.setImageDrawable(drawable)
svgaView.stepToFrame(0, true)
}
override fun onError() {
requestRemoveSelf()
}
},
null
)
}
}

View File

@@ -0,0 +1,56 @@
package com.nnbc123.app.notify.global
import android.content.Context
import android.graphics.Color
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.view.isVisible
import com.nnbc123.app.R
import com.nnbc123.app.support.float.BaseFloatView
/**
* Created by Max on 2024/3/21 17:52
* Desc:
**/
class TestNotifyView(context: Context) : BaseFloatView(context) {
private val view = TextView(context)
init {
addView(
view,
ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
setBackgroundColor(Color.parseColor("#44FFFFFF"))
view.setTextColor(Color.RED)
view.textSize = 30f
}
override fun onBind(item: Any) {
view.text = item.toString()
val inAnimation = AnimationUtils.loadAnimation(context, R.anim.anim_right_in)
this.startAnimation(inAnimation)
postDelayed({
val outAnimation = AnimationUtils.loadAnimation(context, R.anim.anim_left_out)
outAnimation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
this@TestNotifyView.isVisible = false
post {
requestRemoveSelf()
}
}
override fun onAnimationRepeat(animation: Animation?) {
}
})
this.startAnimation(outAnimation)
}, 5000)
}
}

View File

@@ -0,0 +1,93 @@
package com.nnbc123.app.notify.room
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.chuhai.utils.log.ILog
import com.gyf.immersionbar.ImmersionBar
import com.nnbc123.app.notify.global.GlobalNotify
import com.nnbc123.app.notify.global.NotifyAdapter
import com.nnbc123.app.support.float.DoubleQueue
import com.nnbc123.app.support.float.FloatWindowEngine
import com.nnbc123.app.support.float.SimpleFloatWindow
import com.nnbc123.app.support.float.SimpleQueue
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyAttachment
import com.nnbc123.core.manager.IMNetEaseManager
import com.nnbc123.core.manager.RoomEvent
import io.reactivex.disposables.CompositeDisposable
import kotlinx.coroutines.cancel
/**
* Created by Max on 2024/3/22 14:47
* Desc:
**/
class RoomNotify(activity: FragmentActivity) : LifecycleEventObserver, ILog {
val queue = SimpleQueue()
private val compositeDisposable: CompositeDisposable = CompositeDisposable()
init {
bindActivity(activity)
}
private fun bindActivity(activity: FragmentActivity) {
logD("bindActivity() activity:${activity}")
activity.lifecycleScope.launchWhenStarted {
logD("bindActivity() launchWhenStarted activity:${activity}")
bindActivityImpl(activity)
this.cancel()
}
activity.lifecycle.addObserver(this)
}
private fun bindActivityImpl(activity: FragmentActivity) {
val widget = SimpleFloatWindow(activity)
widget.bindActivity(activity)
widget.adapter = NotifyAdapter()
val statusHeight = ImmersionBar.getStatusBarHeight(activity)
widget.getView().setPadding(0, statusHeight, 0, 0)
val queue = DoubleQueue(GlobalNotify.queue, queue)
val engine = FloatWindowEngine(widget, queue)
engine.bindLifecycle(activity.lifecycle)
engine.start()
}
fun start() {
compositeDisposable.add(IMNetEaseManager.get().chatRoomEventObservable
.subscribe { roomEvent: RoomEvent? ->
if (roomEvent == null) return@subscribe
try {
onReceiveChatRoomEvent(roomEvent)
} catch (e: Exception) {
e.printStackTrace()
}
})
}
fun stop() {
if (!compositeDisposable.isDisposed) {
compositeDisposable.dispose()
}
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when (event) {
Lifecycle.Event.ON_DESTROY -> {
stop()
}
}
}
private fun onReceiveChatRoomEvent(roomEvent: RoomEvent) {
when (roomEvent.event) {
RoomEvent.TEMPLATE_NOTIFY -> {
val attachment =
roomEvent.chatRoomMessage.attachment as? RoomTemplateNotifyAttachment
val data = attachment?.getTemplateMsg() ?: return
queue.addLast(data)
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.nnbc123.app.support.float
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.annotation.CallSuper
import androidx.constraintlayout.widget.ConstraintLayout
/**
* Created by Max on 2024/3/20 14:44
* Desc:
**/
abstract class BaseFloatView : ConstraintLayout, FloatView {
private var window: FloatWindow? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
@CallSuper
override fun onAttached(window: FloatWindow, item: Any) {
this.window = window
onBind(item)
}
@CallSuper
override fun onDetached() {
this.window = null
}
protected fun requestRemoveSelf(): Boolean {
if (this.window == null) {
return false
} else {
post {
this.window?.removeChild(this)
}
return true
}
}
abstract fun onBind(item: Any)
override fun getView(): View {
return this
}
}

View File

@@ -0,0 +1,65 @@
package com.nnbc123.app.support.float
import com.chuhai.utils.log.ILog
/**
* Created by Max on 2024/3/22 14:04
* Desc:
**/
open class DoubleQueue(
val queueA: FloatQueue,
val queueB: FloatQueue
) : FloatQueue, FloatQueue.QueueObserver, ILog {
private val queueObservable = FloatQueue.QueueObservable()
override fun pollFirst(): QueueItem? {
return getFirstQueue()?.pollFirst()
}
override fun peekFirst(): QueueItem? {
return getFirstQueue()?.peekFirst()
}
protected open fun getFirstQueue(): FloatQueue? {
val itemA = queueA.peekFirst()
val itemB = queueB.peekFirst()
if (itemA != null && itemB != null) {
if (itemA.time <= itemB.time) {
return queueA
} else {
return queueB
}
}
if (itemA != null) {
return queueA
}
if (itemB != null) {
return queueB
}
return null
}
override fun addLast(data: Any) {
}
override fun registerObserver(observer: FloatQueue.QueueObserver) {
queueObservable.registerObserver(observer)
if (queueObservable.getCount() == 1) {
queueA.registerObserver(this)
queueB.registerObserver(this)
}
}
override fun unregisterObserver(observer: FloatQueue.QueueObserver) {
queueObservable.unregisterObserver(observer)
if (queueObservable.getCount() == 0) {
queueA.unregisterObserver(this)
queueB.unregisterObserver(this)
}
}
override fun onInserted() {
queueObservable.notifyInserted()
}
}

View File

@@ -0,0 +1,51 @@
package com.nnbc123.app.support.float
import android.database.Observable
/**
* Created by Max on 2024/3/22 14:05
* Desc:
**/
interface FloatQueue {
fun pollFirst(): QueueItem?
fun peekFirst(): QueueItem?
fun addLast(data: Any)
fun registerObserver(observer: QueueObserver)
fun unregisterObserver(observer: QueueObserver)
interface QueueObserver {
fun onInserted()
}
class QueueObservable : Observable<QueueObserver>() {
fun notifyInserted() {
mObservers.forEach {
it.onInserted()
}
}
override fun registerObserver(observer: QueueObserver?) {
try {
super.registerObserver(observer)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun unregisterObserver(observer: QueueObserver?) {
try {
super.unregisterObserver(observer)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun getCount(): Int {
return mObservers.size
}
}
}

View File

@@ -0,0 +1,15 @@
package com.nnbc123.app.support.float
import android.view.View
/**
* Created by Max on 2024/3/20 14:34
* Desc:
**/
interface FloatView {
fun onAttached(window: FloatWindow, item: Any)
fun onDetached()
fun getView(): View
}

View File

@@ -0,0 +1,13 @@
package com.nnbc123.app.support.float
import android.content.Context
/**
* Created by Max on 2024/3/20 11:59
* Desc:
**/
interface FloatViewAdapter {
fun onCreateFloatView(context: Context, item: Any): FloatView?
fun onBindFloatView(window: FloatWindow, floatView: FloatView, item: Any)
}

View File

@@ -0,0 +1,44 @@
package com.nnbc123.app.support.float
import android.app.Activity
import android.view.View
import android.view.ViewGroup
import androidx.core.view.contains
import com.chuhai.utils.log.ILog
/**
* Created by Max on 2024/3/20 10:08
* Desc:
**/
interface FloatWindow : ILog {
fun bindActivity(activity: Activity) {
val contentView = activity.window.decorView.findViewById<ViewGroup>(android.R.id.content)
if (contentView == null) {
logE("bindActivity() contentView=null")
return
}
val view = getView()
if (contentView.contains(view)) {
return
}
if (view.layoutParams == null) {
view.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
contentView.addView(view)
}
fun getView(): View
fun onBindEngine(engine: FloatWindowEngine)
fun removeChild(floatView: FloatView)
fun canShow(): Boolean
fun onShow(item: Any)
}

View File

@@ -0,0 +1,72 @@
package com.nnbc123.app.support.float
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.chuhai.utils.log.ILog
/**
* Created by Max on 2024/3/20 10:11
* Desc:
**/
class FloatWindowEngine(
val window: FloatWindow,
val queue: FloatQueue
) : LifecycleEventObserver, FloatQueue.QueueObserver, ILog {
private var isAvailable = true
fun bindLifecycle(lifecycle: Lifecycle) {
lifecycle.addObserver(this)
}
fun start() {
window.onBindEngine(this)
queue.registerObserver(this)
loop()
}
fun stop() {
queue.unregisterObserver(this)
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
val isAvailableOld = isAvailable
isAvailable = event.targetState.isAtLeast(Lifecycle.State.STARTED)
if (isAvailableOld != isAvailable && isAvailable) {
logD("onStateChanged() isAvailable")
loop()
}
if (event == Lifecycle.Event.ON_DESTROY) {
stop()
}
}
fun loop() {
logD("loop()")
if (!isAvailable) {
logD("loop() !isAvailable")
return
}
val item = queue.peekFirst()
logD("loop() item:$item")
if (item == null) {
return
}
if (window.canShow()) {
queue.pollFirst()?.let {
logD("loop() onShow item:$it")
window.onShow(it.data)
}
} else {
logD("loop() canShow==false")
}
}
override fun onInserted() {
logD("onInserted()")
loop()
}
}

View File

@@ -0,0 +1,8 @@
package com.nnbc123.app.support.float
/**
* Created by Max on 2024/3/20 10:59
* Desc:
**/
data class QueueItem(val time: Long, val data: Any) {
}

View File

@@ -0,0 +1,67 @@
package com.nnbc123.app.support.float
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout
/**
* Created by Max on 2024/3/20 11:55
* Desc:
**/
open class SimpleFloatWindow : LinearLayout, FloatWindow {
var adapter: FloatViewAdapter? = null
private var engine: FloatWindowEngine? = null
private var maxVisibleCount: Int = 4
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
constructor(
context: Context?,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
init {
orientation = VERTICAL
setBackgroundColor(Color.parseColor("#44000000"))
}
override fun removeChild(floatView: FloatView) {
floatView.onDetached()
removeView(floatView.getView())
engine?.loop()
}
override fun getView(): View {
return this
}
override fun onBindEngine(engine: FloatWindowEngine) {
this.engine = engine
}
override fun canShow(): Boolean {
return this.childCount < maxVisibleCount
}
override fun onShow(item: Any) {
val floatView = adapter?.onCreateFloatView(context, item)
if (floatView == null) {
engine?.loop()
return
}
addView(floatView.getView())
adapter?.onBindFloatView(this, floatView, item)
}
}

View File

@@ -0,0 +1,38 @@
package com.nnbc123.app.support.float
import com.nnbc123.core.utils.CurrentTimeUtils
import java.util.LinkedList
/**
* Created by Max on 2024/3/20 10:08
* Desc:
**/
class SimpleQueue : FloatQueue {
private val queueObservable = FloatQueue.QueueObservable()
private val queue: LinkedList<QueueItem> = LinkedList()
override fun pollFirst(): QueueItem? {
return queue.pollFirst()
}
override fun peekFirst(): QueueItem? {
return queue.peekFirst()
}
override fun addLast(data: Any) {
val item = QueueItem(CurrentTimeUtils.getCurrentTime(), data)
queue.addLast(item)
queueObservable.notifyInserted()
}
override fun registerObserver(observer: FloatQueue.QueueObserver) {
queueObservable.registerObserver(observer)
}
override fun unregisterObserver(observer: FloatQueue.QueueObserver) {
queueObservable.unregisterObserver(observer)
}
}

View File

@@ -11,9 +11,15 @@ import android.view.View;
import androidx.databinding.DataBindingUtil;
import com.chuhai.utils.log.LogUtil;
import com.google.gson.Gson;
import com.nnbc123.app.BuildConfig;
import com.nnbc123.app.notify.global.GlobalNotify;
import com.nnbc123.app.notify.room.RoomNotify;
import com.nnbc123.core.UriProvider;
import com.nnbc123.core.auth.AuthModel;
import com.nnbc123.core.auth.event.LogoutEvent;
import com.nnbc123.core.im.custom.bean.RoomTemplateNotifyMsgBean;
import com.nnbc123.core.user.UserModel;
import com.nnbc123.core.user.bean.UserInfo;
import com.nnbc123.core.utils.SharedPreferenceUtils;
@@ -47,6 +53,7 @@ import java.io.File;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
import kotlin.random.Random;
/**
* Created by zhouxiangfeng on 2017/4/16.
@@ -55,6 +62,7 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
private ActivitySettingBinding settingBinding;
private WithdrawInfo withdrawInfos;
private RoomNotify notify;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -66,10 +74,19 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
initView();
initData();
initListeners();
notify = new RoomNotify(this);
notify.start();
}
private void initListeners() {
if (BuildConfig.DEBUG) {
settingBinding.titleBar.setOnTitleClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
debug();
}
});
}
}
@Override
@@ -243,7 +260,7 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
File dataDir;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
dataDir = new File(new File(FileHelper.getRootCacheDir().getPath(), "Android"), "data");
}else {
} else {
dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
}
File appCacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
@@ -312,4 +329,30 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
}
static int i = 0;
private void debug() {
LogUtil.INSTANCE.d("SettingActivity", "debug:" + i, false);
GlobalNotify.INSTANCE.getQueue().addLast("G#" + i);
notify.getQueue().addLast("R#" + i);
i++;
debugTemplate();
}
private void debugTemplate() {
String jsonImage = "{\"template\":{\"zh-TW\":\"你好,我是{谁},在{这里}等你\"},\"textColor\":\"#EEEEEE\",\"fontSize\":12,\"skipType\":1,\"skipContent\":\"54\",\"contents\":[{\"key\":\"\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"Name189\"},\"textColor\":\"#FFFF00\",\"skipType\":1,\"skipContent\":\"54\"},{\"key\":\"这里\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"广州路口\"},\"textColor\":\"#00FF00\"}],\"resourceType\":\"IMAGE\",\"resourceContent\":\"https://image.hiyoo.fun/bg_zoo_notice.png\"}";
String jsonImage2 = "{\"template\":{\"zh-TW\":\"你好,我是{谁},在{这里}等你\"},\"textColor\":\"#EEEEEE\",\"fontSize\":12,\"skipType\":1,\"skipContent\":\"54\",\"contents\":[{\"key\":\"\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"Name189\"},\"textColor\":\"#FFFF00\",\"skipType\":1,\"skipContent\":\"54\"},{\"key\":\"这里\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"广州路口\"},\"textColor\":\"#00FF00\"}],\"resourceType\":\"IMAGE\",\"resourceContent\":\"https://img2.baidu.com/it/u=861101866,1488660334&fm=253&fmt=auto&app=138&f=JPEG?w=650&h=244\"}";
String jsonSvga = "{\"template\":{\"zh-TW\":\"S你好我是{谁},在{这里}等你\"},\"textColor\":\"#EEEEEE\",\"fontSize\":24,\"skipType\":1,\"skipContent\":\"54\",\"contents\":[{\"key\":\"\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"Name189\"},\"textColor\":\"#FFFF00\",\"skipType\":1,\"skipContent\":\"54\"},{\"key\":\"这里\",\"type\":\"TEXT\",\"text\":{\"zh-TW\":\"广州路口\"},\"textColor\":\"#00FF00\"}],\"resourceType\":\"SVGA\",\"resourceContent\":\"https://image.hiyoo.fun/fengkuangdongwuyuanjinchangpiaoping.svga\"}";
String json;
int i = Random.Default.nextInt();
if (i % 3 == 0) {
json = jsonImage;
} else if (i % 3 == 1) {
json = jsonImage2;
} else {
json = jsonSvga;
}
RoomTemplateNotifyMsgBean data = new Gson().fromJson(json, RoomTemplateNotifyMsgBean.class);
notify.getQueue().addLast(data);
}
}

View File

@@ -0,0 +1,105 @@
package com.nnbc123.app.ui.widget.dialog
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Window
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import com.chuhai.utils.ktx.singleClick
import com.nnbc123.app.R
import com.nnbc123.app.avroom.activity.AVRoomActivity
import com.nnbc123.app.databinding.AllServiceGiftGoRoomTipsDialogBinding
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity
import com.nnbc123.core.initial.InitialModel
import com.nnbc123.library.common.util.SPUtils
import com.nnbc123.library.utils.JavaUtil
/**
* Created by Max on 2023/10/30 10:29
* Desc:跳转房间提示
**/
class AllServiceGiftGoRoomTipsDialog(
context: Context,
private val roomName: String,
private val roomId: Long
) :
BaseDialog(context, R.style.dialog) {
private var binding: AllServiceGiftGoRoomTipsDialogBinding? = null
companion object {
/**
* 是否需要提示前往房间
*/
fun isNeedTips(): Boolean {
return !SPUtils.getBoolean("all_service_gift_go_room_no_tips", false)
}
/**
* 忽略提示/不在提示
*/
private fun ignoreTips() {
SPUtils.putBoolean("all_service_gift_go_room_no_tips", true)
}
}
private var isCheck: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setCancelable(false)
requestWindowFeature(Window.FEATURE_NO_TITLE)
val inflate =
LayoutInflater.from(context)
.inflate(R.layout.all_service_gift_go_room_tips_dialog, null)
setContentView(inflate.rootView)
binding = DataBindingUtil.bind(inflate)
binding?.tvRoomName?.text = roomName
binding?.ivCheckbox?.setOnClickListener {
updateCheckbox(!isCheck)
}
binding?.tvTips?.setOnClickListener {
updateCheckbox(!isCheck)
}
binding?.tvGo?.singleClick {
if (isCheck) {
ignoreTips()
}
if (roomId == JavaUtil.str2long(InitialModel.get().publicChatHallUid)) {
PublicChatHallHomeActivity.openPublicChatHallPage(context)
} else {
AVRoomActivity.start(context, roomId)
}
dismiss()
}
binding?.tvCancel?.singleClick {
if (isCheck) {
ignoreTips()
}
dismiss()
}
updateCheckbox(false)
}
override fun onStart() {
super.onStart()
this.window?.attributes?.let {
it.width = WindowManager.LayoutParams.MATCH_PARENT
it.height = WindowManager.LayoutParams.WRAP_CONTENT
it.gravity = Gravity.CENTER
window?.attributes = it
}
}
private fun updateCheckbox(isCheck: Boolean) {
this.isCheck = isCheck
if (isCheck) {
binding?.ivCheckbox?.setImageResource(R.drawable.base_ic_checkbox_selected)
} else {
binding?.ivCheckbox?.setImageResource(R.drawable.base_ic_checkbox_unselected)
}
}
}

View File

@@ -1,77 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.databinding.DataBindingUtil;
import com.nnbc123.core.manager.AvRoomDataManager;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceCeremonyBinding;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelCeremonyDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceCeremonyBinding binding;
public AllServiceGiftLevelCeremonyDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_ceremony, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_fade);
window.getWindowManager().getDefaultDisplay().getSize(point);
}
if (dataBean != null) {
// 设置定时器
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
binding.tvGoRoom.setVisibility(dataBean.getRoomUid() == 0
|| (AvRoomDataManager.get().mCurrentRoomInfo != null && dataBean.getRoomUid() == AvRoomDataManager.get().mCurrentRoomInfo.getUid())
? View.GONE : View.VISIBLE);
binding.tvGoRoom.setOnClickListener(view -> AVRoomActivity.start(getContext(), dataBean.getRoomUid()));
}
}
}

View File

@@ -0,0 +1,191 @@
package com.nnbc123.app.ui.widget.dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewConfiguration
import android.view.Window
import android.view.WindowManager
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import com.chuhai.utils.ktx.getColorById
import com.chuhai.utils.ktx.singleClick
import com.chuhai.utils.spannable.SpannableTextBuilder
import com.nnbc123.app.R
import com.nnbc123.app.avroom.activity.AVRoomActivity
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelBinding
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity
import com.nnbc123.core.initial.InitialModel
import com.nnbc123.core.noble.AllServiceGiftProtocol
import com.nnbc123.library.utils.JavaUtil
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
/**
* Created by Max on 2023/10/27 18:42
* Desc:全服礼物弹窗
**/
class AllServiceGiftLevelDialog : BaseDialog {
private var data: AllServiceGiftProtocol.DataBean? = null
private var binding: DialogGiftAllServiceLevelBinding? = null
private var disposable: Disposable? = null
companion object {
private var marqueeError = false
}
constructor(context: Context?, data: AllServiceGiftProtocol.DataBean) : super(
context, R.style.FullScreenDialog
) {
this.data = data
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
val inflate =
LayoutInflater.from(context).inflate(R.layout.dialog_gift_all_service_level, null)
setContentView(inflate.rootView)
setCancelable(true)
setCanceledOnTouchOutside(true)
binding = DataBindingUtil.bind(inflate)
val window = window
if (window != null) {
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val windowParams = window.attributes
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT
//MATCH_PARENT会挡住键盘
// wrap_parent在小米8又会截掉一点在华为测试关闭按钮点击不到
//暂时找不到原因,
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT
windowParams.dimAmount = 0.0f
windowParams.gravity = Gravity.TOP
windowParams.x = 0
windowParams.y = 0
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.attributes = windowParams
window.setWindowAnimations(R.style.anim_left)
}
val data = this.data
val binding = this.binding
if (data != null && binding != null) {
init(data, binding)
} else {
dismiss()
}
}
private fun init(
data: AllServiceGiftProtocol.DataBean,
binding: DialogGiftAllServiceLevelBinding
) {
binding.ivAvatar.singleClick {
goRoom(data)
}
binding.tvRoomGo.singleClick {
goRoom(data)
}
binding.giftBean = data
if ((data.giftNum) <= 1) {
binding.tvCount.text = ""
} else {
binding.tvCount.text = "X${data.giftNum}"
}
SpannableTextBuilder(binding.tvMessage)
.appendText(
data.sendUserNick,
binding.tvMessage.context.getColorById(R.color.color_FFE468)
)
.appendText(
" 送给 ",
binding.tvMessage.context.getColorById(R.color.white)
)
.appendText(
data.recvUserNick + " ",
binding.tvMessage.context.getColorById(R.color.color_FFE468)
)
.appendText(
data.giftName,
binding.tvMessage.context.getColorById(R.color.white)
).apply()
when (data.levelNum.toIntOrNull()) {
2 -> {
binding.ivAvatarBg.setImageResource(R.drawable.all_service_gift_bg_avatar_2)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_2)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go2)
}
3 -> {
binding.ivAvatarBg.setImageResource(R.drawable.all_service_gift_bg_avatar_3)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_3)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go3)
}
else -> {
binding.ivAvatarBg.setImageDrawable(null)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_1)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go1)
}
}
setupTextMarquee(binding.tvMessage)
disposable = Observable.timer(data.notifyStaySecond.toLong(), TimeUnit.SECONDS)
.subscribe { dismiss() }
binding.groupRoom.isVisible = data.roomUid != 0L
}
/**
* 添加跑马灯
* 以及反射一些参数影响跑马灯
*/
private fun setupTextMarquee(view: TextView) {
view.isSelected = true
if (marqueeError) {
return
}
try {
val configuration = ViewConfiguration.get(
context
)
val claz: Class<*> = configuration.javaClass
val field = claz.getDeclaredField("mFadingMarqueeEnabled")
field.isAccessible = true
field[configuration] = true
} catch (e: Exception) {
e.printStackTrace()
marqueeError = true
}
}
private fun goRoom(
data: AllServiceGiftProtocol.DataBean
) {
if (data.roomUid <= 0L) {
// 非房间场景送的礼物
return
}
if (AllServiceGiftGoRoomTipsDialog.isNeedTips()) {
AllServiceGiftGoRoomTipsDialog(context, data.roomTitle ?: "", data.roomUid).show()
} else {
if (data.roomUid == JavaUtil.str2long(InitialModel.get().publicChatHallUid)) {
PublicChatHallHomeActivity.openPublicChatHallPage(context)
} else {
AVRoomActivity.start(context, data.roomUid)
}
}
}
override fun dismiss() {
super.dismiss()
if (disposable?.isDisposed != true) {
disposable?.dispose()
}
disposable = null
}
}

View File

@@ -1,85 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelOneBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelOneDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelOneBinding binding;
public AllServiceGiftLevelOneDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
giftLevel = ALL_SERVICE_GIFT_LEVEL_1;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_one, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
//MATCH_PARENT会挡住键盘
// wrap_parent在小米8又会截掉一点在华为测试关闭按钮点击不到
//暂时找不到原因,
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_left);
}
if (dataBean != null) {
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
}
binding.ivCloseDialogOne.setOnClickListener(v -> dismiss());
}
}

View File

@@ -1,92 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelThreeBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelThreeDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelThreeBinding binding;
private float screenWidth;
public AllServiceGiftLevelThreeDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_three, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height =WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_fade);
window.getWindowManager().getDefaultDisplay().getSize(point);
screenWidth = point.x;
}
if (dataBean != null) {
binding.giftClose.setOnClickListener(v -> {
dismiss();
});
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
// 设置定时器
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
binding.tvRoomId.setVisibility(dataBean.getRoomUid() == 0 ? View.GONE : View.VISIBLE);
}
}
}

View File

@@ -1,88 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelTwoBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelTwoDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelTwoBinding binding;
private float screenWidth;
public AllServiceGiftLevelTwoDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_two, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height =WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_left);
window.getWindowManager().getDefaultDisplay().getSize(point);
screenWidth = point.x;
}
if (dataBean != null) {
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
// 设置定时器
Observable.timer((long) (dataBean.getNotifyStaySecond()), TimeUnit.SECONDS)
.subscribe(aLong -> dismiss());
binding.setGiftBean(dataBean);
}
binding.ivCloseDialogTwo.setOnClickListener(v -> dismiss());
}
}

View File

@@ -10,6 +10,7 @@ import com.nnbc123.app.ui.im.RouterHandler;
import com.nnbc123.app.ui.webview.CommonWebViewActivity;
import com.nnbc123.core.home.bean.BannerInfo;
import com.nnbc123.library.utils.JavaUtil;
import com.nnbc123.core.home.bean.IRouterData;
import static com.nnbc123.core.home.bean.BannerInfo.*;
@@ -19,43 +20,56 @@ import static com.nnbc123.core.home.bean.BannerInfo.*;
* @author xj
*/
public class CommonJumpHelper {
/**
* 通用跳转
*
* @param context
*/
public static void bannerJump(Context context, BannerInfo bannerInfo) {
public static void bannerJump(Context context, IRouterData bannerInfo) {
int skipType = bannerInfo.getSkipType();
if (skipType == SKIP_TYPE_ROUTER) {
bannerJump(context, JavaUtil.str2int(bannerInfo.getRouterType()), bannerInfo.getRouterValue());
} else {
bannerJump(context, skipType, bannerInfo.getSkipUri());
}
}
/**
* 通用跳转
*
* @param context
*/
public static void bannerJump(Context context, int skipType, String skipContent) {
if (null == context || null == bannerInfo) {
if (null == context) {
return;
}
int skipType = bannerInfo.getSkipType();
String url = bannerInfo.getSkipUri();
switch (skipType) {
case SKIP_TYP_APP:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
RouterHandler.handle(context, JavaUtil.str2int(url), null);
RouterHandler.handle(context, JavaUtil.str2int(skipContent), null);
break;
case SKIP_TYP_CHAT_ROOM:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
AVRoomActivity.start(context, JavaUtil.str2long(url));
AVRoomActivity.start(context, JavaUtil.str2long(skipContent));
break;
case SKIP_TYP_H5:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
Intent intent = new Intent(context, CommonWebViewActivity.class);
intent.putExtra("url", url);
intent.putExtra("url", skipContent);
context.startActivity(intent);
break;
case SKIP_TYPE_ROUTER:
RouterHandler.handle(context, JavaUtil.str2int(bannerInfo.getRouterType()), bannerInfo.getRouterValue());
RouterHandler.handle(context, skipType, skipContent);
break;
default:
break;

View File

@@ -42,6 +42,28 @@ public class SpannableBuilder {
return this;
}
/**
* 支持多個spannable 對同一段文字修改
*
* @param text
* @param what
* @return
*/
public SpannableBuilder append(CharSequence text, Object... what) {
if (TextUtils.isEmpty(text)) return this;
int start = builder.length();
builder.append(text);
for (int i = 0; i < what.length; i++) {
Object o = what[i];
if (o == null) {
continue;
}
builder.setSpan(what[i], start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
return this;
}
public SpannableStringBuilder build() {
return builder;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF283889" />
<stroke
android:width="1dp"
android:color="#FF66B5FF" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF49157D" />
<stroke
android:width="1dp"
android:color="#FFFE9FFF" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#87152D" />
<stroke
android:width="1dp"
android:color="#FFED77" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M12.528,0.898L18.773,5.98C19.55,6.611 20,7.558 20,8.557L20,16.009C20,18.213 18.209,20 16,20L15,20C14.264,20 13.667,19.403 13.667,18.667L13.667,14.346L13.667,14.346C13.667,13.269 12.811,12.391 11.742,12.352L11.667,12.35L8.333,12.35C7.254,12.35 6.374,13.204 6.335,14.271L6.333,14.346L6.333,18.667C6.333,19.403 5.736,20 5,20L4,20L4,20C1.791,20 0,18.213 0,16.009L0,8.557C0,7.558 0.45,6.611 1.227,5.98L7.472,0.898C8.944,-0.299 11.056,-0.299 12.528,0.898Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,7m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="1"
android:fillColor="#141414"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M3.576,6.612C3.792,6.373 4.161,6.353 4.4,6.569L6.381,8.353L9.867,4.483C10.098,4.226 10.493,4.205 10.75,4.436C11.006,4.667 11.027,5.062 10.796,5.319L6.948,9.592L6.937,9.604C6.932,9.61 6.926,9.617 6.92,9.623C6.705,9.862 6.336,9.882 6.097,9.666L3.619,7.436C3.38,7.22 3.361,6.851 3.576,6.612Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,7m-6.5,0a6.5,6.5 0,1 1,13 0a6.5,6.5 0,1 1,-13 0"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="#B3B3C3"
android:fillType="evenOdd"/>
</vector>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="21dp"/>
<solid android:color="#FFE6E6F0"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="21dp"/>
<solid android:color="@color/color_theme"/>
</shape>

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="28dp"
android:background="@drawable/shape_white_20dp_round"
android:paddingBottom="24dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/all_service_gift_room_go_title"
android:textColor="@color/color_1F1B4F"
android:textSize="18dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_go_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/all_service_gift_room_go_tips"
android:textColor="@color/color_1F1B4F"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_room_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:gravity="center_horizontal"
android:textColor="@color/color_9168FA"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_go_tips"
tools:text="Name" />
<ImageView
android:id="@+id/iv_checkbox"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginTop="13dp"
android:scaleType="center"
android:src="@drawable/base_ic_checkbox_unselected"
app:layout_constraintEnd_toStartOf="@id/tv_tips"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_room_name" />
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:text="@string/all_service_gift_room_go_ignore"
android:textColor="@color/color_B3B3C3"
android:textSize="12dp"
app:layout_constraintBottom_toBottomOf="@id/iv_checkbox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_checkbox"
app:layout_constraintTop_toTopOf="@id/iv_checkbox" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginStart="28dp"
android:layout_marginTop="19dp"
android:layout_marginEnd="7.5dp"
android:background="@drawable/shape_e6e6f0_21"
android:gravity="center"
android:text="@string/all_service_gift_room_go_cancel"
android:textColor="@color/white"
android:textSize="16dp"
app:layout_constraintEnd_toStartOf="@id/tv_go"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_checkbox" />
<TextView
android:id="@+id/tv_go"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginStart="7.5dp"
android:layout_marginEnd="28dp"
android:background="@drawable/shape_theme_21"
android:gravity="center"
android:text="@string/all_service_gift_room_go_go"
android:textColor="@color/color_333333"
android:textSize="16dp"
app:layout_constraintBottom_toBottomOf="@id/tv_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_cancel"
app:layout_constraintTop_toTopOf="@id/tv_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</layout>

View File

@@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/all_service_gift_ceremony_background"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="35dp"
android:ellipsize="end"
android:gravity="center"
android:maxEms="5"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="#FBC200"
android:textSize="12dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯-宫泽艾里斯-宫泽艾里斯" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="2dp"
app:cborder_color="#FFEB71"
app:cborder_width="1dp"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:text="送给"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/receiver_nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:ellipsize="end"
android:gravity="center"
android:maxEms="5"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="#FBC200"
android:textSize="12dp"
tools:text="梅利奥达斯-梅利奥达斯-梅利奥达斯" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="2dp"
app:cborder_color="#FFEB71"
app:cborder_width="1dp"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/gift_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:gravity="center"
android:text="@{giftBean.giftName}"
android:textColor="#80F9FF"
android:textSize="12dp"
android:textStyle="bold"
tools:ignore="SpUsage"
tools:text="神邸荣光" />
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center"
android:layout_marginStart="2dp" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:gravity="center"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#80F9FF"
android:textSize="12dp"
android:textStyle="bold"
tools:ignore="SpUsage"
tools:text="x1" />
<ImageView
android:id="@+id/tv_go_room"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_5"
android:src="@drawable/all_service_gift_ceremony_go_to" />
</LinearLayout>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/all_service_gift_bg_1"
app:layout_constraintDimensionRatio="h,375:69"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_avatar_bg"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
app:layout_constraintDimensionRatio="w,89:69"
app:layout_constraintEnd_toEndOf="@id/iv_avatar"
app:layout_constraintStart_toStartOf="@id/iv_avatar"
app:layout_constraintTop_toTopOf="@id/iv_avatar"
tools:background="@color/black" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_content_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.0586" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/iv_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintHeight_percent="0.6376"
app:layout_constraintStart_toStartOf="@id/line_content_start"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/tv_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13dp"
android:layout_marginEnd="4.5dp"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:includeFontPadding="false"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="14dp"
app:layout_constraintBottom_toTopOf="@id/tv_room_name"
app:layout_constraintEnd_toStartOf="@id/iv_gift"
app:layout_constraintStart_toEndOf="@id/iv_avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="XXX 送给 XXX XXXX" />
<TextView
android:id="@+id/tv_room_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="2.5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="4.5dp"
android:includeFontPadding="false"
android:singleLine="true"
android:text="@{giftBean.roomTitle}"
android:textColor="@color/white"
android:textSize="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_room_go"
app:layout_constraintStart_toEndOf="@id/iv_room"
app:layout_constraintTop_toBottomOf="@id/tv_message"
tools:text="X1111111111111111111" />
<TextView
android:id="@+id/tv_room_go"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginEnd="2dp"
android:background="@drawable/all_service_gift_bg_room_go1"
android:gravity="center"
android:paddingHorizontal="7.5dp"
android:singleLine="true"
android:text="@string/all_service_gift_room_go"
android:textColor="@color/white"
android:textSize="10dp"
app:layout_constraintBottom_toBottomOf="@id/tv_room_name"
app:layout_constraintEnd_toStartOf="@id/iv_gift"
app:layout_constraintTop_toTopOf="@id/tv_room_name" />
<ImageView
android:id="@+id/iv_room"
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@drawable/all_service_gift_ic_room"
app:layout_constraintBottom_toBottomOf="@id/tv_room_name"
app:layout_constraintStart_toStartOf="@id/tv_message"
app:layout_constraintTop_toTopOf="@id/tv_room_name" />
<ImageView
android:id="@+id/iv_gift"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintEnd_toStartOf="@id/tv_count"
app:layout_constraintHeight_percent="0.9275"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/black" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_content_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.9413" />
<TextView
android:id="@+id/tv_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxWidth="180dp"
android:singleLine="true"
android:textColor="@color/color_FFE468"
android:textSize="16dp"
android:textStyle="italic|bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/line_content_end"
app:layout_constraintTop_toTopOf="parent"
tools:text="X10000" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_room"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tv_room_name,tv_room_go,iv_room"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/all_service_gift_level_one_background">
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="37dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="66.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_one_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="#FF2F0060"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="56dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="37dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="66.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_one_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="#FF2F0060"
android:textSize="10dp"
tools:text="梅利奥达斯-梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginTop="37dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="53dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/iv_close_dialog_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="13dp"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -1,192 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/all_service_gift_level_three_background">
<TextView
android:id="@+id/tv_room_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="@{@string/click_go + giftBean.roomErbanNo}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="ID:1234567" />
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="17dp"
android:layout_marginTop="56dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="56dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="56dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="梅利奥达斯梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="15dp"
android:layout_marginTop="56dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="75dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/dp_10"
android:layout_marginTop="34dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -1,178 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/all_service_gift_level_two_background">
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="17dp"
android:layout_marginTop="34dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="53dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="34dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_two_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="梅利奥达斯梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="15dp"
android:layout_marginTop="34dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="53dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/ivCloseDialogTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="10dp"
android:layout_marginEnd="11dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -0,0 +1,36 @@
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/iv_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/bg_radish_notice" />
<com.coorchice.library.SuperTextView
android:id="@+id/tv_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:lineSpacingExtra="0dp"
android:lineSpacingMultiplier="0.8"
android:maxLines="2"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@id/iv_bg"
app:layout_constraintEnd_toEndOf="@id/iv_bg"
app:layout_constraintStart_toStartOf="@id/iv_bg"
app:layout_constraintTop_toTopOf="@id/iv_bg"
app:layout_constraintWidth_percent="0.626"
tools:layout_height="wrap_content"
tools:text="Message" />
</merge>

View File

@@ -7,6 +7,7 @@
<color name="color_male">@color/color_529EF2</color>
<color name="color_female">@color/color_FC588F</color>
<color name="color_theme">#FFDA24</color>
<color name="transparent">#00000000</color>
<!-- 透明度参考表
@@ -631,4 +632,7 @@
<color name="color_FFF265">#FFFFF265</color>
<color name="color_5CEFFF">#FF5CEFFF</color>
<color name="color_7F8494">#7F8494</color>
<color name="color_FFE468">#FFFFE468</color>
<color name="color_1F1B4F">#1F1B4F</color>
<color name="color_9168FA">#9168FA</color>
</resources>

View File

@@ -992,4 +992,11 @@
<string name="permission_denied_tips_mic">为了实现连麦及语音输入等功能,请您允许应用向您获取“麦克风”权限</string>
<string name="permission_denied_tips_image">访问你的本地内容,以能正常使用图片上传、视频发送等应用功能</string>
<string name="permission_denied_tips_camera">用于拍摄更新个人头像、发布动态、与客服反馈问题时进行照片和视频的拍摄录制</string>
<string name="all_service_gift_room_go">去围观</string>
<string name="all_service_gift_room_go_title">前往围观</string>
<string name="all_service_gift_room_go_tips">是否离开当前房间前往</string>
<string name="all_service_gift_room_go_ignore">下次不再出现此提示</string>
<string name="all_service_gift_room_go_cancel">留在这</string>
<string name="all_service_gift_room_go_go">立即前往</string>
</resources>

View File

@@ -7,7 +7,7 @@ import java.io.Serializable;
/**
* Created by Administrator on 2017/8/7.
*/
public class BannerInfo implements Parcelable, Serializable {
public class BannerInfo implements Parcelable, Serializable,IRouterData {
/**
* 跳转app
*/
@@ -24,6 +24,10 @@ public class BannerInfo implements Parcelable, Serializable {
* routerhandler跳转规则
*/
public static final transient int SKIP_TYPE_ROUTER = 5;
/**
* 房间用户资料卡
*/
public final static transient int SKIP_TYPE_ROOM_USER_CARD = 6;
/*
bannerId1 //id
bannerName: xx//横幅广告名称

View File

@@ -0,0 +1,20 @@
package com.nnbc123.core.home.bean
import java.io.Serializable
/**
* Created by Max on 2024/2/20 16:43
* Desc:路由跳转参数
**/
interface IRouterData : Serializable {
fun getSkipUri(): String?
fun getSkipType(): Int
@Deprecated("SkipType==5时用到该值后台讲这种已经没用到了")
fun getRouterType(): String?
@Deprecated("SkipType==5时用到该值后台讲这种已经没用到了")
fun getRouterValue(): String?
}

View File

@@ -1451,6 +1451,19 @@ public final class IMNetEaseManager {
addMessages(msg);
}
break;
case CUSTOM_MSG_ROOM_TEMPLATE:
switch (second){
case CUSTOM_MSG_ROOM_TEMPLATE_SUB_ROOM:
case CUSTOM_MSG_ROOM_TEMPLATE_SUB_ALL_ROOM:
addMessages(msg);
break;
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY:
if (second == CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM) {
noticeRoomEvent(msg, RoomEvent.TEMPLATE_NOTIFY);
}
break;
default:
break;
}

View File

@@ -0,0 +1,23 @@
package com.nnbc123.core.bean
import java.io.Serializable
/**
* Created by Max on 2024/2/22 18:36
* Desc:
**/
class I18N : HashMap<String, String>(), Serializable {
/**
* 获取优先显示文本
*/
fun getFirstText(): String? {
// 目前应用只支持繁体,后续支持其他语言,这里需要调整
val content = get("zh-CN")
return if (content.isNullOrEmpty()) {
this.values.firstOrNull()
} else {
content
}
}
}

View File

@@ -70,6 +70,9 @@ import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TY
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_LUCKY_MONEY;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_MULTI_MAGIC;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_SINGLE_MAGIC;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO_AUDIO;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO_CLEAN_SCREEN;
@@ -630,6 +633,20 @@ public class CustomAttachParser implements MsgAttachmentParser {
attachment = new DressUpGiftAttachment(first, second);
}
break;
case CustomAttachment.CUSTOM_MSG_ROOM_TEMPLATE:
if (second == CustomAttachment.CUSTOM_MSG_ROOM_TEMPLATE_SUB_ROOM
|| second == CustomAttachment.CUSTOM_MSG_ROOM_TEMPLATE_SUB_ALL_ROOM) {
attachment = new TemplateMessageAttachment(first, second);
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY:
switch (second) {
case CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM:
case CUSTOM_MSG_TEMPLATE_NOTIFY_ALL:
attachment = new RoomTemplateNotifyAttachment(first, second);
break;
}
break;
default:
LogUtils.e("未定义的first,请现在CustomAttachParser中解析first=" + first + " second=" + second);
break;

View File

@@ -448,6 +448,17 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_GAME_INVITE = 103;//发起邀请
public static final int CUSTOM_MSG_GAME_INVITE_SECOND = 1030;//发起邀请(发起用户)
// 模版消息
public static final int CUSTOM_MSG_ROOM_TEMPLATE = 104;
public static final int CUSTOM_MSG_ROOM_TEMPLATE_SUB_ROOM = 1041;
public static final int CUSTOM_MSG_ROOM_TEMPLATE_SUB_ALL_ROOM = 1042;
// 通用模版飘屏
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY = 105;
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM = 1051;// 通用模版飘屏-房间
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY_ALL = 1052;// 通用模版飘屏-全服
/**
* 自定义消息附件的类型,根据该字段区分不同的自定义消息
*/

View File

@@ -0,0 +1,35 @@
package com.nnbc123.core.im.custom.bean
import com.alibaba.fastjson.JSONObject
import com.google.gson.Gson
/**
* Created by Max on 2024/3/18 10:14
* Desc:通用模版飘窗
**/
class RoomTemplateNotifyAttachment : CustomAttachment {
var msgBean: RoomTemplateNotifyMsgBean? = null
constructor() : super()
constructor(first: Int, second: Int) : super(first, second)
public override fun parseData(data: JSONObject?) {
super.parseData(data)
try {
msgBean = Gson().fromJson<RoomTemplateNotifyMsgBean>(
data!!.toJSONString(),
RoomTemplateNotifyMsgBean::class.java
)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun packData(): JSONObject? {
val jsonStr = Gson().toJson(msgBean)
return JSONObject.parseObject(jsonStr)
}
fun getTemplateMsg() = msgBean
}

View File

@@ -0,0 +1,31 @@
package com.nnbc123.core.im.custom.bean
/**
* Created by Max on 2024/3/15 18:55
* Desc:通用模版飘窗
**/
class RoomTemplateNotifyMsgBean : TemplateMessage() {
var fontSize: Int? = null
// IMAGE、SVGA
var resourceType: String? = null
var resourceContent: String? = null
var skipType: Int? = null
var skipContent: String? = null
var resourceWidth: Int? = null
var resourceHeight: Int? = null
// SVGA-文本的坑位KEY
private var svgaTextKey: String? = null
fun getSvgaTextKey(): String {
return svgaTextKey ?: "noble_text_tx"
}
fun getDimensionRatio(): String? {
if (resourceWidth != null && resourceHeight != null) {
return "$resourceWidth:$resourceHeight"
}
return null
}
}

View File

@@ -0,0 +1,131 @@
package com.nnbc123.core.im.custom.bean
import com.chuhai.utils.StringUtils
import com.nnbc123.core.bean.I18N
import com.nnbc123.core.home.bean.IRouterData
import java.io.Serializable
import java.util.regex.Pattern
/**
* Created by Max on 2024/2/22 18:51
* Desc:
**/
open class TemplateMessage : Serializable {
var template: I18N? = null
var textColor: String? = null
var contents: List<Content>? = null
private val nodeList: List<TemplateNode>? = null
fun getNodeList(): List<TemplateNode> {
var nodeList = this.nodeList
if (nodeList == null) {
nodeList = parseNodes()
}
return nodeList
}
// 转化为方便渲染的节点列表
private fun parseNodes(): List<TemplateNode> {
val templateText = template?.getFirstText()
val contentList = this.contents
val defTextColor = this.textColor
if (templateText.isNullOrEmpty()) {
return emptyList()
}
if (contentList.isNullOrEmpty()) {
return listOf(
TemplateNode.NormalNode(
text = templateText,
textColor = defTextColor
)
)
}
val list = ArrayList<TemplateNode>()
StringUtils.split(
content = templateText,
pattern = Pattern.compile("\\{.+?\\}"),
onNormalNode = {
list.add(
TemplateNode.NormalNode(
text = it,
textColor = defTextColor
)
)
},
onMatchNode = { text ->
val content = contentList.firstOrNull {
"{${it.key}}" == text
}
if (content?.type == Content.TEXT && content.textColor.isNullOrEmpty()) {
// 默认文本色
content.textColor = textColor
}
if (content != null) {
list.add(
TemplateNode.SpecialNode(
content = content
)
)
}
})
return list
}
class Content : Serializable, IRouterData {
/**
* 公共字段
*/
val key: String? = null
// TEXT,IMAGE
val type: String? = null
val skipType: Int? = null
val skipContent: String? = null
/**
* 文本相关字段(type=TEXT)
*/
val text: I18N? = null
var textColor: String? = null
/**
* 图片相关字段(type=IMAGE)
*/
val image: String? = null
val width: Int? = null
val height: Int? = null
override fun getSkipType(): Int {
return skipType ?: 0
}
override fun getRouterType(): String? {
return null
}
override fun getRouterValue(): String? {
return null
}
override fun getSkipUri(): String? {
return skipContent
}
companion object {
const val TEXT = "TEXT"
const val IMAGE = "IMAGE"
}
}
interface TemplateNode : Serializable {
data class NormalNode(
var text: String,
var textColor: String? = null
) : TemplateNode
data class SpecialNode(
var content: Content
) : TemplateNode
}
}

View File

@@ -0,0 +1,32 @@
package com.nnbc123.core.im.custom.bean;
import com.alibaba.fastjson.JSONObject
import com.google.gson.Gson
/**
* Created by Max on 2024/2/22 17:28
* Desc:
**/
class TemplateMessageAttachment : CustomAttachment {
constructor() : super()
constructor(first: Int, second: Int) : super(first, second)
private var templateMessage: TemplateMessage? = null
fun getTemplateMessage() = templateMessage
override fun parseData(data: JSONObject?) {
super.parseData(data)
if (data != null) {
try {
templateMessage = Gson().fromJson<TemplateMessage>(
data.toJSONString(),
TemplateMessage::class.java
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}

View File

@@ -260,6 +260,9 @@ public class RoomEvent {
// 小时榜更新
public static final int ROOM_HOUR_RANK = 103;
//通用模版飘屏
public static final int TEMPLATE_NOTIFY = 112;
private int event = NONE;
private int micPosition = Integer.MIN_VALUE;
private int posState = -1;

View File

@@ -28,5 +28,5 @@ COMPILE_SDK_VERSION=32
MIN_SDK_VERSION=21
TARGET_SDK_VERSION=32
version_name=2.0.0
version_code=2000
version_name=2.1.3
version_code=2103

View File

@@ -0,0 +1,64 @@
package com.chuhai.utils
import java.util.regex.Pattern
/**
* Created by Max on 2/10/21 4:56 PM
* Desc:字符串工具
*/
object StringUtils {
/**
* 拆分字符串(根据匹配规则,按顺序拆分出来)
* @param pattern 匹配节点的规则模式
* @param onNormalNode<节点内容> 普通节点
* @param onMatchNode<节点内容> 匹配节点
*/
fun split(
content: String,
pattern: Pattern,
onNormalNode: (String) -> Unit,
onMatchNode: (String) -> Unit,
) {
try {
if (content.isEmpty()) {
onNormalNode.invoke(content)
return
}
val matcher = pattern.matcher(content)
// 最后一个匹配项的结束位置
var lastItemEnd = 0
var noMatch = true
while (matcher.find()) {
noMatch = false
// 匹配元素的开启位置
val start = matcher.start()
// 匹配元素的结束位置
val end = matcher.end()
// 匹配元素的文本
val text = matcher.group()
// 匹配元素的对应索引
// logD("split() start:$start ,end:$end ,text:$text")
if (start > lastItemEnd) {
// 普通节点
val nodeContent = content.substring(lastItemEnd, start)
onNormalNode.invoke(nodeContent)
}
// 匹配节点显示内容
onMatchNode.invoke(text)
lastItemEnd = end
}
if (lastItemEnd > 0 && lastItemEnd < content.length) {
// 最后的匹配项不是尾部(追加最后的尾部)
val nodeContent = content.substring(lastItemEnd, content.length)
onNormalNode.invoke(nodeContent)
}
if (noMatch) {
// 无匹配
onNormalNode.invoke(content)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}