From cd79f0ec3a9cb167e49a0411cb5cabab5bcaaa74 Mon Sep 17 00:00:00 2001 From: huangjian Date: Thu, 18 Aug 2022 10:10:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=82=E9=B8=A6=E7=A4=BC=E7=89=A9=E5=88=9D?= =?UTF-8?q?=E7=89=88=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../erban/avroom/ButtonItemFactory.java | 21 - .../erban/avroom/fragment/BaseRoomFragment.kt | 20 +- .../erban/avroom/widget/GiftV2View.java | 9 + .../OnGiftDialogBtnClickListenerWrapper.java | 7 +- .../erban/ui/gift/dialog/GiftGridView.java | 28 +- .../erban/ui/gift/dialog/MagicInfoVm.java | 37 -- .../erban/ui/im/actions/GiftAction.java | 27 +- .../yizhuan/erban/ui/widget/GiftDialog.java | 561 +++++------------- .../ui/widget/drawgift/DrawGiftHelper.java | 252 ++++++++ .../ui/widget/drawgift/DrawGiftModel.java | 67 +++ .../ui/widget/drawgift/DrawGiftPlayView.java | 217 +++++++ .../ui/widget/drawgift/DrawGiftView.java | 325 ++++++++++ .../widget/magicindicator/GiftIndicator.java | 3 + .../drawable-xhdpi/drawgift_placeholder.png | Bin 0 -> 2907 bytes .../main/res/layout/dialog_bottom_gift.xml | 12 - .../res/layout/list_item_dialog_magic.xml | 63 -- .../activity/MWTeamRoomMessageAct.java | 3 +- .../MiniWorldTeamMessageActivity.java | 3 +- .../PublicChatHallMessageFragment.java | 3 +- .../xchat_android_core/gift/GiftModel.java | 57 +- .../xchat_android_core/gift/IGiftModel.java | 15 +- .../gift/bean/GiftInfo.java | 2 + .../gift/bean/GiftMultiReceiverInfo.java | 2 + .../gift/bean/GiftReceiveInfo.java | 1 + .../gift/toolbox/GiftToolbox.java | 1 + .../im/custom/bean/GiftAttachment.java | 18 +- .../bindinglist/MultiTypeAdapter.java | 135 ++--- 27 files changed, 1190 insertions(+), 699 deletions(-) delete mode 100644 app/src/main/java/com/yizhuan/erban/ui/gift/dialog/MagicInfoVm.java create mode 100644 app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftHelper.java create mode 100644 app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftModel.java create mode 100644 app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftPlayView.java create mode 100644 app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftView.java create mode 100644 app/src/main/res/drawable-xhdpi/drawgift_placeholder.png delete mode 100644 app/src/main/res/layout/list_item_dialog_magic.xml diff --git a/app/src/main/java/com/yizhuan/erban/avroom/ButtonItemFactory.java b/app/src/main/java/com/yizhuan/erban/avroom/ButtonItemFactory.java index 06cd47ce8..c90b7e620 100644 --- a/app/src/main/java/com/yizhuan/erban/avroom/ButtonItemFactory.java +++ b/app/src/main/java/com/yizhuan/erban/avroom/ButtonItemFactory.java @@ -110,7 +110,6 @@ public class ButtonItemFactory { List buttonItems = new ArrayList<>(); //ture则表示需要传入此类型button boolean gift = false; - boolean magic = false; if (isNeedGiftItem) { gift = true; } @@ -162,9 +161,6 @@ public class ButtonItemFactory { buttonItems.add(createSendGiftItem(context, uid, isInRoom, listener)); } } - if (magic) { - buttonItems.add(createSendMagicItem(context, account, isInRoom, listener)); - } // 私聊 buttonItems.add(createPrivateChatItem(context, account, isInRoom)); @@ -268,23 +264,6 @@ public class ButtonItemFactory { } - /** - * 送魔法 - */ - public static ViewItem createSendMagicItem(final Context context, String account, boolean isInRoom, - final GiftDialog.OnGiftDialogBtnClickListener listener) { - return new ViewItem("施魔法", R.drawable.icon_dialog_send_magic, () -> { - StatisticManager.Instance().onEvent(StatisticsProtocol.data_card_magic_send_click, "资料卡片-送魔法"); - - GiftDialog dialog = new GiftDialog(context, JavaUtil.str2long(account), isInRoom, true); - if (listener != null) { - dialog.setGiftDialogBtnClickListener(listener); - } - dialog.show(); - }); - } - - /** * 私聊 */ diff --git a/app/src/main/java/com/yizhuan/erban/avroom/fragment/BaseRoomFragment.kt b/app/src/main/java/com/yizhuan/erban/avroom/fragment/BaseRoomFragment.kt index 1ee655d6f..d4cf12a69 100644 --- a/app/src/main/java/com/yizhuan/erban/avroom/fragment/BaseRoomFragment.kt +++ b/app/src/main/java/com/yizhuan/erban/avroom/fragment/BaseRoomFragment.kt @@ -683,16 +683,21 @@ open class BaseRoomFragment?> : @SuppressLint("CheckResult") override fun onSendGiftBtnClick( - giftInfo: GiftInfo, micMemberInfos: ArrayList, - number: Int, msg: String?, isKnap: Boolean, - isWholdMic: Boolean, callback: SenGiftCallback + giftInfo: GiftInfo, + micMemberInfos: ArrayList, + number: Int, + msg: String?, + isKnap: Boolean, + isWholdMic: Boolean, + drawFixedArray: List>, + callback: SenGiftCallback ) { val targetUids: MutableList = ArrayList() for (i in micMemberInfos.indices) { targetUids.add(micMemberInfos[i].account.toLong()) } GiftModel.get() - .sendRoomGift(giftInfo.giftId, targetUids, number, msg, isKnap, isWholdMic) + .sendRoomGift(giftInfo.giftId, targetUids, number, msg, isKnap, isWholdMic,drawFixedArray) .compose(bindUntilEvent(FragmentEvent.DESTROY)) .doOnError { if (it is VipLevelNotEnoughException) { @@ -713,13 +718,6 @@ open class BaseRoomFragment?> : } } - override fun onSendMagicBtnClick( - magicInfo: MagicInfo, - targetUid: Long, - callback: SenGiftCallback - ) { - } - private fun onUpMicro(micPosition: Int) { showBottomViewForDifRole() updateMicBtn() diff --git a/app/src/main/java/com/yizhuan/erban/avroom/widget/GiftV2View.java b/app/src/main/java/com/yizhuan/erban/avroom/widget/GiftV2View.java index 75360606b..82525109c 100644 --- a/app/src/main/java/com/yizhuan/erban/avroom/widget/GiftV2View.java +++ b/app/src/main/java/com/yizhuan/erban/avroom/widget/GiftV2View.java @@ -35,6 +35,7 @@ import com.opensource.svgaplayer.SVGAVideoEntity; import com.yizhuan.erban.R; import com.yizhuan.erban.common.svga.SimpleSvgaParseCompletion; import com.yizhuan.erban.ui.utils.ImageLoadUtils; +import com.yizhuan.erban.ui.widget.drawgift.DrawGiftHelper; import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil; import com.yizhuan.xchat_android_core.auth.AuthModel; import com.yizhuan.xchat_android_core.fansteam.FansTeamMsgInfo; @@ -57,6 +58,7 @@ import com.yizhuan.xchat_android_core.manager.IMNetEaseManager; import com.yizhuan.xchat_android_core.manager.RoomEvent; import com.yizhuan.xchat_android_core.monsterhunting.bean.MonsterAttackInfo; import com.yizhuan.xchat_android_core.room.bean.RoomInfo; +import com.yizhuan.xchat_android_core.utils.LogUtils; import com.yizhuan.xchat_android_library.utils.ResolutionUtils; import java.lang.ref.WeakReference; @@ -98,6 +100,7 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect private Keyframe[] keyTrans; private SvgaObjectPool mMagicViewPool; private volatile Hashtable currentAnimationMap = new Hashtable<>(); + private DrawGiftHelper drawGiftHelper; public GiftV2View(Context context) { @@ -279,6 +282,12 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect targetUsers.add(giftReceiver); } GiftReceiveInfo giftReceiveInfo = giftReceiveInfos.get(0); + if (giftReceiveInfo.getDrawFixedArray() != null) { + if (drawGiftHelper == null) { + drawGiftHelper = new DrawGiftHelper((Activity) context); + } + drawGiftHelper.prepareShowDrawGift(giftReceiveInfo.getDrawFixedArray(), false); + } GiftInfo giftInfo = giftReceiveInfo.getGift(); if (totalCoin >= 520 || (giftInfo != null && giftInfo.isHasEffect())) { Message msg = Message.obtain(); diff --git a/app/src/main/java/com/yizhuan/erban/ui/gift/callback/OnGiftDialogBtnClickListenerWrapper.java b/app/src/main/java/com/yizhuan/erban/ui/gift/callback/OnGiftDialogBtnClickListenerWrapper.java index 781a4d7ba..12ff0bc1e 100644 --- a/app/src/main/java/com/yizhuan/erban/ui/gift/callback/OnGiftDialogBtnClickListenerWrapper.java +++ b/app/src/main/java/com/yizhuan/erban/ui/gift/callback/OnGiftDialogBtnClickListenerWrapper.java @@ -6,16 +6,13 @@ import com.yizhuan.xchat_android_core.magic.bean.MagicInfo; import com.yizhuan.xchat_android_core.room.queue.bean.MicMemberInfo; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class OnGiftDialogBtnClickListenerWrapper implements GiftDialog.OnGiftDialogBtnClickListener { @Override - public void onSendGiftBtnClick(GiftInfo giftInfo, ArrayList micMemberInfos, int number, String msg, boolean isKnap, boolean isWholeMic, GiftDialog.SenGiftCallback callback) { + public void onSendGiftBtnClick(GiftInfo giftInfo, ArrayList micMemberInfos, int number, String msg, boolean isKnap, boolean isWholeMic, List> drawFixedArray, GiftDialog.SenGiftCallback callback) { } - @Override - public void onSendMagicBtnClick(MagicInfo magicInfo, long targetUid, GiftDialog.SenGiftCallback callback) { - - } } diff --git a/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/GiftGridView.java b/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/GiftGridView.java index 82eb678aa..97bee7fe5 100644 --- a/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/GiftGridView.java +++ b/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/GiftGridView.java @@ -1,18 +1,18 @@ package com.yizhuan.erban.ui.gift.dialog; import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.viewpager.widget.PagerAdapter; -import androidx.viewpager.widget.ViewPager; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.util.AttributeSet; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; -import com.orhanobut.logger.Logger; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + import com.yizhuan.erban.BR; import com.yizhuan.xchat_android_core.gift.bean.GiftInfo; import com.yizhuan.xchat_android_core.magic.bean.MagicInfo; @@ -151,13 +151,8 @@ public class GiftGridView extends ViewPager { page = result.get(result.size() - 1); } } - if (data.get(i) instanceof GiftInfo) { - item = createGiftItem(context, (GiftInfo) data.get(i), i == 0, isKnap); - } else if (data.get(i) instanceof MagicInfo) { - item = createMagicItem(context, (MagicInfo) data.get(i), i == 0); - } - Logger.i("pos:" + i + ", item:" + item + ", page:" + page); - if (item != null && page != null) { + item = createGiftItem(context, (GiftInfo) data.get(i), i == 0, isKnap); + if (page != null) { page.add(item); } } @@ -167,9 +162,4 @@ public class GiftGridView extends ViewPager { public static GiftInfoVm createGiftItem(Context context, GiftInfo giftInfo, boolean select, boolean isKnap) { return new GiftInfoVm(context, giftInfo, select, isKnap); } - - public static MagicInfoVm createMagicItem(Context context, MagicInfo magicInfo, boolean select) { - return new MagicInfoVm(context, magicInfo, select); - } - } diff --git a/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/MagicInfoVm.java b/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/MagicInfoVm.java deleted file mode 100644 index a49643856..000000000 --- a/app/src/main/java/com/yizhuan/erban/ui/gift/dialog/MagicInfoVm.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.yizhuan.erban.ui.gift.dialog; - -import android.content.Context; -import androidx.databinding.ObservableBoolean; -import androidx.databinding.ObservableField; - -import com.yizhuan.erban.R; -import com.yizhuan.xchat_android_core.magic.bean.MagicInfo; -import com.yizhuan.xchat_android_library.bindinglist.BaseItem; - -/** - * 魔法 - * Created by lvzebiao on 2018/11/20. - */ - -public class MagicInfoVm extends BaseItem { - - public final ObservableBoolean isSelect = new ObservableBoolean(); - - public final ObservableField goldText = new ObservableField<>(); - - @Override - public MagicInfo data() { - return super.data(); - } - - public MagicInfoVm(Context context, MagicInfo data, boolean select) { - super(context, data); - this.isSelect.set(select); - this.goldText.set(data.getPrice() + "钻石"); - } - - @Override - public int getType() { - return R.layout.list_item_dialog_magic; - } -} diff --git a/app/src/main/java/com/yizhuan/erban/ui/im/actions/GiftAction.java b/app/src/main/java/com/yizhuan/erban/ui/im/actions/GiftAction.java index fd3b45664..59925c5c5 100644 --- a/app/src/main/java/com/yizhuan/erban/ui/im/actions/GiftAction.java +++ b/app/src/main/java/com/yizhuan/erban/ui/im/actions/GiftAction.java @@ -22,6 +22,8 @@ import com.yizhuan.xchat_android_core.utils.net.VipLevelNotEnoughException; import com.yizhuan.xchat_android_library.utils.SingleToastUtil; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; /** * Created by xiaoyu @@ -53,7 +55,7 @@ public class GiftAction extends BaseAction implements GiftDialog.OnGiftDialogBtn @SuppressLint("CheckResult") @Override - public void onSendGiftBtnClick(GiftInfo giftInfo, ArrayList micMemberInfos, int number, String msg, boolean isknap, boolean isWholeMic, GiftDialog.SenGiftCallback callback) { + public void onSendGiftBtnClick(GiftInfo giftInfo, ArrayList micMemberInfos, int number, String msg, boolean isknap, boolean isWholeMic, List> drawFixedArray, GiftDialog.SenGiftCallback callback) { if (giftInfo == null) return; GiftModel.get().sendPersonalGift(giftInfo.getGiftId(), micMemberInfos.get(0).getAccount(), number, msg, isknap) .doOnError(throwable -> { @@ -80,27 +82,4 @@ public class GiftAction extends BaseAction implements GiftDialog.OnGiftDialogBtn } - @Override - public void onSendMagicBtnClick(MagicInfo magicInfo, long targetUid, GiftDialog.SenGiftCallback callback) { - //赠送魔法的回调 - MagicModel.get().sendMagic(magicInfo.getMagicId(), targetUid) - .subscribe(new BeanObserver() { - @Override - public void onErrorMsg(String error) { - SingleToastUtil.showToast(error); - if (callback != null) { - callback.onFail(); - } - } - - @Override - public void onSuccess(MagicReceivedInfo info) { - PayModel.get().decreaseLocalGold(magicInfo.getPrice()); - if (callback != null) { - callback.onSuccess(); - } - } - }); - } - } \ No newline at end of file diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/GiftDialog.java b/app/src/main/java/com/yizhuan/erban/ui/widget/GiftDialog.java index c1ee1ac06..2975f9679 100644 --- a/app/src/main/java/com/yizhuan/erban/ui/widget/GiftDialog.java +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/GiftDialog.java @@ -1,28 +1,12 @@ package com.yizhuan.erban.ui.widget; import android.annotation.SuppressLint; - -import androidx.annotation.Nullable; -import androidx.lifecycle.Observer; - +import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; - -import androidx.annotation.NonNull; - -import com.google.android.material.bottomsheet.BottomSheetBehavior; -import com.google.android.material.bottomsheet.BottomSheetDialog; - -import androidx.viewpager.widget.PagerAdapter; -import androidx.viewpager.widget.ViewPager; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - import android.text.Editable; import android.text.TextUtils; -import android.text.TextWatcher; import android.text.style.ForegroundColorSpan; import android.util.DisplayMetrics; import android.util.Log; @@ -40,6 +24,16 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; import com.trello.rxlifecycle3.components.support.RxAppCompatActivity; import com.yizhuan.erban.BR; import com.yizhuan.erban.R; @@ -48,16 +42,15 @@ import com.yizhuan.erban.base.BaseActivity; import com.yizhuan.erban.common.widget.CircleImageView; import com.yizhuan.erban.common.widget.dialog.DialogManager; import com.yizhuan.erban.radish.task.activity.TaskCenterActivity; -import com.yizhuan.erban.radish.wallet.RadishWalletManager; import com.yizhuan.erban.ui.gift.dialog.GiftInfoVm; -import com.yizhuan.erban.ui.gift.dialog.MagicInfoVm; import com.yizhuan.erban.ui.gift.dialog.PageIndicatorView; import com.yizhuan.erban.ui.pay.ChargeActivity; import com.yizhuan.erban.ui.pay.ChargeDialog; import com.yizhuan.erban.ui.utils.ImageLoadUtils; import com.yizhuan.erban.ui.webview.DialogWebViewActivity; import com.yizhuan.erban.ui.widget.dialog.GiftManualQuantityDialog; -import com.yizhuan.erban.ui.widget.higuide.TuTuGuideHelper; +import com.yizhuan.erban.ui.widget.drawgift.DrawGiftHelper; +import com.yizhuan.erban.ui.widget.drawgift.DrawGiftView; import com.yizhuan.erban.ui.widget.magicindicator.GiftIndicator; import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil; import com.yizhuan.erban.ui.widget.recyclerview.decoration.VerticalDecoration; @@ -84,8 +77,6 @@ import com.yizhuan.xchat_android_core.pay.PayModel; import com.yizhuan.xchat_android_core.pay.bean.WalletInfo; import com.yizhuan.xchat_android_core.pay.event.FirstChargeEvent; import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent; -import com.yizhuan.xchat_android_core.radish.RadishModel; -import com.yizhuan.xchat_android_core.radish.RadishWalletInfo; import com.yizhuan.xchat_android_core.room.anotherroompk.ShowUserInfoDialogEvent; import com.yizhuan.xchat_android_core.room.pk.model.PkModel; import com.yizhuan.xchat_android_core.room.queue.bean.MicMemberInfo; @@ -93,7 +84,6 @@ import com.yizhuan.xchat_android_core.statistic.StatisticManager; import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol; import com.yizhuan.xchat_android_core.user.UserModel; import com.yizhuan.xchat_android_core.user.bean.UserInfo; -import com.yizhuan.xchat_android_core.utils.ActivityUtil; import com.yizhuan.xchat_android_core.utils.StringExtensionKt; import com.yizhuan.xchat_android_core.utils.net.BalanceNotEnoughExeption; import com.yizhuan.xchat_android_core.utils.net.FreezeException; @@ -103,6 +93,7 @@ import com.yizhuan.xchat_android_library.bindinglist.MultiTypeAdapter; import com.yizhuan.xchat_android_library.utils.FormatUtils; import com.yizhuan.xchat_android_library.utils.ListUtils; import com.yizhuan.xchat_android_library.utils.SingleToastUtil; +import com.yizhuan.xchat_android_library.utils.TextWatcherWrapper; import com.zyyoona7.lib.EasyPopup; import com.zyyoona7.lib.HorizontalGravity; import com.zyyoona7.lib.VerticalGravity; @@ -112,6 +103,7 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -119,7 +111,6 @@ import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; /** * @author chenran @@ -132,19 +123,25 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene private static final int ITEM_TYPE_GOLD = 0; // 钻石 private static final int ITEM_TYPE_RADISH = 1; // 萝卜 public static String GIFT_DIALOG_FROM = ""; // 埋点用,标识从哪个位置打开弹框 - private Context context; + private final Context context; + /** + * 被送礼物的人的uid + */ + private final long uid; + private final int giftId; + private final boolean isInRoom; + /** + * 被选中的uid是否在麦上 + */ + private final boolean userOnMic; + private View mContentView; private ViewPager gridView; private PageIndicatorView indicatorView; private RecyclerView avatarList; private GiftAvatarAdapter avatarListAdapter; @Nullable private GiftInfo currentGiftInfo; - /** - * 当前选中的魔法礼物 - */ - private MagicInfo currentMagicInfo; private List currentGiftInfoList; - private List currentMagicInfoList; private OnGiftDialogBtnClickListener giftDialogBtnClickListener; private CircleImageView avatarImage; private TextView nickText; @@ -165,54 +162,30 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene private GiftIndicator giftIndicator; private int giftNumber = 1; private View sendContainer; - private Button btnSendMagic; private TextView tvTextGold; private TextView tvRecharge; - private ImageView ivAvatarCharm; private ImageView ivAvatarLevel; private TextView tvNickCharm; private TextView tvNickLevel; private View llWeekIn; private View llStarWeek; - /** - * 被送礼物的人的uid - */ - private long uid; - private int giftId; private List micMemberInfos; private View giftNumLayout; private Disposable mSubscribe; private CompositeDisposable compositeDisposable; - private boolean isMagic; - private boolean isInRoom; - /** - * ture则隐藏魔法,默认false - */ - private boolean isHideMagicTab; - /** - * 被选中的uid是否在麦上 - */ - private boolean userOnMic; - private IItem LastSelectedItem; - private List> pagerList; - private Observer radishObserver; - private RadishWalletInfo radishWalletInfo; + private GiftInfoVm lastSelectedItem; + private List> pagerList; private WalletInfo goldWalletInfo; private int itemType = ITEM_TYPE_GOLD; + @Nullable + private DrawGiftHelper drawGiftHelper; + public GiftDialog(Context context, int giftId) { this(context, 0, true, false, true, giftId); } - public GiftDialog(Context context, long OtherUid, boolean isInRoom) { - this(context, OtherUid, isInRoom, false); - } - - public GiftDialog(Context context, long OtherUid, boolean isInRoom, boolean isMagic) { - this(context, OtherUid, isInRoom, isMagic, true); - } - public GiftDialog(Context context, long OtherUid, boolean isInRoom, boolean isMagic, boolean isHideMagicTab) { this(context, OtherUid, isInRoom, isMagic, isHideMagicTab, 0); } @@ -225,7 +198,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene * false表示不在房间,此时OtherUid就是被赠送人的ID * @param isHideMagicTab true则隐藏魔法,默认false */ - public GiftDialog(Context context, long OtherUid, boolean isInRoom, boolean isMagic, boolean isHideMagicTab, int giftId) { + public GiftDialog(Context context, long OtherUid, boolean isInRoom, @Deprecated boolean isMagic, @Deprecated boolean isHideMagicTab, int giftId) { super(context, R.style.ErbanBottomSheetDialogDimFalse); this.context = context; this.uid = OtherUid; @@ -233,25 +206,23 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene this.micMemberInfos = new ArrayList<>(); this.micMemberInfos.addAll(transformAvatarList(OtherUid)); this.isInRoom = isInRoom; - this.isMagic = isMagic; - this.isHideMagicTab = isHideMagicTab; //判断用户在不在麦上 this.userOnMic = AvRoomDataManager.get().checkIsOnMicByAccount(String.valueOf(uid)); } - private static List> beanTransformVm(Context context, - List data, - boolean isKnap, - int pageSize, - @Nullable GiftInfo selectGiftInfo) { - List> result = new ArrayList<>(); + private List> beanTransformVm(Context context, + List data, + boolean isKnap, + int pageSize, + @Nullable GiftInfo selectGiftInfo) { + List> result = new ArrayList<>(); if (ListUtils.isListEmpty(data)) { return result; } boolean hasSelectGift = false; for (int i = 0; i < data.size(); i++) { - IItem item = null; - List page = null; + GiftInfoVm item = null; + List page = null; if (i % pageSize == 0) { page = new ArrayList<>(); result.add(page); @@ -261,34 +232,22 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } } - if (data.get(i) instanceof GiftInfo) { - boolean select = false; - if (selectGiftInfo != null && selectGiftInfo.getGiftId() == ((GiftInfo) data.get(i)).getGiftId()) { - hasSelectGift = true; - select = true; - } - item = createGiftItem(context, (GiftInfo) data.get(i), select, isKnap); - } else if (data.get(i) instanceof MagicInfo) { - item = createMagicItem(context, (MagicInfo) data.get(i), i == 0); + boolean select = false; + if (selectGiftInfo != null && selectGiftInfo.getGiftId() == data.get(i).getGiftId()) { + hasSelectGift = true; + select = true; } - if (item != null && page != null) { + item = new GiftInfoVm(context, data.get(i), select, isKnap); + if (page != null) { page.add(item); } } - if (!hasSelectGift && result.get(0).get(0) instanceof GiftInfoVm) { - ((GiftInfoVm) result.get(0).get(0)).isSelect.set(true); + if (!hasSelectGift) { + result.get(0).get(0).isSelect.set(true); } return result; } - private static GiftInfoVm createGiftItem(Context context, GiftInfo giftInfo, boolean select, boolean isKnap) { - return new GiftInfoVm(context, giftInfo, select, isKnap); - } - - private static MagicInfoVm createMagicItem(Context context, MagicInfo magicInfo, boolean select) { - return new MagicInfoVm(context, magicInfo, select); - } - public void setGiftDialogBtnClickListener(OnGiftDialogBtnClickListener giftDialogBtnClickListener) { this.giftDialogBtnClickListener = giftDialogBtnClickListener; } @@ -357,7 +316,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene setCanceledOnTouchOutside(true); setContentView(R.layout.dialog_bottom_gift); compositeDisposable = new CompositeDisposable(); - init(findViewById(R.id.ll_dialog_bottom_gift)); + mContentView = findViewById(R.id.ll_dialog_bottom_gift); + init(mContentView); FrameLayout bottomSheet = findViewById(R.id.design_bottom_sheet); if (bottomSheet != null) { BottomSheetBehavior.from(bottomSheet).setSkipCollapsed(false); @@ -411,8 +371,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NORMAL, "礼物", "礼物")); tabInfoList.add(new GiftTab(GiftIndicator.TYPE_LUCKY, "幸运礼物", "幸运礼物")); tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NOBLE, "贵族", "贵族")); - tabInfoList.add(new GiftTab(GiftIndicator.TYPE_MAGIC, "魔法", "魔法")); tabInfoList.add(new GiftTab(GiftIndicator.TYPE_WEEK, "周星礼物", "周星礼物")); + tabInfoList.add(new GiftTab(GiftIndicator.TYPE_DRAW_GIFT, "涂鸦礼物", "涂鸦礼物")); tabInfoList.add(new GiftTab(GiftIndicator.TYPE_KNAP, "背包", "背包")); giftIndicator = root.findViewById(R.id.gift_indicator); giftIndicator.initTab( @@ -432,11 +392,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } }); - if (isHideMagicTab) { - giftIndicator.hidePosition(GiftIndicator.TYPE_MAGIC); - } else { - giftIndicator.showPosition(GiftIndicator.TYPE_MAGIC); - } if (isInRoom) { giftIndicator.showPosition(GiftIndicator.TYPE_LUCKY); } else { @@ -469,8 +424,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene etSendMessage = root.findViewById(R.id.et_gift_message); ivOpenNoble.setOnClickListener(this); sendContainer = root.findViewById(R.id.send_container); - btnSendMagic = root.findViewById(R.id.btn_sendMagic); - btnSendMagic.setOnClickListener(this); layoutEmpty.setVisibility(View.GONE); ivFirstRecharge = root.findViewById(R.id.iv_first_recharge); tvLuckyBagIntro = root.findViewById(R.id.tv_lucky_bag_intro); @@ -516,21 +469,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene avatarListAdapter.setMicMemberInfos(micMemberInfos); avatarListAdapter.setOnItemSelectedListener(this); avatarList.setAdapter(avatarListAdapter); - - //添加高亮引导 - if (TuTuGuideHelper.isNeedHiGuide(TuTuGuideHelper.KEY_GUIDE_GIFT_DIALOG)) { - avatarList.post(() -> { - if (!ActivityUtil.isValidContext(context)) { - return; - } - if (!GiftDialog.this.isShowing()) { - return; - } - TuTuGuideHelper.setNoNeedHiGuide(TuTuGuideHelper.KEY_GUIDE_GIFT_DIALOG); - TuTuGuideHelper helper = new TuTuGuideHelper(context, GiftDialog.this); - helper.createHiGuide(() -> helper.createGiftDialogOverLayer(avatarList)); - }); - } } } else { avatarList.setVisibility(View.INVISIBLE); @@ -547,17 +485,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene }); } - etSendMessage.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - - } - + etSendMessage.addTextChangedListener(new TextWatcherWrapper() { @Override public void afterTextChanged(Editable s) { if (s.toString().trim().length() > 15) { @@ -568,15 +496,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene }); compositeDisposable.add(GiftModel.get().requestKnapGiftInfos().subscribe()); - radishObserver = info -> { - if (info == null) { - return; - } - radishWalletInfo = info; - setTvGoldText(); - }; - RadishWalletManager.get().getLdRadishNumber().observeForever(radishObserver); - RadishModel.get().updateRadishWallet().subscribe(); if (isInRoom) { UserModel.get().getCurrentUserInfo() .compose(RxHelper.bindContext(context)) @@ -621,19 +540,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene sendGiftButton.setEnabled(false); setUpdateTipsText(); } - } else if (lastSelectedItem instanceof MagicInfoVm) { - MagicInfoVm magicInfoVm = (MagicInfoVm) lastSelectedItem; - MagicInfo magicInfo = magicInfoVm.data; - btnSendMagic.setEnabled(true); - switch (magicInfo.getConsumeType()) { - case GiftInfo.CONSUME_TYPE_GOLD: - setTvGoldText(); - break; - default: - // 未匹配的类型,不允许进行交易 - btnSendMagic.setEnabled(false); - setUpdateTipsText(); - } } } @@ -658,37 +564,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene tvTextGold.setText(context.getText(R.string.text_need_update)); } - private void updateMagicView() { - btnSendMagic.setVisibility(View.VISIBLE); - sendContainer.setVisibility(View.GONE); - currentGiftInfo = null; - List nobleGiftInfos = getNobleGiftInfos(); - if (ListUtils.isListEmpty(nobleGiftInfos)) { - giftIndicator.hidePosition(GiftIndicator.TYPE_NOBLE); - } else { - giftIndicator.showPosition(GiftIndicator.TYPE_NOBLE); - } - if (ListUtils.isListEmpty(currentMagicInfoList)) { - showEmptyView(); - return; - } - currentMagicInfo = currentMagicInfoList.get(0); - etSendMessage.setVisibility(View.GONE); - List> pagerList = beanTransformVm(context, currentMagicInfoList, false, 8, null); - setGridViewData(pagerList); - } - private void updateGiftView(int position) { updateGiftView(position, null); } private void updateGiftView(int position, @Nullable GiftInfo selectGiftInfo) { - if (position == GiftIndicator.TYPE_MAGIC) { - updateMagicView(); - return; - } showDataView(); - currentMagicInfo = null; // 获得对应的普通礼物/贵族礼物/背包礼物 List nobleGiftInfos = getNobleGiftInfos(); if (position == GiftIndicator.TYPE_KNAP) { @@ -702,6 +583,22 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene currentGiftInfoList = getLuckyGiftInfos(); } else if (position == GiftIndicator.TYPE_WEEK) { currentGiftInfoList = getWeekStarGiftInfos(); + } else if (position == GiftIndicator.TYPE_DRAW_GIFT) { + currentGiftInfoList = getNormalGiftInfos(); + if (drawGiftHelper == null) { + drawGiftHelper = new DrawGiftHelper((Activity) context); + } + drawGiftHelper.lazyDrawGiftView(mContentView.getHeight(), new DrawGiftView.DrawGiftListener() { + @Override + public void onGiftPainted(DrawGiftView drawGiftView, int giftId) { + + } + + @Override + public void onTouchEventUpWhenDrawDisable(DrawGiftView drawGiftView) { + dismiss(); + } + }); } // 有贵族礼物才显示贵族礼物的tab if (ListUtils.isListEmpty(nobleGiftInfos)) { @@ -741,6 +638,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } updateLuckyBagIntro(); updateWeekStarDesc(); + updateDrawGift(); } private void updateLuckyBagIntro() { @@ -796,6 +694,16 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } } + private void updateDrawGift() { + if (drawGiftHelper == null || currentGiftInfo == null) return; + if (giftIndicator.getCurrrentType() == GiftIndicator.TYPE_DRAW_GIFT) { + drawGiftHelper.setCurrentGift(currentGiftInfo.getGiftId(), currentGiftInfo.getGiftUrl(), currentGiftInfo.getGoldPrice()); + drawGiftHelper.setDrawEnable(true); + } else { + drawGiftHelper.setDrawEnable(false); + } + } + private void updateTotalPrice() { String diamond = ""; double totalValue = 0; @@ -846,7 +754,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene etSendMessage.setVisibility(View.GONE); tvLuckyBagIntro.setVisibility(View.GONE); tvGiftValue.setVisibility(View.GONE); - btnSendMagic.setVisibility(View.GONE); ivOpenNoble.setVisibility(View.GONE); llWeekIn.setVisibility(View.GONE); llStarWeek.setVisibility(View.GONE); @@ -856,7 +763,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene sendContainer.setVisibility(View.VISIBLE); } - private void setGridViewData(List> pagerList) { + private void setGridViewData(List> pagerList) { if (ListUtils.isListEmpty(pagerList)) { return; } @@ -865,10 +772,10 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene int defaultSelectItem = 0; wai: for (int i = 0; i < pagerList.size(); i++) { - List pager = pagerList.get(i); + List pager = pagerList.get(i); for (int j = 0; j < pager.size(); j++) { - IItem iItem = pager.get(j); - if (iItem instanceof GiftInfoVm && ((GiftInfoVm) iItem).isSelect.get()) { + GiftInfoVm iItem = pager.get(j); + if (iItem != null && iItem.isSelect.get()) { defaultSelectPage = i; defaultSelectItem = j; break wai; @@ -881,8 +788,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene indicatorView.setVisibility(pagerList.size() > 1 ? View.VISIBLE : View.INVISIBLE); SparseArray cacheItemView = new SparseArray<>(); - LastSelectedItem = pagerList.get(defaultSelectPage).get(defaultSelectItem); - setGoldOrRadishText(LastSelectedItem); + lastSelectedItem = pagerList.get(defaultSelectPage).get(defaultSelectItem); + setGoldOrRadishText(lastSelectedItem); gridView.setAdapter(new PagerAdapter() { @Override @@ -899,52 +806,38 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene @Override public Object instantiateItem(@NonNull ViewGroup container, int pagePos) { RecyclerView recyclerView; - MultiTypeAdapter giftAdapter; + MultiTypeAdapter giftAdapter; if (cacheItemView.get(pagePos) == null) { recyclerView = new RecyclerView(context); recyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); recyclerView.setLayoutManager(new GridLayoutManager(context, 4)); - giftAdapter = new MultiTypeAdapter(BR.item, true); + giftAdapter = new MultiTypeAdapter<>(BR.item, true); recyclerView.setAdapter(giftAdapter); cacheItemView.put(pagePos, recyclerView); } else { recyclerView = cacheItemView.get(pagePos); - giftAdapter = (MultiTypeAdapter) recyclerView.getAdapter(); + giftAdapter = (MultiTypeAdapter) recyclerView.getAdapter(); } giftAdapter.clearAllItem(); giftAdapter.addData(pagerList.get(pagePos)); giftAdapter.setOnItemClickListener(item -> { - if (item instanceof GiftInfoVm) { - GiftInfoVm giftInfoVm = (GiftInfoVm) item; - if (giftInfoVm.data.isSendMsg()) { - etSendMessage.setVisibility(View.VISIBLE); - } else { - etSendMessage.setVisibility(View.GONE); - } - if (LastSelectedItem != null) { - if (LastSelectedItem instanceof GiftInfoVm) { - ((GiftInfoVm) LastSelectedItem).isSelect.set(false); - } - } - giftInfoVm.isSelect.set(true); - LastSelectedItem = item; - currentGiftInfo = giftInfoVm.data; - } else if (item instanceof MagicInfoVm) { - MagicInfoVm magicInfoVm = (MagicInfoVm) item; - if (LastSelectedItem != null) { - if (LastSelectedItem instanceof MagicInfoVm) { - ((MagicInfoVm) LastSelectedItem).isSelect.set(false); - } - } - magicInfoVm.isSelect.set(true); - LastSelectedItem = item; - currentMagicInfo = magicInfoVm.data; + if (item.data.isSendMsg()) { + etSendMessage.setVisibility(View.VISIBLE); + } else { + etSendMessage.setVisibility(View.GONE); } - setGoldOrRadishText(LastSelectedItem); + if (lastSelectedItem != null) { + lastSelectedItem.isSelect.set(false); + } + item.isSelect.set(true); + lastSelectedItem = item; + currentGiftInfo = item.data; + setGoldOrRadishText(lastSelectedItem); updateLuckyBagIntro(); updateWeekStarDesc(); + updateDrawGift(); }); container.addView(recyclerView); return recyclerView; @@ -953,7 +846,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { RecyclerView recyclerView = cacheItemView.get(position); - MultiTypeAdapter adapter = (MultiTypeAdapter) recyclerView.getAdapter(); + MultiTypeAdapter adapter = (MultiTypeAdapter) recyclerView.getAdapter(); adapter.getAllItems().clear(); container.removeView(recyclerView); } @@ -1058,97 +951,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene dismiss(); break; - //送魔法 - case R.id.btn_sendMagic: - btnSendMagic.setEnabled(false); - btnSendMagic.setText("施法中..."); - if (!AuthModel.get().isImLogin()) { - SingleToastUtil.showToast("网络异常,请重试!"); - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - return; - } - if (currentMagicInfo == null) { - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - return; - } - if (!isInRoom) { - if (giftDialogBtnClickListener != null) { - giftDialogBtnClickListener.onSendMagicBtnClick(currentMagicInfo, uid, - new SenGiftCallback() { - @Override - public void onSuccess() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - - @Override - public void onFail() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - }); - } - return; - } - if (!userOnMic && uid > 0) { - //用户不在麦上 - sendSingleMagic(currentMagicInfo, uid, new SenGiftCallback() { - @Override - public void onSuccess() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - - @Override - public void onFail() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - }); - return; - } - //以下是房间内的操作 - if (avatarListAdapter == null || micMemberInfos.size() == 0) { -// Toast.makeText(context, "暂无成员在麦上", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("暂无成员在麦上"); - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - dismiss(); - return; - } - List selectedMember = avatarListAdapter.getSelectedMember(); - if (selectedMember == null || ListUtils.isListEmpty(selectedMember)) { -// Toast.makeText(context, "请选择要送魔法的人", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("请选择要送魔法的人"); - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - return; - } - - sendBatchMagic(currentMagicInfo, 1, selectedMember, - avatarListAdapter.getSelectType() == GiftAvatarAdapter.SELECT_TYPE_WHOLE_MIC, - new SenGiftCallback() { - @Override - public void onSuccess() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - - @Override - public void onFail() { - if (btnSendMagic == null) return; - btnSendMagic.setText("施法"); - btnSendMagic.setEnabled(true); - } - }); - break; //送礼物 case R.id.btn_send: sendGiftButton.setEnabled(false); @@ -1167,8 +969,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } String giftMessage = getGiftMessage(); if (Objects.equals(giftMessage, "")) { -// Toast.makeText(context, "请输入喊话内容", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("请输入喊话内容"); + SingleToastUtil.showToast("请输入喊话内容"); sendGiftButton.setText("赠送"); sendGiftButton.setEnabled(true); } else { @@ -1178,8 +979,14 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene micMemberInfo.setAccount(String.valueOf(uid)); targetUids.add(micMemberInfo); Log.e(TAG, "onClick: indicator type: " + giftIndicator.getCurrrentType()); - giftDialogBtnClickListener.onSendGiftBtnClick(currentGiftInfo, targetUids, giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, giftMessage, - giftIndicator.getCurrrentType() == GiftIndicator.TYPE_KNAP, false, + giftDialogBtnClickListener.onSendGiftBtnClick( + currentGiftInfo, + targetUids, + giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, + giftMessage, + giftIndicator.getCurrrentType() == GiftIndicator.TYPE_KNAP, + false, + getDrawFixedArray(), new SenGiftCallback() { @Override public void onSuccess() { @@ -1204,10 +1011,14 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene micMemberInfo.setAccount(String.valueOf(uid)); targetUids.add(micMemberInfo); Log.e(TAG, "onClick: indicator type: " + giftIndicator.getCurrrentType()); - giftDialogBtnClickListener.onSendGiftBtnClick(currentGiftInfo, targetUids, - giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, giftMessage, + giftDialogBtnClickListener.onSendGiftBtnClick( + currentGiftInfo, + targetUids, + giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, + giftMessage, giftIndicator.getCurrrentType() == GiftIndicator.TYPE_KNAP, false, + getDrawFixedArray(), new SenGiftCallback() { @Override public void onSuccess() { @@ -1229,15 +1040,19 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene if (giftIndicator.getCurrrentType() == GiftIndicator.TYPE_KNAP && giftNumber * selectedMembers.size() > currentGiftInfo.getCount()) { -// Toast.makeText(context, "礼物数量不足", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("礼物数量不足"); + SingleToastUtil.showToast("礼物数量不足"); sendGiftButton.setText("赠送"); sendGiftButton.setEnabled(true); return; } - giftDialogBtnClickListener.onSendGiftBtnClick(currentGiftInfo, selectedMembers, giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, giftMessage, + giftDialogBtnClickListener.onSendGiftBtnClick( + currentGiftInfo, + selectedMembers, + giftNumber == -1 ? currentGiftInfo.getCount() : giftNumber, + giftMessage, giftIndicator.getCurrrentType() == GiftIndicator.TYPE_KNAP, avatarListAdapter.getSelectType() == GiftAvatarAdapter.SELECT_TYPE_WHOLE_MIC, + getDrawFixedArray(), new SenGiftCallback() { @Override public void onSuccess() { @@ -1256,14 +1071,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene etSendMessage.setText(""); } else if (micMemberInfos.size() == 0) { -// Toast.makeText(context, "暂无成员在麦上", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("暂无成员在麦上"); + SingleToastUtil.showToast("暂无成员在麦上"); sendGiftButton.setText("赠送"); sendGiftButton.setEnabled(true); dismiss(); } else { -// Toast.makeText(context, "请选择送礼物的人", Toast.LENGTH_SHORT).show(); - SingleToastUtil.showToastShort("请选择送礼物的人"); + SingleToastUtil.showToast("请选择送礼物的人"); sendGiftButton.setText("赠送"); sendGiftButton.setEnabled(true); } @@ -1385,80 +1198,9 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene }) ); break; - - case GiftIndicator.TYPE_MAGIC: - //compositeDisposable.add(getMagicData()); - break; } } - @SuppressLint("CheckResult") - private void sendBatchMagic(MagicInfo magicInfo, int magicNum, List micMemberInfos, boolean isWholeMic, SenGiftCallback callback) { - List targetUids = new ArrayList<>(); - for (MicMemberInfo memberInfo : micMemberInfos) { - targetUids.add(Long.parseLong(memberInfo.getAccount())); - } - MagicModel.get().sendBatchMagic(magicInfo.getMagicId(), magicNum, targetUids, isWholeMic) - .subscribe((multiMagicReceivedInfo, throwable) -> { - if (multiMagicReceivedInfo != null) { - if (callback != null) { - callback.onSuccess(); - } - System.out.println("发送成功"); - } else { - if (throwable instanceof BalanceNotEnoughExeption) { - needCharge(); - } else if (throwable instanceof MagicOutOfDateException) { - SingleToastUtil.showToast(throwable.getMessage()); - } else if (throwable instanceof FreezeException) { - SingleToastUtil.showToast(throwable.getMessage()); - } else { - throwable.printStackTrace(); - } - if (callback != null) { - callback.onFail(); - } - } - }); - } - - @SuppressLint("CheckResult") - private void sendSingleMagic(MagicInfo magicInfo, long account, SenGiftCallback callback) { - MagicModel.get().sendMagic(magicInfo.getMagicId(), account) - .subscribe((magicReceivedInfo, throwable) -> { - if (magicReceivedInfo != null) { - if (callback != null) { - callback.onSuccess(); - } - System.out.println("发送成功"); - } else { - if (throwable instanceof BalanceNotEnoughExeption) { - needCharge(); - } else if (throwable instanceof MagicOutOfDateException) { - //魔法过期 - SingleToastUtil.showToast(throwable.getMessage()); - } else { - throwable.printStackTrace(); - } - if (callback != null) { - callback.onFail(); - } - } - }); - } - - private void needCharge() { - new DialogManager(context).showOkCancelDialog("余额不足,是否充值", - true, new DialogManager.AbsOkDialogListener() { - @Override - public void onOk() { - StatisticManager.Instance().onEvent(StatisticsProtocol.EVENT_NOT_ENOUGH_TO_RECHARGE, - "余额不足_去充值:送礼物"); - ChargeActivity.start(context); - } - }); - } - private String getGiftMessage() { if (currentGiftInfo != null && currentGiftInfo.isSendMsg()) { if (etSendMessage.getText().toString().length() == 0) { @@ -1487,6 +1229,11 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene 0, -UIUtil.dip2px(context, 11)); } + @Nullable + private List> getDrawFixedArray() { + return drawGiftHelper == null ? null : drawGiftHelper.getDrawFixedArray(); + } + @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); @@ -1499,9 +1246,6 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene compositeDisposable.dispose(); compositeDisposable = null; } - if (radishObserver != null) { - RadishWalletManager.get().getLdRadishNumber().removeObserver(radishObserver); - } } @Subscribe(threadMode = ThreadMode.MAIN) @@ -1514,7 +1258,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene @Subscribe(threadMode = ThreadMode.MAIN) public void onWalletInfoUpdate(UpdateWalletInfoEvent event) { goldWalletInfo = PayModel.get().getCurrentWalletInfo(); - setGoldOrRadishText(LastSelectedItem); + setGoldOrRadishText(lastSelectedItem); } @Subscribe(threadMode = ThreadMode.MAIN) @@ -1531,16 +1275,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene if (ListUtils.isListEmpty(pagerList)) { return; } - for (List page : pagerList) { - for (IItem item : page) { - if (!(item instanceof GiftInfoVm)) { - return; - } - GiftInfoVm giftInfoVm = (GiftInfoVm) item; - if (giftInfoVm.data.getGiftId() == giftId) { - int count = giftInfoVm.data.getCount() - sendNum; - giftInfoVm.data.setCount(count < 0 ? 0 : count); - giftInfoVm.updateCount(); + for (List page : pagerList) { + for (GiftInfoVm item : page) { + if (item.data.getGiftId() == giftId) { + int count = item.data.getCount() - sendNum; + item.data.setCount(Math.max(count, 0)); + item.updateCount(); break; } } @@ -1557,6 +1297,14 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene avatarList.smoothScrollToPosition(position); } + @Override + public void dismiss() { + super.dismiss(); + if (drawGiftHelper != null) { + drawGiftHelper.onDialogDismiss(); + } + } + public interface OnGiftDialogBtnClickListener { /** @@ -1570,16 +1318,15 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene * @param isWholeMic * @param callback */ - void onSendGiftBtnClick(GiftInfo giftInfo, ArrayList micMemberInfos, - int number, String msg, boolean isKnap, - boolean isWholeMic, SenGiftCallback callback); + void onSendGiftBtnClick(GiftInfo giftInfo, + ArrayList micMemberInfos, + int number, + String msg, + boolean isKnap, + boolean isWholeMic, + List> drawFixedArray, + SenGiftCallback callback); - /** - * 送魔法 - * - * @param targetUid 被赠送人id - */ - void onSendMagicBtnClick(MagicInfo magicInfo, long targetUid, SenGiftCallback callback); } public interface SenGiftCallback { diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftHelper.java b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftHelper.java new file mode 100644 index 000000000..49a7a8771 --- /dev/null +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftHelper.java @@ -0,0 +1,252 @@ +package com.yizhuan.erban.ui.widget.drawgift; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.FutureTarget; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; +import com.netease.nim.uikit.common.util.sys.ScreenUtil; +import com.netease.nim.uikit.support.glide.GlideApp; +import com.yizhuan.erban.R; +import com.yizhuan.xchat_android_core.gift.GiftModel; +import com.yizhuan.xchat_android_core.gift.bean.GiftInfo; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +public class DrawGiftHelper { + //为了节省内存。通过giftId当做Key来缓存Bitmap(如果你的giftId是String,那么这里要修改成HashMap) + //其实这个东西你可以做成单例。我现在没用单例,就需要每次进入直播间都重新缓存 + private final SparseArray cacheBitmapByGiftIdMap; + private Activity activity; + private MyHandler handler; + private List giftBeanList; + //画礼物的背景View(透明的,并不是灰底) + private DrawGiftView drawGiftView; + //播放礼物动画的层 + private DrawGiftPlayView playView; + //为了预加载,里面存的是adapter的itemView,你可以不用 + private LinkedList cachedItemViewList = new LinkedList<>(); + + private View cachedBottomGiftSheetView; + + public DrawGiftHelper(Activity activity) { + this.activity = activity; + handler = new MyHandler(this); + //key是giftId,value是Bitmap。为了不重复生成Bitmap + cacheBitmapByGiftIdMap = new SparseArray(); + //本地的 giftBeanList,你肯定是需要从缓存里取出来的,至于什么时候刷新,看你们的逻辑 + giftBeanList = new ArrayList(); + } + + //播放礼物draw动画,insertToFirst = 是否插入到队列前面 + public void playDrawGift(List allDrawGiftArray, boolean insertToFirst) { + if (playView == null) { + playView = new DrawGiftPlayView(activity); + playView.setOnDrawAnimationListener(new DrawGiftPlayView.DrawAnimationListener() { + + @Override + public void onAnimationNodeEnd(DrawGiftPlayView drawGiftPlayView) { + + } + + @Override + public void onAnimationAllOver(DrawGiftPlayView drawGiftPlayView) { + //动画放完了,移除掉播放礼物View层。当然这里你也可以不移除,一直保留 + FrameLayout contentParent = (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content); + contentParent.removeView(drawGiftPlayView); + } + }); + } + + if (playView.getParent() == null) { + //添加到decorView + FrameLayout contentParent = (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content); + playView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + contentParent.addView(playView); + } + + playView.addDrawGifts(allDrawGiftArray, insertToFirst); + } + + //从缓存里取出bitmap + public Bitmap obtainThumbBitmap(int giftId, Bitmap largeBitmap) { + Bitmap thumbGiftBitmap = cacheBitmapByGiftIdMap.get(giftId); + if (thumbGiftBitmap == null) { + int newSize = ScreenUtil.dip2px(20); + thumbGiftBitmap = Bitmap.createScaledBitmap(largeBitmap, newSize, newSize, true); + cacheBitmapByGiftIdMap.put(giftId, thumbGiftBitmap); + } + return thumbGiftBitmap; + } + + public void lazyDrawGiftView(int bottomSheetHeight, DrawGiftView.DrawGiftListener onDrawGiftListener) { + if (drawGiftView == null) { + drawGiftView = new DrawGiftView(activity); + drawGiftView.setOnDrawGiftListener(onDrawGiftListener); + drawGiftView.showInActivityWindow(activity, bottomSheetHeight); + } + } + + public void onDialogDismiss() { + //底部弹框消失 + //移除掉draw礼物View层。 + //FrameLayout contentParent = (FrameLayout) getWindow().getDecorView().findViewById(android.R.id.content); + + WindowManager mWindowManager = activity.getWindowManager(); + mWindowManager.removeView(drawGiftView); + //如果不 = null,leakCanary会报内存泄漏,但其实是误报 + drawGiftView = null; + } + + + //计算需要的金币并setText + public void resetNeedPriceDisplay() { + float totalPrice = 0; + List allDrawGiftArray = drawGiftView.getAllDrawGiftArray(); + for (DrawGiftModel giftModel : allDrawGiftArray) { + totalPrice += giftModel.getGiftPrice(); + } + // giftSheetBuilder.costCoinTv.setText("消耗金币:"+totalPrice); + } + + //子线程处理播放礼物的数据 + public void prepareShowDrawGift(List> fixedArray, boolean insertToFirst) { + //把服务器推送来的"礼物位置json" 和 本地的 giftBeanList 一一对应上,找到礼物的bitmap + final List allDrawGiftArray = new ArrayList<>(); + + //经过测试,这个子线程耗时仅为30ms左右(前提是bitmap已经被是从本地取的) + Thread thread = new Thread() { + @Override + public void run() { + + //本机屏幕宽高 + DisplayMetrics displayMetrics = new DisplayMetrics(); + ((WindowManager) activity.getApplicationContext().getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay().getMetrics(displayMetrics); + float viewWidth = displayMetrics.widthPixels; + float viewHeight = displayMetrics.heightPixels; + + //fixedArray 是服务器推送过来的礼物json + for (HashMap fixedMap : fixedArray) { + //giftBeanList 是手机本地缓存的全部礼物列表 + //我们要做的就是两个列表相互匹配,根据礼物id,找出礼物的bitmap(通过glide) + int giftId = Integer.parseInt(fixedMap.get("giftid")); + GiftInfo giftBean = GiftModel.get().findGiftInfoById(giftId); + + + //将服务器推送来的x,y转成绝对像素坐标 + DrawGiftModel drawGiftModel = new DrawGiftModel(); + drawGiftModel.setX(Float.valueOf(fixedMap.get("x")) * viewWidth); + drawGiftModel.setY(Float.valueOf(fixedMap.get("y")) * viewHeight); + + Bitmap thumbGiftBitmap = cacheBitmapByGiftIdMap.get(giftId); + if (thumbGiftBitmap != null) { + //缓存中就有bitmap + drawGiftModel.setGiftBitmap(thumbGiftBitmap); + + } else { + //缓存没有bitmap + //从Glide里找出礼物的bitmap + FutureTarget futureBitmap = Glide.with(activity).asBitmap() + .load(giftBean.getGiftUrl()) + .submit(); + + try { + Bitmap bitmap = futureBitmap.get(); + thumbGiftBitmap = obtainThumbBitmap(giftId, bitmap); + drawGiftModel.setGiftBitmap(thumbGiftBitmap); + } catch (Exception e) { + e.printStackTrace(); + //万一下载失败了,取本地的图片占位 + Bitmap errorBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.default_cover); + drawGiftModel.setGiftBitmap(errorBitmap); + } + } + allDrawGiftArray.add(drawGiftModel); + } + + Message message = Message.obtain(handler, 1, insertToFirst ? 1 : 0, 0, allDrawGiftArray); + handler.sendMessage(message); + } + }; + thread.start(); + } + + public void setCurrentGift(int giftId, String giftUrl, float giftPrice) { + if (drawGiftView == null) return; + GlideApp.with(activity) + .asBitmap() + .load(giftUrl) + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + drawGiftView.setCurrentGift(giftId, obtainThumbBitmap(giftId, resource), giftPrice); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + + } + + //是否可以画 + public void setDrawEnable(boolean drawEnable) { + if (drawGiftView != null) { + drawGiftView.setDrawEnable(drawEnable); + } + } + + public List> getDrawFixedArray() { + if (drawGiftView != null) { + return drawGiftView.transformGiftArrayFitScreen(activity); + } + return null; + } + + + private static class MyHandler extends Handler { + + private WeakReference reference; + + public MyHandler(DrawGiftHelper context) { + super(Looper.getMainLooper()); + reference = new WeakReference<>(context); + } + + @Override + public void handleMessage(Message msg) { + final DrawGiftHelper activity = (DrawGiftHelper) reference.get(); + if (activity == null) { + return; + } + if (msg.what == 1) { + List allDrawGiftArray = (List) msg.obj; + activity.playDrawGift(allDrawGiftArray, msg.arg1 == 1); + } + } + } + +} diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftModel.java b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftModel.java new file mode 100644 index 000000000..0343a8bb1 --- /dev/null +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftModel.java @@ -0,0 +1,67 @@ +package com.yizhuan.erban.ui.widget.drawgift; + +import android.graphics.Bitmap; +import android.graphics.Matrix; + +public class DrawGiftModel { + + private float x; + private float y; + private int giftId; + private float giftPrice;//礼物价格,为了方便画的过程中,快速的计算出当前一共画了多少钱的礼物,默认0 + private Bitmap giftBitmap; + + //在收到礼物显示动画的时候,本demo为了体现出礼物放大消失的动画,引入了这个Matrix参数,如果没有放大动画,就不需要这两个 + private Matrix matrix; + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public int getgiftId() { + return giftId; + } + + public void setgiftId(int giftId) { + this.giftId = giftId; + } + + public Bitmap getGiftBitmap() { + return giftBitmap; + } + + public void setGiftBitmap(Bitmap giftBitmap) { + this.giftBitmap = giftBitmap; + } + + public Matrix getMatrix() { + if (matrix == null){ + matrix = new Matrix(); + } + return matrix; + } + + public void setMatrix(Matrix matrix) { + this.matrix = matrix; + } + + public float getGiftPrice() { + return giftPrice; + } + + public void setGiftPrice(float giftPrice) { + this.giftPrice = giftPrice; + } +} diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftPlayView.java b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftPlayView.java new file mode 100644 index 000000000..61c625488 --- /dev/null +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftPlayView.java @@ -0,0 +1,217 @@ +package com.yizhuan.erban.ui.widget.drawgift; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.view.View; + +import java.util.LinkedList; +import java.util.List; + +public class DrawGiftPlayView extends View { + + //需要被画上的全部的礼物,采用链表的方式,每次取第0个 + private LinkedList> allDrawGiftsLinkedList; + + //当前这幅画播放到第几个礼物 + private int currentGiftShowIndex; + + private DrawAnimationListener onDrawAnimationListener; + + //为了体现最后的消失动画效果,才引入了这个Paint + private Paint mPaint; + + private static final int DRAW_ONE_GIFT = 0; + + private Handler mHandler; + + private Handler.Callback mCallback = new Handler.Callback() { + @Override + public boolean handleMessage(Message msg) { + switch (msg.what) { + case DRAW_ONE_GIFT: + //画一个礼物 + currentGiftShowIndex = msg.arg1; + invalidate(); + + if (currentGiftShowIndex == allDrawGiftsLinkedList.getFirst().size()){ + //进入这里,说明已经播放完最后一个礼物了 + //播放扩大动画,然后消失 + ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 2); + valueAnimator.setDuration(500); + valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float p = (float) animation.getAnimatedValue(); + //透明效果(所有礼物都做这个动作) + mPaint.setAlpha((int)((2.0F - p) * 255)); + //放大效果(所有礼物都做这个动作) + for (DrawGiftModel giftModel : allDrawGiftsLinkedList.getFirst()) { + + giftModel.getMatrix().reset(); + giftModel.getMatrix().preTranslate(giftModel.getX() - giftModel.getGiftBitmap().getWidth() / 2F, giftModel.getY() - giftModel.getGiftBitmap().getHeight() / 2F); + giftModel.getMatrix().postScale((float) (1.0F + (p - 1) * 0.4), (float) (1.0F + (p - 1) * 0.4), giftModel.getX(), giftModel.getY()); + } + + invalidate(); + } + }); + valueAnimator.addListener(new Animator.AnimatorListener(){ + + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + //放大动画结束 + mPaint.reset(); + + currentGiftShowIndex = 0; + allDrawGiftsLinkedList.removeFirst(); + + if (onDrawAnimationListener != null) { + //当前的这一幅画结束 + onDrawAnimationListener.onAnimationNodeEnd(DrawGiftPlayView.this); + + if (allDrawGiftsLinkedList.isEmpty()){ + //所有画全部结束 + onDrawAnimationListener.onAnimationAllOver(DrawGiftPlayView.this); + } else { + //还有画没播完,继续画下一幅画 + //要先清理掉画布上的上一幅画 + invalidate(); + + Message message = Message.obtain(); + message.arg1 = 0; + message.what = DRAW_ONE_GIFT; + mHandler.sendMessageDelayed(message, 100); + } + } + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + valueAnimator.start(); + } else { + //继续画下一个礼物 + Message message = Message.obtain(); + message.arg1 = currentGiftShowIndex + 1; + message.what = DRAW_ONE_GIFT; + mHandler.sendMessageDelayed(message, 100); + } + + return true; + } + return true; + } + }; + + public DrawGiftPlayView(Context context) { + this(context, null); + } + + public DrawGiftPlayView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public DrawGiftPlayView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mHandler = new Handler(mCallback); + allDrawGiftsLinkedList = new LinkedList>(); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + int size = allDrawGiftsLinkedList.getFirst().size(); + for(int i = 0; i <= currentGiftShowIndex && i < size; i++) { + DrawGiftModel giftModel = allDrawGiftsLinkedList.getFirst().get(i); + canvas.drawBitmap(giftModel.getGiftBitmap(), giftModel.getMatrix(), mPaint); + } + } + + public void addDrawGifts(List currentDrawGiftArray, boolean insertToFirst){ + + //处理每个小bitmap的大小和位置 + for(int i = 0; i < currentDrawGiftArray.size(); i++) { + DrawGiftModel giftModel = currentDrawGiftArray.get(i); + + giftModel.getMatrix().reset(); + giftModel.getMatrix().postTranslate(giftModel.getX() - giftModel.getGiftBitmap().getWidth() / 2F, giftModel.getY() - giftModel.getGiftBitmap().getHeight() / 2F); + } + + //添加到队列 + if (insertToFirst){ + if (allDrawGiftsLinkedList.size() > 0){ + //说明队列里已经有画在draw了。 + //由于我目前的逻辑是:取first节点,画完了再remove;而不是先remove再设置为全局变量。所以要插入到第1个元素 + allDrawGiftsLinkedList.add(1, currentDrawGiftArray); + } else { + //说明当前列表是空的,直接插入到表头 + allDrawGiftsLinkedList.offerFirst(currentDrawGiftArray); + } + } else { + //插入到表尾 + allDrawGiftsLinkedList.offerLast(currentDrawGiftArray); + } + + if (allDrawGiftsLinkedList.size() == 1){ + //刚插入完,size==1,说明是刚开始,这时候要开始播放 + List firstDrawGiftArray = this.allDrawGiftsLinkedList.getFirst(); + + if (firstDrawGiftArray != null){ + //说明有需要播放的,开始draw + Message message = Message.obtain(); + message.arg1 = 0; + message.what = DRAW_ONE_GIFT; + mHandler.sendMessage(message); + } + } + } + + @Override + public void onAttachedToWindow(){ + super.onAttachedToWindow(); + mPaint = new Paint(); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mHandler.removeCallbacksAndMessages(null); + mPaint.reset(); + currentGiftShowIndex = 0; + } + + public void setOnDrawAnimationListener(DrawAnimationListener onDrawAnimationListener) { + this.onDrawAnimationListener = onDrawAnimationListener; + } + + public interface DrawAnimationListener{ + //礼物动画全部结束 + public void onAnimationNodeEnd(DrawGiftPlayView drawGiftPlayView); + //礼物动画当前的这一幅画结束 + public void onAnimationAllOver(DrawGiftPlayView drawGiftPlayView); + } +} diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftView.java b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftView.java new file mode 100644 index 000000000..a02eb1c64 --- /dev/null +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/drawgift/DrawGiftView.java @@ -0,0 +1,325 @@ +package com.yizhuan.erban.ui.widget.drawgift; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; + +import com.yizhuan.erban.R; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +//手绘礼物的View +public class DrawGiftView extends View { + + private final Bitmap placeholderBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.drawgift_placeholder); + private final Paint textPaint = new Paint(); + //当前被画上去的全部的DrawGiftModel + private List allDrawGiftArray; + private float mLastX; + private float mLastY; + //每一笔的最后一个图的index,所以:这个List.size = 一共几笔 + private List strokeFirstPositionArray; + private DrawGiftListener onDrawGiftListener; + //当前选中的礼物的id和bitmap + private int currentGiftId; + private Bitmap currentGiftBitmap; + private float currentGiftPrice; + //连续两个礼物之间的间距(像素),0表示用当前礼物的宽 + private int drawStrokeInterval; + //是否可以画 + private boolean drawEnable = false; + //没画的时候,显示的默认文本 + private String placeHolderText = "涂鸦模式,绘制你的图案"; + + + public DrawGiftView(Context context) { + this(context, null); + } + + public DrawGiftView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public DrawGiftView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (!drawEnable) { + //因为选了普通礼物,所以当前View不能画 + //这时候要清空之前画的内容(一定要draw一些东西,只调用invalidate的话无法清空) + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + return; + } + + if (allDrawGiftArray.isEmpty()) { + float placeHolderViewHeight = 500; + canvas.drawBitmap(placeholderBitmap, (getWidth() - placeholderBitmap.getWidth()) / 2f, (getHeight() - placeHolderViewHeight) / 2, null); + textPaint.setStyle(Paint.Style.FILL); + textPaint.setColor(0xffffffff); + textPaint.setStrokeWidth(8); + textPaint.setTextSize(42); + textPaint.setTextAlign(Paint.Align.CENTER); + if (placeHolderText != null) { + float baseline = (getHeight() - placeHolderViewHeight) / 2 + 340; + canvas.drawText(placeHolderText, getWidth() / 2f, baseline, textPaint); + } + } else { + for (DrawGiftModel giftModel : allDrawGiftArray) { + canvas.drawBitmap(giftModel.getGiftBitmap(), giftModel.getX() - giftModel.getGiftBitmap().getWidth() / 2f, giftModel.getY() - giftModel.getGiftBitmap().getHeight() / 2f, null); + //这里肯定是不能recycle的 + } + } + } + + //正常情况下一个View的如果Down事件return false,那么就吃不到后面的move事件了。 + //但是本View是被windowManager.addView(view) 添加到windowManager层。那么后续的move up都肯定会触发 + @Override + public boolean onTouchEvent(MotionEvent event) { + int action = event.getAction(); + switch (action) { + case MotionEvent.ACTION_DOWN: + if (!drawEnable || currentGiftBitmap == null) { + //不允许画 || 当前没选中任何礼物 + return super.onTouchEvent(event); + } + //点下 + mLastX = checkIfBelongHorizontalEdge(event.getX()); + mLastY = checkIfBelongVerticalEdge(event.getY()); + addDrawGiftModel(mLastX, mLastY, currentGiftBitmap); + invalidate(); + + //记录这一笔的开头 + strokeFirstPositionArray.add(allDrawGiftArray.size() - 1); + + return true; + case MotionEvent.ACTION_MOVE: + if (!drawEnable || currentGiftBitmap == null) { + //不允许画 || 当前没选中任何礼物 + return super.onTouchEvent(event); + } + float moveX = checkIfBelongHorizontalEdge(event.getX()); + float moveY = checkIfBelongVerticalEdge(event.getY()); + + //距离上一个礼物的移动距离 + float distance = (float) (Math.pow(moveX - mLastX, 2) + Math.pow(moveY - mLastY, 2)); + //理应移动多少才需要画新礼物 + float reference = (float) Math.pow(drawStrokeInterval == 0 ? currentGiftBitmap.getWidth() : drawStrokeInterval, 2); + + if (distance >= reference) { + //距离拉开了,应该画新礼物 + if (moveX >= getLeft() && moveX < getRight() && moveY >= getTop() && moveY < getBottom()) { + //看看新礼物是否在View内 + addDrawGiftModel(moveX, moveY, currentGiftBitmap); + mLastX = moveX; + mLastY = moveY; + invalidate(); + + if (onDrawGiftListener != null) { + onDrawGiftListener.onGiftPainted(this, currentGiftId); + } + } else { + //越界 + } + } + break; + case MotionEvent.ACTION_CANCEL: + break; + case MotionEvent.ACTION_UP: + if (!drawEnable && onDrawGiftListener != null) { + //不允许画,那么要回调up事件,为了让底部的sheet收起来 + onDrawGiftListener.onTouchEventUpWhenDrawDisable(this); + } + + break; + } + return super.onTouchEvent(event); + } + + private void addDrawGiftModel(float x, float y, Bitmap bitmap) { + DrawGiftModel mDIYGiftModel = new DrawGiftModel(); + mDIYGiftModel.setGiftBitmap(bitmap); + mDIYGiftModel.setgiftId(currentGiftId); + mDIYGiftModel.setGiftPrice(currentGiftPrice); + mDIYGiftModel.setX(x); + mDIYGiftModel.setY(y); + allDrawGiftArray.add(mDIYGiftModel); + } + + //检查是否是屏幕边缘 + private float checkIfBelongHorizontalEdge(float intrinsicX) { + if (intrinsicX > getWidth() - (currentGiftBitmap.getWidth() / 2)) { + //超过右边界 + return getWidth() - (currentGiftBitmap.getWidth() / 2); + } else if (intrinsicX < currentGiftBitmap.getWidth() / 2) { + //超过左边界 + return currentGiftBitmap.getWidth() / 2; + } else { + return intrinsicX; + } + } + + //检查是否是屏幕边缘 + private float checkIfBelongVerticalEdge(float intrinsicY) { + if (intrinsicY > getHeight() - (currentGiftBitmap.getHeight() / 2)) { + //超过右边界 + return getHeight() - (currentGiftBitmap.getHeight() / 2); + } else if (intrinsicY < currentGiftBitmap.getHeight() / 2) { + //超过左边界 + return currentGiftBitmap.getHeight() / 2; + } else { + return intrinsicY; + } + } + + //清空当前画的所有礼物 + public void removeAll() { + strokeFirstPositionArray.clear(); + allDrawGiftArray.clear(); + invalidate(); + } + + //移除最后一笔 + public void removeLastStroke() { + if (strokeFirstPositionArray.isEmpty()) { + return; + } + + int lastStrokeIndex = strokeFirstPositionArray.get(strokeFirstPositionArray.size() - 1); + + //先从全部礼物里删除最后一笔礼物 + for (int i = allDrawGiftArray.size() - 1; i >= lastStrokeIndex; i--) { + allDrawGiftArray.remove(i); + } + + //移除最后一笔的记录点 + strokeFirstPositionArray.remove(strokeFirstPositionArray.size() - 1); + + invalidate(); + } + + //设置当前这笔礼物 + public void setCurrentGift(int giftId, Bitmap giftBitmap, float giftPrice) { + this.currentGiftId = giftId; + this.currentGiftBitmap = giftBitmap; + this.currentGiftPrice = giftPrice; + } + + //bottomSheetHeight是底部不能画的区域的高度 + public void showInActivityWindow(Activity activity, int bottomSheetHeight) { + WindowManager mWindowManager = activity.getWindowManager(); + WindowManager.LayoutParams wl = new WindowManager.LayoutParams(); + + //用TYPE_APPLICATION 是本View所在的层级,如果太高了(超过了应用)还要申请权限 + wl.type = WindowManager.LayoutParams.TYPE_APPLICATION; + + //据说这个可以让触摸事件穿透到view层,但是我们的sheet是dialog,所以无用 +// wl.flags = WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE; + + wl.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + wl.gravity = Gravity.TOP;//这个top会盖住titleBar,但是盖不住状态栏 + wl.width = WindowManager.LayoutParams.MATCH_PARENT; + wl.height = activity.getWindow().getDecorView().findViewById(android.R.id.content).getHeight() - bottomSheetHeight; + wl.token = activity.getWindow().getAttributes().token; + wl.format = PixelFormat.TRANSLUCENT;//Toast就是用这个实现的透明 + mWindowManager.addView(this, wl); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + allDrawGiftArray = new ArrayList<>(); + strokeFirstPositionArray = new ArrayList<>(); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + allDrawGiftArray.clear(); + strokeFirstPositionArray.clear(); + } + + @Override + public void onFinishInflate() { + super.onFinishInflate(); + } + + public List getAllDrawGiftArray() { + return allDrawGiftArray; + } + + //由于不同手机屏幕尺寸不同,如果礼物画在大屏幕的最右边(X很大)在小屏幕上绘制礼物的时候,X会超出屏幕。因此在这里转成百分比再上传给服务器 + public List> transformGiftArrayFitScreen(Context context) { + + DisplayMetrics displayMetrics = new DisplayMetrics(); + ((WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay().getMetrics(displayMetrics); + + //fixedArray是需要转成json发送给服务器的 + List> fixedArray = new ArrayList<>(); + float viewWidth = displayMetrics.widthPixels; + float viewHeight = displayMetrics.heightPixels; + HashMap param = null; + for (DrawGiftModel giftModel : allDrawGiftArray) { + //x 和 y转为屏幕比例 + param = new HashMap<>(); + param.put("x", String.valueOf(((int) ((giftModel.getX() / viewWidth) * 1000)) / 1000f)); + param.put("y", String.valueOf(((int) ((giftModel.getY() / viewHeight) * 1000)) / 1000f)); + param.put("giftid", String.valueOf(giftModel.getgiftId())); + fixedArray.add(param); + } + return fixedArray; + } + + //连续两个礼物之间的间距(像素),0表示用当前礼物的宽 + public void setDrawStrokeInterval(int drawStrokeInterval) { + this.drawStrokeInterval = drawStrokeInterval; + } + + //还没画的时候,提示语 + public void setPlaceHolderText(String placeHolderText) { + this.placeHolderText = placeHolderText; + invalidate(); + } + + //是否可以画 + public void setDrawEnable(boolean drawEnable) { + if (drawEnable != this.drawEnable) { + this.drawEnable = drawEnable; + if (!drawEnable) { + allDrawGiftArray.clear(); + strokeFirstPositionArray.clear(); + } + invalidate(); + } + } + + public void setOnDrawGiftListener(DrawGiftListener onDrawGiftListener) { + this.onDrawGiftListener = onDrawGiftListener; + } + + public interface DrawGiftListener { + //新的礼物节点被画上 + public void onGiftPainted(DrawGiftView drawGiftView, int giftId); + + //当drawDisable的情况下,触发的touchUp回调 + public void onTouchEventUpWhenDrawDisable(DrawGiftView drawGiftView); + } +} diff --git a/app/src/main/java/com/yizhuan/erban/ui/widget/magicindicator/GiftIndicator.java b/app/src/main/java/com/yizhuan/erban/ui/widget/magicindicator/GiftIndicator.java index d8f717990..3b1e02c75 100644 --- a/app/src/main/java/com/yizhuan/erban/ui/widget/magicindicator/GiftIndicator.java +++ b/app/src/main/java/com/yizhuan/erban/ui/widget/magicindicator/GiftIndicator.java @@ -47,6 +47,9 @@ public class GiftIndicator extends LinearLayout { /**周星礼物*/ public static final int TYPE_WEEK = 6; + /**涂鸦礼物*/ + public static final int TYPE_DRAW_GIFT = 7; + private Map map = new HashMap<>(); public GiftIndicator(Context context, @Nullable AttributeSet attrs) { diff --git a/app/src/main/res/drawable-xhdpi/drawgift_placeholder.png b/app/src/main/res/drawable-xhdpi/drawgift_placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..4dac2373296415be659ac02cb535c5726f3ea4d7 GIT binary patch literal 2907 zcmbW3`9Bkm1ICAx$dytek=#^D&K(gJxk40bDH$O$%&{4*Lei4k808~!Rm#oGk=x8U z%rV5=8)D4$^*4N<*Xw!SujiNN=O^0Q5-P}ljvoL32%6qDvN>efq4W884%6920DFid za03ei0N^K1VAqBBuyY}7poV~Avef)x(X}?WGlu$_AN*fJ1CuNcN5uSXENuaoZ{7PP zq-!4GC;36%?Q?!Atm$HQGYtUX|7>bxU>7v<$BB_PEptLs`6;~& zRnCS3Rpbo*dTwx9pXomL#{& z1t(Uh9+#3`cAyJ9zp%F*L-x5)zt=_N`tI10e6Yn2T(m_h zm^9yaGAx`;UVPN<(%#sXzO0s)FJj-y)uH68A?L~ej+j?%P;zTFUiO%806+0ua*+Q@ zN|+@24e7xSVly>%yMN)9 zt5a*OLB}j7NLH>)y@LQJI5oA8%_?p#C$OA7ybDz|MRwZ*-jaoXEXEMw)D&CUrks~% zS965cBFX&Hs!u~%F|4|jxuJsRk@P2Y*|&tBA+niV6*7I1Lu~Aa6fwi2cdLn0>n8NyTB1NOX@9$$PwkXW5knEEfts}C zFTTER&Cu9X-hyp^bo0v-9Zf~KPV6*tsNhR~A5Eqo_jgXu^+{`)kf})}dT*7`7cbby zOGa*3oz*M!fki?@(5v1-vGf`0JpKTW+RBeYOA@9%8%~~5$l;i%v_f;4|Gh6vex2Sn zmM2^&L?PdBsVsdY27XZfcsh|wz-LbXzarknj~BQwC?~sIq8!aVrFE?OaS)hZ#@Mmk zjD#=Ef9ga#QCHC(##>rvZUsekL9y}+1z1>Q?nLkA`I})hXUz}hV>Dlnn-{FNh)=ow z0T?fZ5*QDX4GOz7hPUGTa&k62{^OQs3Hm(vQ^{B6mgDF<<;-oa5d@4nS&E|(7WLOe zclV<#8GS!ZCPFuN9zlBz8kN05@r(Lj>>SO(l4H`uO;95EZga{rBUyS`xfRgED^Cly zpfDB6LgU(zDegQf5e^FktyDWVX{i^AWhPTSIybf7es~_LJDotSRF4crw7GFrX;||6 zzfRhR3X6`b^T%Si!OJ}xvNQ)M^->G78C?x-I=P|YWCv7UN=jVGyT*v>i$2{g358jy zWa}SmmG%A}?qfOcwHDfx9N$IZA{Yk=gWa$=ph^XzDz=ia;61V7dTl*iU%iLv_mQ1@ z+P(_^e74XpLTi0on|E9!ZWsJKd9IZxoI^wisiKiRc|&9&!g)yRPMMIV^nLSd;S4_n z=8PBn%JHPAM7tKiBrlz&qFD9H3~AP)f~>oqV(*x+##&>J!;NPQTW=gQoc8PzUm0f# zTwr>+BvbDVM89aZw?zmDxP^OFfx2_g2ps3`X7LVv1# zkwIxOyrL#IDVq~^wS=1gcsNGq|zQ{rbdu&XRporSybEx z4FP5z*xN1GW52G1#Z@jiM{_>WkDWl5Sqqm+)AH2@0*Bu2*i_(Fi3T|@bZ+DgDFyCw zlW@~#Wok?(#fbFgtS24kXyF&?Uj%2yli$66J8E%TOAe3vPUj>1l+^Cs<>N;7wp%|B zZ9~f6adH?#At`bCh^^$>ZVL+AdrT77WA;!hESbVgsl>Vo9jsA)dOesB^dSgPN8093 z=Iq3gc(yynsW->))fews30pL@A*!zMf<}y)-ShuMPKmQsT%H%DifMIL$mNcT0+|km zmqQN1iv+7P&n$dRW`*zGwYjV_j_&?;g-KM~u3FMLn4&>cFT1)-h(ePm1-Y zEzOxXyU8p(15Hh}=2{ph5AD^YDp_)*em%?fnu{B68_+ol0kp0k;$FMsVEAmT$eb6tMt5&w&K3*e*k6T`RIl zs>m>|<_u!bT5(d%VInwfHomp?UC3*)=i^DP%Q#e7YOdL))4)PCau1&cuMQhZ#}}vl zi9G1Q`t3#3`GCg9{o*n$%me= zuKoOCqv+oB^qTIpbzzadF`^!f(~yK>~rznwb8D7aDEW%Gj1Fx zrW*Usae@1;70s8u(mPPF!kyQB#prS|;35l8Yj(`|us~T2NGK>Me$`)*o4_-t&D>II zXPf-ZZxElV=(lYckZ+|`4;F&7W#jPkrW0c8jte3?o9#vF^uqKcmv0WKvP#ne0fLl` zy;#^ty7c{m>%j>H{oZD}KlUU@8$R~6!=^Ltxdm7h5B+pTi}Cu-4!Meu#OUjhR{+*u zi^mqn9?NX>RGbc;mt&*{z8f1W7RBanylU<%?Jd=?YbaZ}spPLJECm@q{P zO0dg;w*NuCUXHgDM9{W~EHfpvE6nDct0^$R6Si~a@U zKX1**{b7Z{)V|IX1B>HL*3HFrPi=@^DQ`-?Z3GYV$sRv4hQ$p{m1Ja1n=vaha3eB! zO{phsrf@SjwqFtKg;ggSJ)L&YhrS}e{f0x8H`+&ge^t&HczA0zdqQKw!}LRAO(XkuY=Lyww0^)laOsaQOGy_&7Bt5vnkL*pG -