diff --git a/app/src/main/java/com/mango/moshen/avroom/widget/ScrollSpeedLinearLayoutManger.java b/app/src/main/java/com/mango/moshen/avroom/widget/ScrollSpeedLinearLayoutManger.java index f49306f21..b459a6629 100644 --- a/app/src/main/java/com/mango/moshen/avroom/widget/ScrollSpeedLinearLayoutManger.java +++ b/app/src/main/java/com/mango/moshen/avroom/widget/ScrollSpeedLinearLayoutManger.java @@ -2,11 +2,17 @@ package com.mango.moshen.avroom.widget; import android.content.Context; import android.graphics.PointF; + import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; + import android.util.DisplayMetrics; import android.util.Log; +import android.view.View; + +import com.mango.xchat_android_library.utils.ListUtils; +import com.mango.xchat_android_library.utils.LogUtil; /** * @author chenran @@ -14,39 +20,50 @@ import android.util.Log; */ public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager { - private float MILLISECONDS_PER_INCH = 0.2F; - private Context context; - private LinearSmoothScroller linearSmoothScroller; - private int lastPosition = -1; + private final float MILLISECONDS_PER_INCH = 2F; + private final LinearSmoothScroller linearSmoothScroller; - ScrollSpeedLinearLayoutManger(Context context) { - super(context); - this.context = context; + public ScrollSpeedLinearLayoutManger(Context context) { + this(context, RecyclerView.VERTICAL, false); + } + + /** + * @param context Current context, will be used to access resources. + * @param orientation Layout orientation. Should be {@link #HORIZONTAL} or {@link + * #VERTICAL}. + * @param reverseLayout When set to true, layouts from end to start. + */ + public ScrollSpeedLinearLayoutManger(Context context, @RecyclerView.Orientation int orientation, + boolean reverseLayout) { + super(context, orientation, reverseLayout); linearSmoothScroller = new LinearSmoothScroller(context) { @Override public PointF computeScrollVectorForPosition(int targetPosition) { - PointF pointF = ScrollSpeedLinearLayoutManger.this - .computeScrollVectorForPosition(targetPosition); - Log.e("Point", pointF.y + ""); - return pointF; + return ScrollSpeedLinearLayoutManger.this.computeScrollVectorForPosition(targetPosition); } - @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { - //返回滑动一个pixel需要多少毫秒 return MILLISECONDS_PER_INCH; } + protected int calculateTimeForScrolling(int dx) { + return 2000; + } + + @Override + protected void onTargetFound(View targetView, RecyclerView.State state, Action action) { + final int dx = calculateDxToMakeVisible(targetView, getHorizontalSnapPreference()); + final int dy = calculateDyToMakeVisible(targetView, getVerticalSnapPreference()); + final int time = 2000; + action.update(-dx, -dy, time, mLinearInterpolator); + } }; } + @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { - if (linearSmoothScroller.isRunning() && lastPosition != -1) { - scrollToPosition(lastPosition); - } linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); - lastPosition = position; } } \ No newline at end of file diff --git a/app/src/main/java/com/mango/moshen/ui/widget/GiftDialog.java b/app/src/main/java/com/mango/moshen/ui/widget/GiftDialog.java index 79574a41a..3ab4f6f59 100644 --- a/app/src/main/java/com/mango/moshen/ui/widget/GiftDialog.java +++ b/app/src/main/java/com/mango/moshen/ui/widget/GiftDialog.java @@ -32,6 +32,8 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; import com.github.mmin18.widget.RealtimeBlurView; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; @@ -42,8 +44,10 @@ import com.mango.core.gift.GiftModel; import com.mango.core.gift.bean.GiftInfo; import com.mango.core.gift.bean.GiftTab; import com.mango.core.gift.bean.GiftType; +import com.mango.core.gift.bean.LuckyBagNoticeInfo; import com.mango.core.gift.bean.SimpleUserInfo; import com.mango.core.gift.event.UpdateKnapEvent; +import com.mango.core.im.custom.bean.RoomReceivedLuckyGiftAttachment; import com.mango.core.initial.InitialModel; import com.mango.core.manager.AvRoomDataManager; import com.mango.core.manager.IMNetEaseManager; @@ -64,6 +68,8 @@ import com.mango.core.utils.net.RxHelper; import com.mango.moshen.BR; import com.mango.moshen.R; import com.mango.moshen.avroom.firstcharge.FirstChargeDialog; +import com.mango.moshen.avroom.widget.MessageView; +import com.mango.moshen.avroom.widget.ScrollSpeedLinearLayoutManger; import com.mango.moshen.base.BaseActivity; import com.mango.moshen.common.widget.CircleImageView; import com.mango.moshen.radish.task.activity.TaskCenterActivity; @@ -101,11 +107,18 @@ import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.Observer; import io.reactivex.Single; +import io.reactivex.SingleSource; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; /** * @author chenran @@ -134,6 +147,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene private PageIndicatorView indicatorView; private RecyclerView avatarList; private GiftAvatarAdapter avatarListAdapter; + private BaseQuickAdapter luckyMsgAdapter; @Nullable private GiftInfo currentGiftInfo; private List currentGiftInfoList; @@ -145,6 +159,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene private ImageView giftNumberOptions; private ImageView ivLuckyBagIntro; private View flLuckyDesc; + private RecyclerView rvLuckyMsg; private TextView tvGiftValue; private EditText etSendMessage; private Button sendGiftButton; @@ -188,6 +203,9 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene @Nullable private DrawGiftHelper drawGiftHelper; + @Nullable + private Disposable luckyMsgDisposable; + public GiftDialog(Context context, int giftId) { this(context, 0, true, false, true, giftId); } @@ -352,6 +370,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene case RoomEvent.GIFT_OUT_OF_DATE: onGiftOutOfDate(roomEvent.getMessage()); break; + case RoomEvent.RECEIVE_SERVICE_LUCKY_BAG_NOTICE: + RoomReceivedLuckyGiftAttachment attachment = (RoomReceivedLuckyGiftAttachment) roomEvent.getCustomAttachment(); + if (luckyMsgAdapter != null && luckyMsgAdapter.getItemCount() > 0 && attachment.getLuckyBagNoticeInfo() != null) { + luckyMsgAdapter.addData(attachment.getLuckyBagNoticeInfo()); + } + break; default: break; } @@ -449,6 +473,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene layoutEmpty.setVisibility(View.GONE); ivLuckyBagIntro = findViewById(R.id.iv_lucky_bag_intro); flLuckyDesc = findViewById(R.id.fl_lucky_desc); + rvLuckyMsg = findViewById(R.id.rv_lucky_msg); tvGiftValue = findViewById(R.id.tv_gift_value); ivLuckyBagIntro.setOnClickListener(this); if (giftId == 0) { @@ -663,10 +688,42 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene } private void updateLuckyBagIntro() { + if (luckyMsgDisposable != null) luckyMsgDisposable.dispose(); if (currentGiftInfo == null || currentGiftInfo.getGiftType() != GiftType.GIFT_TYPE_LUCKY) { flLuckyDesc.setVisibility(View.GONE); } else { flLuckyDesc.setVisibility(View.VISIBLE); + if (luckyMsgAdapter == null) { + luckyMsgAdapter = new BaseQuickAdapter(R.layout.item_lucky_gift_msg) { + @Override + protected void convert(@NonNull BaseViewHolder helper, LuckyBagNoticeInfo noticeInfo) { + TextView tvContent = helper.getView(R.id.tv_content); + String nickName = RegexUtil.getPrintableString(noticeInfo.getNick()); + SpannableBuilder text = new SpannableBuilder() + .append("恭喜 ", new ForegroundColorSpan(Color.WHITE)) + .append(nickName, new ForegroundColorSpan(Color.parseColor("#FFD436"))) + .append(" 开" + noticeInfo.getLuckyBagName() + "获得 ", new ForegroundColorSpan(Color.WHITE)) + .append(noticeInfo.getGiftName() + "", new ForegroundColorSpan(Color.parseColor("#66D8DA"))); + tvContent.setText(text.build()); + } + }; + rvLuckyMsg.setAdapter(luckyMsgAdapter); + rvLuckyMsg.setLayoutManager(new ScrollSpeedLinearLayoutManger(context, LinearLayoutManager.HORIZONTAL, false)); + } + luckyMsgDisposable = GiftModel.get().getLuckyGiftMsgList() + .compose(RxHelper.bindContext(context)) + .doOnSuccess(luckyBagNoticeInfos -> luckyMsgAdapter.setNewData(luckyBagNoticeInfos)) + .toObservable() + .flatMap(luckyBagNoticeInfos -> Observable.intervalRange(0, Integer.MAX_VALUE, 0, 5, TimeUnit.SECONDS)) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(aLong -> { + int index = Math.toIntExact(aLong) % luckyMsgAdapter.getItemCount(); + if (index == 0) { + rvLuckyMsg.scrollToPosition(index); + } else { + rvLuckyMsg.smoothScrollToPosition(index); + } + }); } } diff --git a/app/src/main/res/layout/dialog_bottom_gift.xml b/app/src/main/res/layout/dialog_bottom_gift.xml index e40986eb5..02b8f6672 100644 --- a/app/src/main/res/layout/dialog_bottom_gift.xml +++ b/app/src/main/res/layout/dialog_bottom_gift.xml @@ -15,6 +15,7 @@ android:layout_marginBottom="12dp" android:background="@drawable/bg_gift_dialog_lucky_desc" android:visibility="gone" + tools:visibility="visible" app:layout_constraintBottom_toTopOf="@id/ll_dialog_bottom_gift" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> @@ -26,15 +27,14 @@ android:layout_marginStart="8dp" android:src="@drawable/bg_gift_dialog_lucky_bag" /> - + tools:listitem="@layout/item_lucky_gift_msg" + tools:itemCount="1" + android:layout_gravity="center_vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> + + diff --git a/core/src/main/java/com/mango/core/gift/GiftModel.java b/core/src/main/java/com/mango/core/gift/GiftModel.java index 3088367d8..84262b485 100644 --- a/core/src/main/java/com/mango/core/gift/GiftModel.java +++ b/core/src/main/java/com/mango/core/gift/GiftModel.java @@ -10,6 +10,7 @@ import android.util.Log; import androidx.annotation.Nullable; +import com.mango.core.gift.bean.LuckyBagNoticeInfo; import com.netease.nim.uikit.common.util.log.LogUtil; import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage; import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum; @@ -619,6 +620,13 @@ public class GiftModel extends BaseModel implements IGiftModel { .compose(RxHelper.handleSchAndExce()); } + @Override + public Single> getLuckyGiftMsgList() { + return api.getLuckyGiftMsgList() + .compose(RxHelper.handleBeanData()) + .compose(RxHelper.handleSchAndExce()); + } + private interface Api { /** @@ -678,6 +686,14 @@ public class GiftModel extends BaseModel implements IGiftModel { @Field("giftSource") int giftSource, @Field("chatSessionId") String chatSessionId); + /** + * 福袋最近20条全服记录 + * + * @return + */ + @GET("/gift/luckyBag/serviceMsg/record") + Single>> getLuckyGiftMsgList(); + } private static class UiHandler extends Handler { diff --git a/core/src/main/java/com/mango/core/gift/IGiftModel.java b/core/src/main/java/com/mango/core/gift/IGiftModel.java index b4959c5ea..277403c52 100644 --- a/core/src/main/java/com/mango/core/gift/IGiftModel.java +++ b/core/src/main/java/com/mango/core/gift/IGiftModel.java @@ -2,6 +2,8 @@ package com.mango.core.gift; import androidx.annotation.Nullable; +import com.mango.core.gift.bean.LuckyBagNoticeInfo; +import com.mango.core.im.custom.bean.RoomReceivedLuckyGiftAttachment; import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage; import com.mango.core.bean.response.ServiceResult; import com.mango.core.gift.bean.GiftInfo; @@ -198,4 +200,11 @@ public interface IGiftModel { */ Single> sendFansTeamGift(int giftId, String targetUid); + + /** + * 福袋最近20条全服记录 + * + * @return - + */ + Single> getLuckyGiftMsgList( ); }