Compare commits

...

59 Commits

Author SHA1 Message Date
eggmanQQQ
ce50e32a73 feat ; 去掉 carshCat 2024-09-26 16:11:20 +08:00
eggmanQQQ
7223db9e9c fix: 修复bug , 增加全局报错日志抓取 2024-09-26 15:28:07 +08:00
eggmanQQQ
4a2a9d4400 feat : 明文流量修改回退 2024-09-25 19:39:57 +08:00
eggmanQQQ
8049bdf6ea fix : bug 修复 2024-09-25 19:37:21 +08:00
eggmanQQQ
c90a961e2f feat : 修改权限 , 新增 定制礼物, 去掉友盟取设备号的sdk , 明文请求修改 2024-09-25 19:06:52 +08:00
eggmanQQQ
892f7c3e70 fix: vip 时间 2024-09-24 18:36:54 +08:00
eggmanQQQ
4c8182ee2f update version to 1.0.16 2024-09-24 18:26:33 +08:00
eggmanQQQ
343e73c6e3 feat: 修改 cp 相关bug 2024-09-24 18:18:53 +08:00
eggmanQQQ
eabe2ae7f8 feat : 修复bug 2024-09-24 11:31:29 +08:00
eggmanQQQ
36c011d18e feat : cp 功能 , 个人主页UI修改 , cp列表 , 房间cp飘屏,cp相关动画 , vip中心banner 显示剩余时间 2024-09-23 16:10:39 +08:00
eggmanQQQ
f929d78540 feat : 房間按鈕調整 (欠缺几个图片。app icon 和空状态图 未更改 2024-09-14 15:30:09 +08:00
eggmanQQQ
8184cdd6e1 feat: 房间 排行按钮, 音乐按钮 2024-09-13 13:53:13 +08:00
max
e4d44155dc feat: 更改类名 ,处理代码区分 2024-09-12 19:20:13 +08:00
max
06c974a6ed feat: 图片资源 格式转换 2024-09-12 19:03:23 +08:00
max
4bfbd19b53 fix: 修复bug, 调整升级弹窗不再弹出, 兼容旧版本连击横幅,礼物动画加快, 2024-09-12 18:55:55 +08:00
max
61a26f0c4f fix: 调整ui, 修复bug 2024-09-12 10:15:17 +08:00
max
e8cfc8a13b fix:异常注释 2024-09-11 16:23:24 +08:00
max
295de38074 feat: 幸运礼物 弹窗跟飘屏 , 替换 金币图标 2024-09-11 16:21:58 +08:00
max
e3c5f10d02 feat: 联机送礼功能 2024-09-09 18:39:22 +08:00
max
d949cfa7ff temp save 2024-09-05 19:24:44 +08:00
max
e30f4fd15f feat: 更正 tabbar size 2024-08-30 20:57:09 +08:00
max
90ece5366b feat: 更新数据明文处理 2024-08-30 20:54:13 +08:00
max
555b81589c feat: 修正 en 语言的部分 UI 2024-08-30 16:15:31 +08:00
max
e4cdc39ad8 feat: 修正反饋問題 2024-08-30 15:54:20 +08:00
max
09411df1ff feat:UI 調整 2024-08-29 19:21:07 +08:00
max
9cbc6cf39f fix: 修正 VIP 購買選項 model 2024-08-29 18:19:44 +08:00
max
444d043aa8 feat: 修改聯繫人列表 UI 2024-08-29 17:06:40 +08:00
max
f99d193598 feat: 修改信息列表 UI 2024-08-29 16:42:24 +08:00
max
4a57bd50c5 feat:UI 調整 2024-08-29 12:00:28 +08:00
eggmanQQQ
8a59f8a769 feat: 调整 RTL 布局 UI 2024-08-29 11:59:28 +08:00
max
2c1ecbb263 feat:UI 調整 2024-08-28 21:41:19 +08:00
max
aa2987cb0d feat:修正問題 2024-08-28 21:40:15 +08:00
eggmanQQQ
5e6864d87f feat: 更新 UI 2024-08-28 21:39:59 +08:00
eggmanQQQ
6aabeb3eb3 feat: 更新 UI 2024-08-28 17:36:16 +08:00
eggmanQQQ
9ff48bc500 feat: 移除资源,补充多语言 2024-08-28 13:55:59 +08:00
max
e9ba0b1929 feat:調整 VIP 顯示邏輯,移除公聊廳 2024-08-28 13:55:12 +08:00
max
adf2adc173 feat:調整 VIP 顯示邏輯,移除公聊廳 2024-08-27 16:51:46 +08:00
max
74b2d71821 調試 UI 2024-08-27 16:51:46 +08:00
eggmanQQQ
81a5c6ba65 feat: 補充卡片背景,補充 VIP 資源播放 MP4 的功能 2024-08-27 16:31:44 +08:00
eggmanQQQ
5f8a8113c6 feat:个人资料卡支持 MP4 资源 2024-08-27 11:53:49 +08:00
eggmanQQQ
b0bf9ce98d feat: 调整文案 2024-08-27 11:24:32 +08:00
eggmanQQQ
c3fcbc3942 feat: 更新资源,调整布局 2024-08-27 10:33:34 +08:00
max
6e08f397ee fix:Vip 頁面支持 MP4 播放,修正佈局問題 2024-08-26 16:58:19 +08:00
eggmanQQQ
3d29568b3c feat: 更新 VIP 页面 UI & 功能 2024-08-26 09:13:28 +08:00
eggmanQQQ
cb4dac8e81 feat: 更新 VIP 页面 UI & 功能 2024-08-23 19:29:38 +08:00
eggmanQQQ
f58701a2d6 version update 2024-08-20 10:53:52 +08:00
max
654bc45c8c fix:修正信息 tag 列表項阿語環境在 Android 低版本時佈局異常問題 2024-08-13 18:35:23 +08:00
max
87a36d796c Version Update 2024-08-13 18:19:19 +08:00
eggmanQQQ
0bc1023c99 fix: 修正用户访问失败时的返回处理 2024-08-06 19:27:00 +08:00
max
154e688673 version code update 2024-08-06 11:20:31 +08:00
max
a91dee592d fix:補充查找禮物的類型 2024-08-05 21:42:47 +08:00
eggmanQQQ
7ef78bc3e1 fix: 調整多語言時,點擊 tab 的移動判斷 2024-08-05 19:22:44 +08:00
eggmanQQQ
b5bcd9cb5f fix: 調整多語言時,禮物面板 tab 的默認方向 2024-08-05 19:06:08 +08:00
max
de7eb25045 feat:隱藏超級幸運禮物標記 2024-08-05 18:57:18 +08:00
eggmanQQQ
029b7fcf96 feat: 完成礼物面板调整 2024-08-05 16:39:41 +08:00
eggmanQQQ
23a3858a2c feat: "我的" 列表支持跳转至“我的装扮” 2024-08-02 10:32:49 +08:00
eggmanQQQ
67044ded6b fix:修正个播房玩法入口布局 2024-08-01 17:57:01 +08:00
eggmanQQQ
3e6d34a986 fix:修正个播房玩法入口布局 2024-07-31 18:48:14 +08:00
max
e7ca237a3e fix:修正個播房遊戲玩法入口的顯示問題 2024-07-31 17:51:20 +08:00
428 changed files with 10709 additions and 3820 deletions

View File

@@ -205,6 +205,7 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
api 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
@@ -270,6 +271,8 @@ dependencies {
//wheelView
implementation 'com.contrarywind:wheelview:4.1.0'
// 轮播组件
implementation 'io.github.youth5201314:banner:2.2.3'
implementation project(':modules:module_base')
if (!isolationMode && file("../modules/module_google/build.gradle").exists()) {

View File

@@ -51,9 +51,9 @@
tools:node="remove" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
@@ -316,6 +316,9 @@
android:name=".ui.user.activity.UserInfoActivity"
android:label="@string/main_androidmanifest_016"
android:screenOrientation="portrait" />
<activity
android:name=".ui.user.activity.UserCpListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".audio.AudioRecordActivity"
android:label="@string/main_androidmanifest_017"
@@ -733,8 +736,8 @@
android:name=".ui.setting.PermissionGuideActivity"
android:screenOrientation="portrait" />
<activity
android:name=".vip.VipMainActivity"
android:screenOrientation="portrait" /> <!-- 隐私设置 -->
android:name=".vip.VipCenterActivity"
android:screenOrientation="portrait" />
<activity
android:name=".vip.VipSettingActivity"
android:screenOrientation="portrait" /> <!-- 通知提醒设置 -->

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -9,6 +9,7 @@ import android.content.res.Configuration;
import android.graphics.Color;
import android.net.http.HttpResponseCache;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

View File

@@ -97,7 +97,7 @@ public class GlobalHandleManager {
Activity activity = getActivity();
if (activity == null) return;
if (AvRoomDataManager.get().isSelfGamePlaying()) return;
LevelUpDialog.start(activity, event.getLevelName(), true);
// LevelUpDialog.start(activity, event.getLevelName(), true);
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -105,7 +105,7 @@ public class GlobalHandleManager {
Activity activity = getActivity();
if (activity == null) return;
if (AvRoomDataManager.get().isSelfGamePlaying()) return;
LevelUpDialog.start(activity, event.getLevelName(), false);
// LevelUpDialog.start(activity, event.getLevelName(), false);
}
private static final class Helper {

View File

@@ -0,0 +1,149 @@
package com.chwl.app.avroom.dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.viewbinding.ViewBinding
import com.chwl.app.R
import com.chwl.app.avroom.widget.VDHLayout
import com.chwl.app.ui.widget.dialog.BaseDialog
abstract class BaseRoomNotifyDialog<VB : ViewBinding>(context: Context, theme: Int = 0) : BaseDialog(context, theme) {
protected val handle = Handler(Looper.getMainLooper())
protected lateinit var mBinding: VB
abstract fun createBinding(inflater: LayoutInflater): VB
abstract fun init()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = createBinding(LayoutInflater.from(context))
setContentView(mBinding.root)
setCancelable(true)
setCanceledOnTouchOutside(false)
window?.let {
initWindow(it)
}
init()
if (useAutoDismiss()) {
handle.postDelayed({
dismissDialog()
}, (getStaySecond()*1000).toLong())
}
}
override fun onDetachedFromWindow() {
handle.removeCallbacksAndMessages(null)
super.onDetachedFromWindow()
}
protected open fun initWindow(window: Window) {
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val windowParams = window.attributes
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 = getTopOffset()
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.attributes = windowParams
window.setWindowAnimations(getAnimations())
}
protected open fun getStaySecond():Float{
return 5f
}
protected open fun getTopOffset():Int{
return 0
}
@StyleRes
protected open fun getAnimations():Int{
return R.style.anim_left
}
override fun setContentView(view: View) {
if (useSlipSlip()) {
val vdhLayout = VDHLayout(context, null)
vdhLayout.addView(view)
vdhLayout.setListener { dismissDialog() }
super.setContentView(vdhLayout)
return
}
super.setContentView(view)
}
override fun setContentView(layoutResID: Int) {
if (useSlipSlip()) {
val vdhLayout = VDHLayout(context, null)
LayoutInflater.from(context).inflate(layoutResID, vdhLayout)
vdhLayout.setListener { dismissDialog() }
super.setContentView(vdhLayout)
return
}
super.setContentView(layoutResID)
}
override fun setContentView(view: View, params: ViewGroup.LayoutParams?) {
if (useSlipSlip()) {
val vdhLayout = VDHLayout(context, null)
vdhLayout.addView(view)
vdhLayout.setListener { dismissDialog() }
super.setContentView(vdhLayout, params)
return
}
super.setContentView(view, params)
}
/**
* 是否启动侧滑,左滑:删除,右滑:回到原位置
*/
protected open fun useSlipSlip(): Boolean {
return true
}
protected open fun useAutoDismiss(): Boolean {
return true
}
var mCallBack : CallBack? = null
interface CallBack{
fun onHide();
}
open fun dismissDialog() {
try {
dismiss()
} catch (e: Exception) {
}
mCallBack?.onHide()
}
open fun clearDialog() {
try {
dismiss()
} catch (e: Exception) {
}
}
open fun showDialog(){
show()
}
}

View File

@@ -19,20 +19,26 @@ import com.chwl.app.common.widget.dialog.DialogManager
import com.chwl.app.databinding.RoomGameplayDialogBinding
import com.chwl.app.home.helper.OpenRoomHelper
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.room.bean.RoomIcon
import com.chwl.core.room.bean.RoomInfo
import com.chwl.core.room.bean.RoomModeType
import com.chwl.core.room.core.RoomDataService
import com.chwl.core.room.game.GameModel
import com.chwl.core.room.game.GameModel.getGameList
import com.chwl.core.room.game.bean.BaiShunGameConfig
import com.chwl.core.room.game.bean.GameInfo
import com.chwl.core.room.model.AvRoomModel
import com.chwl.core.support.room.AudioRoomContext
import com.chwl.core.utils.LogUtils
import com.chwl.library.utils.JavaUtil
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import com.example.lib_utils.ktx.asLifecycle
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.gson.Gson
import com.unity3d.splash.services.core.lifecycle.LifecycleEvent
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
class RoomGameListDialog :
BottomSheetDialogFragment(), LifecycleObserver {
private var binding: RoomGameplayDialogBinding? = null
@@ -40,6 +46,10 @@ class RoomGameListDialog :
private val adapter = RoomGameListAdapter()
private var dialogManager: DialogManager? = null
private lateinit var recycleView: RecyclerView
val cacheKey = "game_list#${parentFragment.hashCode()}"
private var mStatus = -1
private var mGameData = arrayListOf<GameInfo>()
var listener: RoomGameplayDialog.GameplayDialogListener? = null
override fun getTheme(): Int {
return R.style.ErbanBottomSheetDialogDimFalse
}
@@ -101,27 +111,50 @@ class RoomGameListDialog :
}
private fun requestData() {
val dataService =
AudioRoomContext.get()
?.findAbility<RoomDataService>(RoomDataService::class.java.simpleName)
val cacheKey = "game_list#${parentFragment.hashCode()}"
val dataService = AudioRoomContext.get()?.findAbility<RoomDataService>(RoomDataService::class.java.simpleName)
// val cacheKey = "game_list#${parentFragment.hashCode()}"
val list = dataService?.getData(cacheKey) as? List<GameInfo>
if (!list.isNullOrEmpty()) {
updateDialogHeight(list.size)
loadData(list)
return
}
val disposable = getGameList(AvRoomDataManager.get().roomUid)
val getGameList = getGameList(AvRoomDataManager.get().roomUid)
.doOnError {
SingleToastUtil.showToast(it.message)
switchStatus(-2)
if (mStatus != 1)switchStatus(-2)
}
.subscribe { it: List<GameInfo> ->
LogUtils.d(" gamegame getGameList GameInfo = $it")
mGameData.addAll(0,it)
dataService?.putData(cacheKey, it)
updateDialogHeight(it.size)
loadData(it)
updateDialogHeight(mGameData.size)
loadData(mGameData)
}
getCompositeDisposable().add(disposable)
val roomGamePlayList = AvRoomModel.get().roomGamePlayList
.doOnError {
SingleToastUtil.showToast(it.message)
if (mStatus != 1)switchStatus(-2)
}
.subscribe { it: List<RoomIcon> ->
LogUtils.d(" gamegame roomGamePlayList RoomIcon = $it")
it.forEachIndexed { index, roomIcon ->
if (roomIcon.isBaiShunGame()) {
mGameData.add(GameInfo(name = roomIcon.name?:"", pic = roomIcon.icon?:"" , pic2 = roomIcon.icon?:"", skipContent = roomIcon.skipContent?:"", ruleValue = roomIcon.ruleValue?:""))
}
}
dataService?.putData(cacheKey, mGameData)
updateDialogHeight(mGameData.size)
loadData(mGameData)
}
getCompositeDisposable().add(getGameList)
getCompositeDisposable().add(roomGamePlayList)
}
private fun loadData(list: List<GameInfo>?) {
@@ -134,6 +167,7 @@ class RoomGameListDialog :
}
private fun switchStatus(status: Int) {
mStatus = status
when (status) {
// loading
0 -> {
@@ -185,27 +219,55 @@ class RoomGameListDialog :
dialogManager?.showOkCancelDialog(
getString(R.string.room_switch_game_tips)
) {
if (gameInfo.isStandardRoom()) {
OpenRoomHelper.updateRoomInfo(
activity as BaseActivity,
AvRoomDataManager.get().mCurrentRoomInfo,
RoomInfo.ROOMTYPE_HOME_PARTY,
0,
false
)
} else {
OpenRoomHelper.updateRoomInfo(
activity as BaseActivity,
AvRoomDataManager.get().mCurrentRoomInfo,
RoomInfo.ROOMTYPE_GAME,
JavaUtil.str2long(gameInfo.mgId),
false
)
if (gameInfo.mgId.isNotEmpty()) {
if (gameInfo.isStandardRoom()) {
OpenRoomHelper.updateRoomInfo(
activity as BaseActivity,
AvRoomDataManager.get().mCurrentRoomInfo,
RoomInfo.ROOMTYPE_HOME_PARTY,
0,
false
)
} else {
OpenRoomHelper.updateRoomInfo(
activity as BaseActivity,
AvRoomDataManager.get().mCurrentRoomInfo,
RoomInfo.ROOMTYPE_GAME,
JavaUtil.str2long(gameInfo.mgId),
false
)
}
}else if(!gameInfo.skipContent.isNullOrEmpty() || !gameInfo.ruleValue.isNullOrEmpty()){
jumpBaiShunGame(gameInfo)
}
dismissAllowingStateLoss()
}
}
private fun jumpBaiShunGame(data: GameInfo) {
try {
val url = data.skipContent
val ruleValue = Gson().fromJson<RoomIcon.RuleValueBean>(
data.ruleValue,
RoomIcon.RuleValueBean::class.java
)
val config = Gson().fromJson<BaiShunGameConfig>(
ruleValue.RESERVE,
BaiShunGameConfig::class.java
)
if (config != null && url != null) {
config.reloadDynamicParams()
listener?.onShowBaiShunGame(url, config)
} else {
SingleToastUtil.showToast(R.string.manager_trtc_trtcengineadapter_042)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onDestroy() {
super.onDestroy()
onUnbindContext()
@@ -233,4 +295,8 @@ class RoomGameListDialog :
return currentRoomInfo != null && currentRoomInfo.type != RoomInfo.ROOM_TYPE_SINGLE &&
(currentRoomInfo.roomModeType == RoomModeType.NORMAL_MODE || currentRoomInfo.roomModeType == 2 || currentRoomInfo.roomModeType == 4)
}
interface GameplayDialogListener {
fun onShowBaiShunGame(url: String, config: BaiShunGameConfig)
}
}

View File

@@ -0,0 +1,87 @@
package com.chwl.app.avroom.dialog
import android.content.Context
import android.graphics.Bitmap
import android.view.LayoutInflater
import com.chwl.app.databinding.RoomNotifyCpBindBinding
import com.chwl.app.ui.utils.CpUtils
import com.chwl.core.gift.bean.CpMsgBean
import com.chwl.core.utils.LogUtils
import com.tencent.qgame.animplayer.inter.IFetchResource
import com.tencent.qgame.animplayer.mix.Resource
import com.tencent.qgame.animplayer.util.ScaleType
class RoomNotifyCpBindDialog (private val context: Context) : BaseRoomNotifyDialog<RoomNotifyCpBindBinding>(context) {
override fun createBinding(inflater: LayoutInflater): RoomNotifyCpBindBinding {
return RoomNotifyCpBindBinding.inflate(inflater)
}
var cpMsgBean : CpMsgBean? = null
var senderAvatar : Bitmap? = null
var receiverAvatar : Bitmap? = null
var index = 0
override fun init() {
cpMsgBean?.let { data->
mBinding.anim.setScaleType(ScaleType.CENTER_CROP)
mBinding.anim.setFetchResource(object : IFetchResource {
override fun fetchImage(resource: Resource, result: (Bitmap?) -> Unit) {
result(if (resource.tag == "avatar1") senderAvatar else receiverAvatar)
}
override fun fetchText(resource: Resource, result: (String?) -> Unit) {
var name = ""
try {
name = if (resource.tag == "name1") data.senderNick else data.receiverNick
} catch (e: Exception) {
}
result(name)
}
override fun releaseResource(resources: List<Resource>) {
resources?.forEach {
it?.bitmap?.recycle()
}
}
})
mBinding.anim.startPlay(context.assets,"mp4/cp_bind.mp4")
}
}
override fun useSlipSlip() = false
override fun useAutoDismiss() = true
override fun showDialog() {
index = 0
cpMsgBean?.let {
CpUtils.downLoadAvatar(it.senderAvatar) { resource ->
index += 1
senderAvatar = resource
checkImg()
}
CpUtils.downLoadAvatar(it.receiverAvatar) { resource ->
index += 1
receiverAvatar = resource
checkImg()
}
}
}
fun checkImg() {
if (index == 2){
show()
}
}
}

View File

@@ -0,0 +1,31 @@
package com.chwl.app.avroom.dialog
import android.content.Context
import android.view.LayoutInflater
import com.chwl.app.databinding.RoomNotifyCpGiftBinding
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.core.gift.bean.CpMsgBean
import kotlin.math.truncate
/**
* cp 飘屏
*/
class RoomNotifyCpGiftDialog (private val context: Context) : BaseRoomNotifyDialog<RoomNotifyCpGiftBinding>(context) {
override fun createBinding(inflater: LayoutInflater): RoomNotifyCpGiftBinding {
return RoomNotifyCpGiftBinding.inflate(inflater)
}
var cpMsgBean : CpMsgBean? = null
override fun init() {
cpMsgBean?.let {
ImageLoadUtils.loadImage(mBinding.sendAvatar,it.senderAvatar)
ImageLoadUtils.loadImage(mBinding.receiverAvatar,it.receiverAvatar)
ImageLoadUtils.loadImage(mBinding.gift,it.giftUrl)
}
}
override fun useSlipSlip() = true
}

View File

@@ -0,0 +1,101 @@
package com.chwl.app.avroom.dialog
import android.content.Context
import android.graphics.Color
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
import android.view.LayoutInflater
import com.chwl.app.R
import com.chwl.app.avroom.helper.AnimHelper
import com.chwl.app.databinding.RoomNotifyCpLevelUpBinding
import com.chwl.app.ui.utils.CpUtils
import com.chwl.app.ui.utils.loadFromAssets
import com.chwl.app.utils.SpannableBuilder
import com.chwl.core.gift.bean.CpMsgBean
import com.chwl.core.utils.SpanUtils
import com.example.lib_utils.ktx.getColor
import com.example.lib_utils.ktx.getString
import com.opensource.svgaplayer.SVGADrawable
import com.opensource.svgaplayer.SVGADynamicEntity
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAParser.Companion.shareParser
import com.opensource.svgaplayer.SVGAVideoEntity
class RoomNotifyLevelUpDialog (private val context: Context) : BaseRoomNotifyDialog<RoomNotifyCpLevelUpBinding>(context) {
override fun createBinding(inflater: LayoutInflater): RoomNotifyCpLevelUpBinding {
return RoomNotifyCpLevelUpBinding.inflate(inflater)
}
var cpMsgBean : CpMsgBean ? = null
override fun init() {
cpMsgBean?.let {
SpanUtils.with(mBinding.text)
.append(" ${it.senderNick} ").setForegroundColor(R.color.white.getColor())
.append(" ${R.string.avroom_widget_roomeffectview_02.getString()} ").setForegroundColor(R.color.color_fff664.getColor())
.append(" ${it.receiverNick} ").setForegroundColor(R.color.white.getColor())
.append(" ${R.string.Become.getString()} ").setForegroundColor(R.color.color_fff664.getColor())
.append(" ${CpUtils.getCpLevelUpStr(it.cpLevel)} ").setForegroundColor(R.color.white.getColor())
.create()
mBinding.text.setBackgroundResource(CpUtils.getCpLevelUpTextBg(it.cpLevel))
if (it.cpLevel < 1) return
val svga = "svga/cp_level_up_${it.cpLevel}.svga"
try {
shareParser().decodeFromAssets(svga, object : SVGAParser.ParseCompletion {
override fun onComplete(svgaVideoEntity: SVGAVideoEntity) {
val dynamicEntity = SVGADynamicEntity()
// val textPaint = TextPaint()
// textPaint.color = Color.WHITE //字体颜色
// textPaint.textSize = 24f //字体大小
// dynamicEntity.setDynamicText(
// StaticLayout(
// text.build(),
// 0,
// text.build().length,
// textPaint,
// 0,
// Layout.Alignment.ALIGN_CENTER,
// 1.0f,
// 0.0f,
// false
// ), "bg"
// )
AnimHelper.addDynamicImage(
mBinding.svga,
dynamicEntity,
it.senderAvatar,
"user_img1"
)
AnimHelper.addDynamicImage(
mBinding.svga,
dynamicEntity,
it.receiverAvatar,
"user_img2"
)
val drawable = SVGADrawable(svgaVideoEntity, dynamicEntity)
mBinding.svga.setImageDrawable(drawable)
mBinding.svga.stepToFrame(0, true)
// mBinding.svga.startAnimation()
}
override fun onError() {
}
}, null)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun useSlipSlip() = false
}

View File

@@ -0,0 +1,64 @@
package com.chwl.app.avroom.dialog
import android.content.Context
import android.view.LayoutInflater
import com.chwl.app.R
import com.chwl.app.avroom.activity.AVRoomActivity
import com.chwl.app.common.widget.dialog.DialogManager
import com.chwl.app.common.widget.dialog.DialogManager.OkCancelDialogListener
import com.chwl.app.databinding.RoomNotifyLuckGiftDlgBinding
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.utils.NumberUtils
import com.chwl.core.gift.bean.LuckyGiftMsgAllBean
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.UiUtils
/**
* @Author Vance
* 幸运礼物的飘屏,全服但是展示的时候限制只有房间才展示
*/
class RoomNotifyLuckGiftDialog(private val context: Context) : BaseRoomNotifyDialog<RoomNotifyLuckGiftDlgBinding>(context) {
override fun createBinding(inflater: LayoutInflater): RoomNotifyLuckGiftDlgBinding {
return RoomNotifyLuckGiftDlgBinding.inflate(inflater)
}
private var mDialogManager: DialogManager? = null
var luckyGiftMsgBean: LuckyGiftMsgAllBean ? = null
override fun init() {
if (UiUtils.isRtl(context)) {
mBinding.bg.scaleX = -1f
}
ImageLoadUtils.loadImage(mBinding.avatar,luckyGiftMsgBean?.sender?.avatar?:"")
mBinding.giftName.text = luckyGiftMsgBean?.giftNameMap?.getFirstText()
mBinding.winNum.text = luckyGiftMsgBean?.times.toString()
val coinNum = NumberUtils.format(luckyGiftMsgBean?.coins?:0)
mBinding.coinNum.text = coinNum
mBinding.clickArea.setOnClickListener {
mDialogManager = DialogManager(context)
mDialogManager?.showOkCancelDialog(ResUtil.getString(R.string.changeRoomTips), true, object : OkCancelDialogListener {
override fun onCancel() {
mDialogManager?.dismissDialog()
}
override fun onOk() {
mDialogManager?.dismissDialog()
luckyGiftMsgBean?.roomUid?.let {
if (AvRoomDataManager.get().roomUid != it) {
AVRoomActivity.start(context, it)
}
}
}
})
}
}
}

View File

@@ -77,6 +77,14 @@ public class RoomOperationDialog extends BottomSheetDialog {
private Context context;
private OptAdapter optAdapter;
private OnActionListener onActionListener;
private CallBack callBack;
public void setCallBack(CallBack callBack) {
this.callBack = callBack;
}
public interface CallBack{
void onCLick(int Type);
}
public RoomOperationDialog(@NonNull Context context) {
super(context, R.style.ErbanBottomSheetDialogDimFalse);
@@ -114,30 +122,30 @@ public class RoomOperationDialog extends BottomSheetDialog {
true));
rvOPtList.setLayoutManager(new FullyGridLayoutManager(getContext(), 5));
optAdapter = new OptAdapter(context, null);
addRoomAlbum(optAdapter);
addDatingAction(optAdapter);
// addPKAction(optAdapter);
// addRoomPKAction(optAdapter);
addSingleRoomPKAction(optAdapter);
addSendBroadcastAction(optAdapter);
// addInviteFansOptAdapter();
addVipSendBroadcastAction(optAdapter);
// addRedPacketAction(optAdapter);
addRoomSettingAction(optAdapter);
addGiftEffectAction(optAdapter);
// addOpenOrClosePublicScreenAction(optAdapter);
// addRedPackageSwitch();
addCleanScreenAction(optAdapter);
// addRoomLimit(optAdapter);
// addGiftValueAction(optAdapter);
addSuperAdminAction(optAdapter);
addShieldReportAction(optAdapter);
addRoomTypeSwitchAction(optAdapter);
addRoomAlbum(optAdapter); //房间相册
addDatingAction(optAdapter); // 相亲 模式
addPKAction(optAdapter); //pk PK 模式-同房间
addRoomPKAction(optAdapter); //跨房PK
addSingleRoomPKAction(optAdapter); //个播PK
// addSendBroadcastAction(optAdapter); //发布广播
// addInviteFansOptAdapter(); //邀请粉丝
addVipSendBroadcastAction(optAdapter); //小喇叭
// addRedPacketAction(optAdapter); //红包
addRoomSettingAction(optAdapter); //房间设置
addGiftEffectAction(optAdapter); //礼物特效
// addOpenOrClosePublicScreenAction(optAdapter); //公屏开关
// addRedPackageSwitch(); // 开关红包
addCleanScreenAction(optAdapter); //清空公屏
// addRoomLimit(optAdapter); //添加房间限制
// addGiftValueAction(optAdapter); //礼物值
addSuperAdminAction(optAdapter); //超管管理
addShieldReportAction(optAdapter); //举报屏蔽
addRoomTypeSwitchAction(optAdapter); //房间类型切换
rvOPtList.setAdapter(optAdapter);
}
/**
* PK 模式
* PK 模式-同房间
*
* @param optAdapter
*/
@@ -162,6 +170,9 @@ public class RoomOperationDialog extends BottomSheetDialog {
int icon = AvRoomDataManager.get().isOpenPKMode() ?
R.drawable.ic_room_opt_op_pk :
R.drawable.ic_room_opt_in_pk;
optAdapter.addData(new OptAction(icon, str, () -> {
if (AvRoomDataManager.get().isDatingMode()) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_dialog_roomoperationdialog_01));
@@ -178,7 +189,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
/**
* 跨房PK
* 跨房PK
*
* @param optAdapter
*/
@@ -202,6 +213,9 @@ public class RoomOperationDialog extends BottomSheetDialog {
int icon = AvRoomDataManager.get().isOpenAnotherPKMode() ?
R.drawable.ic_room_opt_another_pk_in :
R.drawable.ic_room_opt_another_pk_open;
optAdapter.addData(new OptAction(icon, str, () -> {
if (AvRoomDataManager.get().isDatingMode()) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_dialog_roomoperationdialog_05));
@@ -222,7 +236,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
/**
* 跨房PK
* 个播PK
*
* @param optAdapter
*/
@@ -252,6 +266,9 @@ public class RoomOperationDialog extends BottomSheetDialog {
R.drawable.ic_room_opt_single_pk_open :
R.drawable.ic_room_opt_single_pk_in;
String finalStr = str;
optAdapter.addData(new OptAction(icon, str, () -> {
if (pkBean != null && ResUtil.getString(R.string.avroom_dialog_roomoperationdialog_011).equals(finalStr)) {
SingleRoomPKModel.INSTANCE
@@ -271,6 +288,8 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
}
//房间相册
private void addRoomAlbum(OptAdapter optAdapter) {
if (AvRoomDataManager.get().isHasRoomAlbum()) {
optAdapter.addData(new OptAction(R.drawable.ic_room_operation_album, ResUtil.getString(R.string.room_album), () -> {
@@ -335,7 +354,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
/**
* 相亲 模式
* 红包
*
* @param optAdapter
*/
@@ -584,7 +603,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
/**
* 超管管理
* 发布广播
*/
private void addSendBroadcastAction(OptAdapter optAdapter) {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
@@ -609,7 +628,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
/**
* 超管管理
* 小喇叭
*/
private void addVipSendBroadcastAction(OptAdapter optAdapter) {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;

View File

@@ -22,9 +22,7 @@ import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope
@@ -48,7 +46,6 @@ import com.chwl.app.avroom.dialog.RoomGameListDialog
import com.chwl.app.avroom.dialog.RoomGameplayDialog
import com.chwl.app.avroom.dialog.RoomOperationDialog
import com.chwl.app.avroom.presenter.BaseRoomPresenter
import com.chwl.app.avroom.public_chat.PublicChatRoomMessageWidget
import com.chwl.app.avroom.room_album.RoomAlbumModel
import com.chwl.app.avroom.view.IBaseRoomView
import com.chwl.app.avroom.widget.BottomView
@@ -60,9 +57,7 @@ import com.chwl.app.event.OpenRoomIntroEvent
import com.chwl.app.friend.view.SelectFriendActivity
import com.chwl.app.home.adapter.RoomActAdapter
import com.chwl.app.music.widget.MusicPlayerView
import com.chwl.app.public_chat.ui.message.HeadlineViewModel
import com.chwl.app.room_chat.activity.RoomMsgActivity
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.ui.webview.DialogWebViewActivity
import com.chwl.app.ui.widget.ButtonItem
@@ -70,7 +65,6 @@ import com.chwl.app.ui.widget.GiftDialog
import com.chwl.app.ui.widget.GiftDialog.OnGiftDialogBtnClickListener
import com.chwl.app.ui.widget.GiftDialog.SenGiftCallback
import com.chwl.app.ui.widget.UserInfoDialog
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.app.ui.widget.dynamicface.DynamicFaceDialog
import com.chwl.app.ui.widget.magicindicator.MagicIndicator
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
@@ -79,13 +73,14 @@ import com.chwl.app.ui.widget.rollviewpager.RollPagerView
import com.chwl.app.ui.widget.rollviewpager.Util
import com.chwl.app.ui.widget.rollviewpager.hintview.ColorPointHintView
import com.chwl.app.utils.KeyBoardUtils
import com.chwl.app.vip.dialog.SelectPayTypeDialog
import com.chwl.core.Constants
import com.chwl.core.UriProvider
import com.chwl.core.auth.AuthModel
import com.chwl.core.bean.RoomMicInfo
import com.chwl.core.gift.GiftModel
import com.chwl.core.gift.bean.GiftInfo
import com.chwl.core.gift.bean.GiftType
import com.chwl.core.gift.event.GiftComboEvent
import com.chwl.core.gift.event.RoomFreeGiftEvent
import com.chwl.core.helper.AtProxy
import com.chwl.core.home.bean.BannerInfo
@@ -119,12 +114,17 @@ import com.chwl.core.support.room.RoomWidget
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.BaseInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.utils.net.BalanceNotEnoughExeption
import com.chwl.core.utils.LogUtils
import com.chwl.core.utils.net.VipLevelNotEnoughException
import com.chwl.library.common.util.LimitClickUtils
import com.chwl.library.net.rxnet.utils.RxNetWorkUtils
import com.chwl.library.rxbus.RxBus
import com.chwl.library.utils.*
import com.chwl.library.utils.JavaUtil
import com.chwl.library.utils.ListUtils
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import com.chwl.library.utils.UIUtils
import com.example.lib_utils.ktx.getString
import com.google.gson.Gson
import com.netease.nim.uikit.common.antispam.AntiSpamEvent
import com.netease.nimlib.sdk.StatusCode
@@ -136,7 +136,6 @@ import com.tbruyelle.rxpermissions2.RxPermissions
import com.trello.rxlifecycle3.android.FragmentEvent
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -157,12 +156,10 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
private var myUid: Long = 0
protected lateinit var messagePager: ViewPager2
protected lateinit var messageView: MessageView
protected var publicChatMessageWidget: PublicChatRoomMessageWidget? = null
protected lateinit var bottomView: BottomView
protected lateinit var inputLayout: RelativeLayout
protected lateinit var inputEdit: EditText
protected lateinit var inputSend: ImageView
protected lateinit var inputHeadlineSend: ImageView
protected lateinit var microView: MicroView
private var musicPlayerView: MusicPlayerView? = null
private var mVsMusicPlayer: ViewStub? = null
@@ -204,8 +201,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
// 房间小组件
private var widgets: HashMap<String, RoomWidget> = HashMap()
private val headlineViewModel by activityViewModels<HeadlineViewModel>()
@CallSuper
override fun onFindViews() {
initMessageView()
@@ -221,7 +216,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
false
}
inputSend = mView.findViewById(R.id.input_send)
inputHeadlineSend = mView.findViewById(R.id.input_headline_send)
microView = mView.findViewById(R.id.micro_view)
mVsMusicPlayer = mView.findViewById(R.id.vs_music_player)
messageView.setClickConsumer {
@@ -244,10 +238,9 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
protected open fun initMessageView() {
messagePager = mView.findViewById<ViewPager2>(R.id.message_pager)
messageView = MessageView(context)
publicChatMessageWidget = PublicChatRoomMessageWidget(requireContext())
val tabList: MutableList<String> = java.util.ArrayList(2)
tabList.add(getString(R.string.room))
tabList.add(getString(R.string.public_chat))
// tabList.add(getString(R.string.public_chat))
val messageIndicator = mView.findViewById<MagicIndicator>(R.id.message_indicator)
messagePager.offscreenPageLimit = tabList.size
messagePager.adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -255,12 +248,8 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
parent: ViewGroup,
viewType: Int
): RecyclerView.ViewHolder {
val view = if (viewType == 0) {
messageView
} else {
publicChatMessageWidget
}
view?.layoutParams = ViewGroup.LayoutParams(
val view = messageView
view.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
@@ -314,7 +303,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
override fun onSetListener() {
bottomView.setMagicBtnEnable(true)
inputSend.setOnClickListener(this)
inputHeadlineSend.setOnClickListener(this)
inputLayout.setOnTouchListener { _: View?, _: MotionEvent? ->
inputEdit.clearFocus()
inputLayout.visibility = View.GONE
@@ -322,7 +310,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
false
}
messageView.setOnLongClickListener { _, account, name ->
showInputLayout()
if (atProxy == null) atProxy = AtProxy(inputEdit)
@@ -378,44 +365,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
//获取免费礼物详情
mvpPresenter?.queryFreeFlower()
initRoomAlbum()
initHeadline()
}
private fun initHeadline() {
headlineViewModel.loadingLiveData.observe(this) {
if (it) dialogManager?.showProgressDialog(context)
else dialogManager?.dismissDialog()
}
lifecycleScope.launch(Dispatchers.Main) {
headlineViewModel.sendHeadlineFlow.collect {
if (it.isSuccess) {
SingleToastUtil.showToast(R.string.sent_success)
inputEdit.setText("")
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
} else {
if (it.code == BalanceNotEnoughExeption.code) {
showBalanceNotEnoughDialog()
} else {
SingleToastUtil.showToast(it.message)
}
}
}
}
headlineViewModel.getHeadlinePayMoneyIsNull()
}
private fun showBalanceNotEnoughDialog() {
val tipDialog = CommonTipDialog(context)
tipDialog.setTipMsg(ResUtil.getString(R.string.insufficient_balance_recharge_tips))
tipDialog.setOkText(getString(R.string.charge))
tipDialog.setOnActionListener(
object : CommonTipDialog.OnActionListener {
override fun onOk() {
ChargeActivity.start(context)
}
}
)
tipDialog.show()
}
@SuppressLint("CheckResult")
@@ -699,14 +648,14 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
@CallSuper
open fun updateMicBtn() {
//todo do 关麦开麦
val currentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo
if (currentRoomInfo != null) {
if (AudioEngineManager.get().isAudienceRole) {
bottomView.setMicBtnEnable(false)
bottomView.setMicBtnOpen(false)
} else {
val roomQueueInfo = AvRoomDataManager.get()
.getRoomQueueMemberInfoByAccount(myUid.toString())
val roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByAccount(myUid.toString())
if (roomQueueInfo?.mChatRoomMember != null
&& myUid.toString() == roomQueueInfo.mChatRoomMember.account
&& roomQueueInfo.mRoomMicInfo?.isMicMute == true
@@ -807,21 +756,17 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
}
}
R.id.iv_game -> {
val dialog = RoomGameplayDialog()
dialog.isOnlyPK = false
val dialog = RoomGameListDialog();
dialog.listener = object : RoomGameplayDialog.GameplayDialogListener {
override fun onShowBaiShunGame(url: String, config: BaiShunGameConfig) {
(activity as? AVRoomActivity)?.showBaiShunGame(url, config)
}
}
dialog.show(childFragmentManager, "ROOM_GAME_PLAY")
dialog.show(childFragmentManager, "GAME_LIST")
}
R.id.input_send -> {
sendMsg()
}
R.id.input_headline_send -> {
sendHeadline()
}
R.id.layout_room_rank -> {
DialogWebViewActivity.start(mContext, UriProvider.getRoomRanking())
}
@@ -869,41 +814,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
}
}
private fun sendHeadline() {
val message = inputEdit.text.toString().trim()
if (TextUtils.isEmpty(message)) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_fragment_baseroomfragment_08))
return
}
if (message.length > 100) {
toast(R.string.headline_input_length_limit_tips)
return
}
val money = headlineViewModel.headlinePayMoneyLiveData.value
if (money != null) {
showHeadlinePayDialog(money, message)
} else {
SingleToastUtil.showToast(R.string.ui_setting_modifypwdactivity_01)
headlineViewModel.getHeadlinePayMoney()
}
}
private fun showHeadlinePayDialog(money: Long, message: String) {
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
SelectPayTypeDialog.newInstance(
money.toString(),
money,
false
).apply {
setOnDiamondChargeClick {
headlineViewModel.sendHeadline(message)
}
setOnChargeClick {
ChargeActivity.start(context)
}
}.show(context)
}
@SuppressLint("CheckResult")
fun sendMsg(msg: String) {
if (!AuthModel.get().isImLogin) {
@@ -934,7 +844,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
return
}
mvpPresenter?.sendPublicChatTextMessage(message)
publicChatMessageWidget?.getMessageView()?.setNeedAutoScroll(true) // 發送後自動滾動公屏列表
inputEdit.setText("")
}
@@ -960,6 +869,9 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
for (i in micMemberInfos.indices) {
targetUids.add(micMemberInfos[i].account.toLong())
}
EventBus.getDefault().post(GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_BEGIN))
GiftModel.get()
.sendRoomGift(
giftInfo.giftId,
@@ -981,11 +893,18 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
dialogManager.showOkDialog(message)
}
}
.subscribe { _, throwable ->
.subscribe { gift, throwable ->
if (throwable != null) {
toast(throwable.message)
callback.onFail()
EventBus.getDefault().post(GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_CANCEL))
} else {
if (giftInfo.giftType == GiftType.GIFT_TYPE_NORMAL || giftInfo.giftType == GiftType.GIFT_TYPE_SUPER_LUCKY || giftInfo.giftType == GiftType.GIFT_TYPE_LUCKY_24) {
giftDialog?.hide()
val giftComboEvent = GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_END)
giftComboEvent.giftNumber = gift.data.giftNum
EventBus.getDefault().post(giftComboEvent)
}
callback.onSuccess()
}
}
@@ -1250,7 +1169,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
}
override fun onSendPublicChatMsgSuccess(msg: ChatRoomMessage) {
publicChatMessageWidget?.getMessageView()?.addMessages(msg)
inputEdit.setText("")
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
}
@@ -1371,6 +1289,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
giftDialog?.setOnDismissListener { giftDialog = null }
}
if (giftDialog?.isShowing != true && !requireActivity().isFinishing) {
EventBus.getDefault().post(GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_POINT))
giftDialog?.show()
}
}
@@ -1419,8 +1338,8 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
open inner class BaseRoomBottomViewWrapper : BottomViewListenerWrapper() {
@SuppressLint("CheckResult")
override fun onOpenMicBtnClick() {
val roomQueueInfo = AvRoomDataManager.get()
.getRoomQueueMemberInfoByAccount(AuthModel.get().currentUid.toString())
//todo do 关麦开麦
val roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByAccount(AuthModel.get().currentUid.toString())
if (roomQueueInfo?.mRoomMicInfo == null) return
//先判斷麥上是否是開麥的
if (!roomQueueInfo.mRoomMicInfo.isMicMute && !AudioEngineManager.get().isAudienceRole) {
@@ -1542,9 +1461,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
}
open fun initWidget() {
publicChatMessageWidget?.let {
registerWidget(PublicChatRoomMessageWidget::class.java.simpleName, it)
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -1562,7 +1478,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
* 打开公屏输入
*/
fun openMessageInput(text: String?) {
inputHeadlineSend.isVisible = isPublicMessageTab()
inputLayout.visibility = View.VISIBLE
if (text != null) {
inputEdit.setText(text)
@@ -1580,4 +1495,24 @@ open class BaseRoomFragment<V : IBaseRoomView?, P1 : BaseRoomPresenter<V>?> :
protected open fun onInitMusicPlayerView(view: MusicPlayerView) {
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onGiftComboEvent(event: GiftComboEvent) {
when (event.action) {
GiftComboEvent.Action.ACT_GIFT_START-> {
giftDialog?.sendGift()
}
GiftComboEvent.Action.ACT_GIFT_SHOW-> {
giftDialog?.show()
}
else -> {}
}
}
}

View File

@@ -100,9 +100,6 @@ class GameRoomFragment : BaseRoomFragment<IGameRoomView?, GameRoomPresenter?>(),
messageView.messageListView?.let {
setMessagePagerAutoHeight(it)
}
publicChatMessageWidget?.getMessageView()?.messageListView?.let {
setMessagePagerAutoHeight(it)
}
}
override fun onClick(v: View) {

View File

@@ -6,7 +6,10 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewStub;
@@ -19,9 +22,26 @@ import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import com.chwl.app.avroom.activity.RoomTitleEditActivity;
import com.chwl.app.avroom.dialog.RoomNotifyLuckGiftDialog;
import com.chwl.app.databinding.LayoutRoomNotifyLuckyGiftTipBinding;
import com.chwl.app.utils.GiftAnimUtil;
import com.chwl.app.utils.NumberUtils;
import com.chwl.app.utils.RoomNotifyManager;
import com.chwl.app.utils.WeakPool;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.gift.bean.CpMsgBean;
import com.chwl.core.gift.bean.LuckyGiftMsgAllBean;
import com.chwl.core.gift.bean.LuckyGiftMsgSelfBean;
import com.chwl.core.gift.bean.MsgSuperLuckyGift;
import com.chwl.core.gift.bean.RoomNotifyDialogBean;
import com.chwl.core.utils.ComboUtil;
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
import com.chwl.app.ui.widget.BonsellaJoinAttackButtonView;
import com.chwl.app.ui.widget.GiftDialog;
import com.chwl.app.ui.widget.UserInfoDialog;
import com.chwl.core.gift.event.GiftComboEvent;
import com.chwl.core.gift.toolbox.GiftToolbox;
import com.chwl.core.utils.LogUtils;
import com.chwl.library.utils.JavaUtil;
import com.example.lib_utils.UiUtils;
import com.netease.nim.uikit.common.util.string.StringUtil;
@@ -66,6 +86,7 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.lang.reflect.Field;
import java.util.ArrayList;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
@@ -101,6 +122,7 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
//收藏房间
private String FOLLOW_ROOM_TYPE = "";
public static HomePartyFragment newInstance() {
HomePartyFragment homePartyFragment = new HomePartyFragment();
Bundle bundle = new Bundle();
@@ -243,7 +265,7 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
case RoomEvent.ROOM_INFO_UPDATE:
updateView(AvRoomDataManager.get().mCurrentRoomInfo);
break;
case RoomEvent.RECEIVE_NORMALE_GIFT:
case RoomEvent.RECEIVE_NORMALE_GIFT://普通
onReceiveGiftMsg(roomEvent.getGiftReceiveInfo());
break;
case RoomEvent.RECEIVE_MUTLT_NORMALEI_GIFT://普通多人
@@ -267,12 +289,20 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
case RoomEvent.FANS_TEAM_JOIN:
onReceiveFansTeamJoinMsg(roomEvent.getChatRoomMessage());
break;
case RoomEvent.MSG_SUPER_LUCKY_GIFT:
onLuckyGiftMsg(roomEvent);
break;
case RoomEvent.MSG_CP_ABOUT:
onCpAboutMsg(roomEvent);
break;
default:
break;
}
});
}
/**
* 获取礼物飘屏是否展示
*
@@ -491,10 +521,16 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
@Override
public void onDestroy() {
luckyGiftTipPool.clear();
handler.removeCallbacksAndMessages(null);
RoomNotifyManager.INSTANCE.clear();
if (giftView != null) {
giftView.release();
}
EventBus.getDefault().unregister(this);
gameMainBinding.giftComboBtn.cancel();
super.onDestroy();
}
@@ -508,10 +544,10 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
updateOnlineNumberView(onlineNumber);
}
/**
* 普通多人
*
* @param giftMultiReceiverInfo
*/
private void onReceiveMultiGiftMsg(GiftMultiReceiverInfo giftMultiReceiverInfo) {
if (giftMultiReceiverInfo == null || !isResumed()) return;
@@ -519,12 +555,12 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveGiftToMultiMsg(giftMultiReceiverInfo);
giftMultiReceiverInfo.isMulti = true;
gameMainBinding.giftComboLayout.onRoomCustomMsg(giftMultiReceiverInfo);
}
/**
* 普通全麦
*
* @param multiGiftReceiveInfo
*/
private void onReceiveAllMicGiftMsg(MultiGiftReceiveInfo multiGiftReceiveInfo) {
if (multiGiftReceiveInfo == null || !isResumed()) return;
@@ -532,14 +568,20 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveMultiGiftMsg(multiGiftReceiveInfo);
gameMainBinding.giftComboLayout.onRoomCustomMsg(GiftToolbox.transformToGiftMultiReceiverInfo(multiGiftReceiveInfo));
}
/**
* 普通
*/
private void onReceiveGiftMsg(GiftReceiveInfo giftReceiveInfo) {
if (giftReceiveInfo == null || !isResumed()) return;
if (giftView == null) {
giftView = (GiftV2View) mVsGift2View.inflate();
}
giftView.onReceiveGiftMsg(giftReceiveInfo);
gameMainBinding.giftComboLayout.onRoomCustomMsg(GiftToolbox.transformToGiftMultiReceiverInfo(giftReceiveInfo));
}
private void onReceiveMagicMsg(MagicReceivedInfo magicReceivedInfo) {
@@ -611,4 +653,143 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
dialogFragment.show(requireActivity().getSupportFragmentManager(), "roomTitle");
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onGiftComboEvent(GiftComboEvent event) {
if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_BEGIN) {
if (gameMainBinding.giftComboBtn.isInCombo()){
gameMainBinding.giftComboBtn.waitStart();
}
} else if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_END) {
showComboBtn(event.getGiftNumber());
}else if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_CANCEL) {
if (gameMainBinding.giftComboBtn.isInCombo()) {
gameMainBinding.giftComboBtn.cancel();
}
}else if (event.getAction() == GiftComboEvent.Action.ACT_GIFT_POINT) {
ComboUtil.INSTANCE.setPoint(gameMainBinding.giftComboBtn);
}
}
private void showComboBtn(int number) {
if (gameMainBinding.giftComboBtn.getOnGiftComboEndListener() == null) {
gameMainBinding.giftComboBtn.setOnClickListener(v -> {
ComboUtil.INSTANCE.setPoint(gameMainBinding.giftComboBtn);
EventBus.getDefault().post(new GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_START));
gameMainBinding.giftComboBtn.onBtnDown();
});
gameMainBinding.giftComboBtn.setOnGiftComboEndListener(new BonsellaJoinAttackButtonView.OnGiftComboEndListener() {
@Override
public void onGiftComboEnd() {
gameMainBinding.giftComboBtn.showView(false);
EventBus.getDefault().post(new GiftComboEvent(GiftComboEvent.Action.ACT_GIFT_SHOW));
}
});
}
gameMainBinding.giftComboBtn.showView(true);
gameMainBinding.giftComboBtn.start();
gameMainBinding.giftComboBtn.updateNumber(number);
}
/**
* 幸运礼物 飘屏 跟 圆球提示
*/
private void onLuckyGiftMsg(RoomEvent roomEvent) {
MsgSuperLuckyGift msgSuperLuckyGift = roomEvent.getMsgSuperLuckyGift();
if (msgSuperLuckyGift != null) {
if (msgSuperLuckyGift.luckyGiftMsgAllBean != null) {
showLuckyGiftDlg(msgSuperLuckyGift.luckyGiftMsgAllBean);
}
if (msgSuperLuckyGift.luckyGiftMsgSelfBean != null) {
showLuckyGiftDlgNotify(msgSuperLuckyGift.luckyGiftMsgSelfBean);
}
}
}
private Handler handler = new Handler(Looper.getMainLooper());
private WeakPool<View> luckyGiftTipPool = new WeakPool<>(3);
private void showLuckyGiftDlgNotify(LuckyGiftMsgSelfBean luckyGiftMsgBean) {
if (luckyGiftMsgBean == null) return;
if (luckyGiftMsgBean.getUid() != AuthModel.get().getCurrentUid()) return;
if (luckyGiftMsgBean.getRoomId() != AvRoomDataManager.get().getRoomId()) return;
if (luckyGiftMsgBean.getRoomUid() != AvRoomDataManager.get().getRoomUid()) return;
LogUtils.i(" showLuckyGiftDlgNotify = start");
View root = luckyGiftTipPool.acquire(() -> {
return LayoutInflater.from(gameMainBinding.flLuckyGiftNotifyLayout.getContext()).inflate(R.layout.layout_room_notify_lucky_gift_tip, gameMainBinding.flLuckyGiftNotifyLayout, false);
});
LayoutRoomNotifyLuckyGiftTipBinding binding = LayoutRoomNotifyLuckyGiftTipBinding.bind(root);
binding.coinNum.setText(NumberUtils.format(luckyGiftMsgBean.getCoins()));
binding.winNum.setText(java.lang.String.valueOf(luckyGiftMsgBean.getTimes()));
if (luckyGiftMsgBean.getLevel() > 1) {
binding.rootView.setBackgroundResource(R.drawable.bg_lucky_gift_tip_2);
}
root.setAlpha(0f);
root.setScaleX(0f);
root.setScaleY(0f);
gameMainBinding.flLuckyGiftNotifyLayout.addView(root);
GiftAnimUtil.showAnimation(root);
// GiftAnimUtil.expandAnimation(root);
handler.postDelayed(() -> {
try {
root.animate()
.alpha(0f)
.setDuration(500)
.withEndAction(() -> {
gameMainBinding.flLuckyGiftNotifyLayout.post(new Runnable() {
@Override
public void run() {
root.clearAnimation();
gameMainBinding.flLuckyGiftNotifyLayout.removeView(root);
luckyGiftTipPool.release(root);
}
});
})
.start();
} catch (Exception e) {
}
}, 2300);
}
private void showLuckyGiftDlg(LuckyGiftMsgAllBean data) {
//todo do 校验数据是否异常
RoomNotifyManager.INSTANCE.addDialog(new RoomNotifyDialogBean(
CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE,
CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_ROOM,
data
));
}
/**
* cp 礼物
*/
private void onCpAboutMsg(RoomEvent roomEvent) {
//todo do 校验数据是否异常
CpMsgBean cpMsgBean = roomEvent.getCpMsgBean();
if (cpMsgBean != null) {
RoomNotifyManager.INSTANCE.addDialog(new RoomNotifyDialogBean(
CustomAttachment.CP_FIRST,
cpMsgBean.getSecond(),
cpMsgBean
));
}
}
}

View File

@@ -22,6 +22,8 @@ import com.chwl.core.room.bean.RoomIcon;
import com.chwl.core.room.core.RoomDataService;
import com.chwl.core.room.pk.event.PKDataUpdateEvent;
import com.chwl.core.support.room.AudioRoomContext;
import com.chwl.core.support.room.RoomAbility;
import com.chwl.core.support.room.RoomContext;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.trello.rxlifecycle3.android.FragmentEvent;
import com.chwl.app.R;
@@ -162,24 +164,30 @@ public class HomePartyRoomFragment extends BaseRoomFragment<IHomePartyView, Home
}
private void requestData() {
RoomDataService dataService = (RoomDataService) AudioRoomContext.Companion.get().findAbility(RoomDataService.class.getSimpleName());
String cacheKey = "gameplay_list#" + hashCode();
Disposable disposable = AvRoomModel.get().getRoomGamePlayList().doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
hasBaishunGames = false;
updateConfigButtonArea();
RoomContext roomContext = AudioRoomContext.Companion.get();
if (roomContext != null) {
RoomDataService dataService = roomContext.findAbility(RoomDataService.class.getSimpleName());
if (dataService != null) {
String cacheKey = "gameplay_list#" + hashCode();
Disposable disposable = AvRoomModel.get().getRoomGamePlayList().doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
hasBaishunGames = false;
updateConfigButtonArea();
}
}).subscribe(new Consumer<List<RoomIcon>>() {
@Override
public void accept(List<RoomIcon> roomIcons) throws Exception {
if (dataService != null) {
dataService.putData(cacheKey, roomIcons);
}
hasBaishunGames = roomIcons.size() > 0;
updateConfigButtonArea();
}
});
}
}).subscribe(new Consumer<List<RoomIcon>>() {
@Override
public void accept(List<RoomIcon> roomIcons) throws Exception {
if (dataService != null) {
dataService.putData(cacheKey, roomIcons);
}
hasBaishunGames = roomIcons.size() > 0;
updateConfigButtonArea();
}
});
}
}
@Override
@@ -547,14 +555,10 @@ public class HomePartyRoomFragment extends BaseRoomFragment<IHomePartyView, Home
}
}
if (AvRoomDataManager.get().isDatingMode()) {
if (hasBaishunGames) {
gameBinding.ivGame.setVisibility(View.VISIBLE);
}else {
gameBinding.ivGame.setVisibility(View.GONE);
} else {
if (hasBaishunGames) {
gameBinding.ivGame.setVisibility(View.VISIBLE);
}else {
gameBinding.ivGame.setVisibility(View.GONE);
}
}
}

View File

@@ -26,6 +26,7 @@ import com.chwl.app.fansteam.FansTeamJoinActivity
import com.chwl.app.fansteam.FansTeamJoinedActivity
import com.chwl.app.fansteam.FansTeamViewModel
import com.chwl.app.music.widget.MusicPlayerView
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.ui.webview.DialogWebViewActivity
import com.chwl.core.UriProvider
@@ -36,6 +37,10 @@ import com.chwl.core.im.custom.bean.RequestUpmicAttachment
import com.chwl.core.im.custom.bean.RoomPKAttachment
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.manager.RoomEvent
import com.chwl.core.room.core.RoomDataService
import com.chwl.core.room.model.AvRoomModel
import com.chwl.core.support.room.AudioRoomContext.Companion.get
import com.chwl.core.support.room.RoomAbility
import com.chwl.core.user.bean.UserInfo
import com.chwl.library.base.factory.CreatePresenter
import com.netease.nim.uikit.common.util.sys.ScreenUtil
@@ -63,6 +68,8 @@ class SingleRoomFragment : BaseRoomFragment<ISingleRoomView?, SingleRoomPresente
private lateinit var gameBinding: FragmentSingleRoomBinding
private lateinit var upMicDialog: RequestUpMicDialog
private var hasBaishunGames = false
private val fansTeamViewModel: FansTeamViewModel by viewModels()
override fun getRootLayoutId(): Int {
return R.layout.fragment_single_room

View File

@@ -93,8 +93,8 @@ class RoomHeadlineWidget : FrameLayoutRoomWidget {
private fun requestCurrentHeadline() {
safeLaunch {
val data = PublicChatModel.getCurrentHeadline()
updateHeadline(data)
// val data = PublicChatModel.getCurrentHeadline()
// updateHeadline(data)
}
}

View File

@@ -1,884 +0,0 @@
package com.chwl.app.avroom.public_chat;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.chwl.app.R;
import com.chwl.app.UIHelper;
import com.chwl.app.avroom.activity.AVRoomActivity;
import com.chwl.app.avroom.dialog.RoomTeamPKResultDialog;
import com.chwl.app.avroom.widget.OnMsgLongClickListener;
import com.chwl.app.avroom.widget.TemplateMessageAdapter;
import com.chwl.app.common.widget.CustomImageSpan;
import com.chwl.app.common.widget.OriginalDrawStatusClickSpan;
import com.chwl.app.photo.BigPhotoActivity;
import com.chwl.app.photo.PagerOption;
import com.chwl.app.public_chat.core.viewholder.ChatRoomMessageViewHolderThumbBase;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
import com.chwl.app.ui.widget.DividerItemDecoration;
import com.chwl.app.ui.widget.MyItemAnimator;
import com.chwl.app.ui.widget.RecyclerViewNoViewpagerScroll;
import com.chwl.app.ui.widget.TextSpannableBuilder;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.utils.ObjectTypeHelper;
import com.chwl.app.utils.RegexUtil;
import com.chwl.core.DemoCache;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.bean.attachmsg.RoomQueueMsgAttachment;
import com.chwl.core.decoration.car.bean.CarInfo;
import com.chwl.core.home.event.FollowRoomEvent;
import com.chwl.core.home.model.CollectionRoomModel;
import com.chwl.core.im.custom.bean.CustomAttachment;
import com.chwl.core.im.custom.bean.HeadlineChangedAttachment;
import com.chwl.core.im.custom.bean.MonsterHuntingResultAttachment;
import com.chwl.core.im.custom.bean.MonsterStatusAttachment;
import com.chwl.core.im.custom.bean.RoomBoxPrizeAttachment;
import com.chwl.core.im.custom.bean.RoomFollowOwnerAttachment2;
import com.chwl.core.im.custom.bean.RoomTipAttachment;
import com.chwl.core.im.custom.bean.TarotAttachment;
import com.chwl.core.level.UserLevelResourceType;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.monsterhunting.bean.MonsterDataBean;
import com.chwl.core.monsterhunting.bean.MonsterHuntingResult;
import com.chwl.core.noble.NobleUtil;
import com.chwl.core.praise.PraiseModel;
import com.chwl.core.public_chat_hall.bean.HeadlineBean;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.pk.attachment.RoomPkAttachment;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.core.utils.ExtensionUtil;
import com.chwl.library.common.util.Utils;
import com.chwl.library.utils.JavaUtil;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.SizeUtils;
import com.example.lib_utils.UiUtils;
import com.example.lib_utils.spannable.SpannableTextBuilder;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.common.util.media.ImageUtil;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessageExtension;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment;
import com.netease.nimlib.sdk.msg.attachment.ImageAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.NotificationType;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.reactivex.Single;
import io.reactivex.functions.Consumer;
import kotlin.jvm.functions.Function1;
/**
* 直播間消息界面
*
* @author xiaoyu
*/
public class PublicChatMessageView extends FrameLayout {
private static final String TAG = "PublicChatMessageView";
private final static int MAX_MESSAGE_SIZE = 100;//公屏最多展示條數
private final static int BLOCK_MAX_MESSAGE_SIZE = MAX_MESSAGE_SIZE * 3 / 2;//在查看消息停住的時候 最多消息條數.
private final List<ChatRoomMessage> atMessages = new ArrayList<>();
private final List<ChatRoomMessage> chatRoomMessages = new LinkedList<>();
private RecyclerView messageListView;
private TextView tvBottomTip;
private TextView tvAtTip;
private MessageAdapter mMessageAdapter;
private LinearLayoutManager layoutManger;
private int paddingWidth;
private int paddingHeight;
private int whiteColor;
private int greyColor;
private int roomTipColor;
private int badgeWidth;
private int badgeHeight;
private int expLevelHeight;
private int defTextSize = 12;
private volatile boolean needAutoScroll = true;//是否自動滾動到底部
private Consumer<String> clickConsumer;
private OnClick onClick;
private OnMsgLongClickListener onLongClickListener;
private TemplateMessageAdapter templateMessageAdapter;
public PublicChatMessageView(Context context) {
this(context, null);
}
public PublicChatMessageView(Context context, AttributeSet attr) {
this(context, attr, 0);
}
public PublicChatMessageView(Context context, AttributeSet attr, int i) {
super(context, attr, i);
init(context);
}
public void setOnLongClickListener(OnMsgLongClickListener onLongClickListener) {
this.onLongClickListener = onLongClickListener;
}
public void setClickConsumer(Consumer<String> clickConsumer) {
this.clickConsumer = clickConsumer;
}
public void setOnClick(OnClick onClick) {
this.onClick = onClick;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
@SuppressLint("ClickableViewAccessibility")
private void init(Context context) {
whiteColor = ContextCompat.getColor(context, R.color.white);
greyColor = ContextCompat.getColor(context, R.color.white_transparent_50);
roomTipColor = ContextCompat.getColor(context, R.color.color_FEE057);
paddingWidth = Utils.dip2px(context, 11);
paddingHeight = Utils.dip2px(context, 6);
badgeWidth = Utils.dip2px(context, 15);
badgeHeight = Utils.dip2px(context, 15);
//經驗等級圖片後臺已經更換尺寸了公屏同步下尺寸是36:18
expLevelHeight = Utils.dip2px(context, 18);
// 內容區域
layoutManger = new LinearLayoutManager(context, RecyclerView.VERTICAL, false);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
messageListView = new RecyclerViewNoViewpagerScroll(context);
messageListView.setLayoutParams(params);
messageListView.setFadingEdgeLength(60);
messageListView.setVerticalFadingEdgeEnabled(true);
messageListView.setOverScrollMode(OVER_SCROLL_NEVER);
messageListView.setHorizontalScrollBarEnabled(false);
addView(messageListView);
messageListView.setLayoutManager(layoutManger);
messageListView.addItemDecoration(new DividerItemDecoration(context, layoutManger.getOrientation(), 16, R.color.transparent));
mMessageAdapter = new MessageAdapter(getContext());
mMessageAdapter.setData(chatRoomMessages);
messageListView.setAdapter(mMessageAdapter);
messageListView.setItemAnimator(new MyItemAnimator());
messageListView.getItemAnimator().setAddDuration(0);
messageListView.getItemAnimator().setChangeDuration(0);
messageListView.getItemAnimator().setMoveDuration(0);
messageListView.getItemAnimator().setRemoveDuration(0);
((SimpleItemAnimator) messageListView.getItemAnimator()).setSupportsChangeAnimations(false);
// 底部有新消息
tvBottomTip = new TextView(context);
LayoutParams params1 = new LayoutParams(
Utils.dip2px(context, 115F), Utils.dip2px(context, 27));
params1.gravity = Gravity.BOTTOM;
params1.leftMargin = UIUtil.getScreenWidth(context) / 2 - UIUtil.dip2px(context, 115 / 2);
tvBottomTip.setBackgroundResource(R.drawable.bg_messge_view_bottom_tip);
tvBottomTip.setGravity(Gravity.CENTER);
tvBottomTip.setText(context.getString(R.string.message_view_bottom_tip));
tvBottomTip.setTextColor(context.getResources().getColor(R.color.appColor));
tvBottomTip.setLayoutParams(params1);
tvBottomTip.setVisibility(GONE);
tvBottomTip.setOnClickListener(v -> {
tvBottomTip.setVisibility(GONE);
needAutoScroll = true;
if (mMessageAdapter.getItemCount() > 0) {
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
}
});
addView(tvBottomTip);
//有人@我
tvAtTip = new TextView(context);
LayoutParams params2 = new LayoutParams(
Utils.dip2px(context, 115F), Utils.dip2px(context, 27));
params2.gravity = Gravity.BOTTOM;
params2.leftMargin = UIUtil.getScreenWidth(context) / 2 - UIUtil.dip2px(context, 115 / 2);
tvAtTip.setBackgroundResource(R.drawable.bg_messge_view_bottom_tip);
tvAtTip.setGravity(Gravity.CENTER);
tvAtTip.setText(context.getString(R.string.message_view_bottom_tip));
tvAtTip.setTextColor(context.getResources().getColor(R.color.color_FD85C9));
tvAtTip.setLayoutParams(params2);
tvAtTip.setVisibility(GONE);
tvAtTip.setOnClickListener(v -> {
if (!atMessages.isEmpty()) {
int scrollIndex = chatRoomMessages.indexOf(atMessages.remove(0));
if (scrollIndex != -1 && scrollIndex < mMessageAdapter.getItemCount()) {
messageListView.smoothScrollToPosition(scrollIndex);
}
}
needAutoScroll = false;
checkShowAtTip();
});
addView(tvAtTip);
messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
}
@Override
public void onScrollStateChanged(final RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
// Logger.e(TAG, "onScrollStateChanged: SCROLL_STATE_DRAGGING");
needAutoScroll = false;
}
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// Logger.e(TAG, "onScrollStateChanged: SCROLL_STATE_IDLE");
int lastVisibleItemPosition = layoutManger.findLastVisibleItemPosition();
if (lastVisibleItemPosition == RecyclerView.NO_POSITION) {
// Logger.e(TAG, "lastCompletelyVisibleItemPosition : RecyclerView.NO_POSITION");
needAutoScroll = true;
} else if (!atMessages.isEmpty() && atMessages.remove(chatRoomMessages.get(lastVisibleItemPosition))) {
checkShowAtTip();
}
// Log.e(TAG, "lastVisibleItemPosition:" + lastVisibleItemPosition
// + " mMessageAdapter.getItemCount()-1:" + (recyclerView.getAdapter().getItemCount()-1)
// + " dis:"+ (lastVisibleItemPosition-(recyclerView.getAdapter().getItemCount()-1)));
if (lastVisibleItemPosition >= recyclerView.getAdapter().getItemCount() - 3) {
//最後一個顯示出來了
// Logger.e(TAG, ResUtil.getString(R.string.avroom_widget_messageview_01));
needAutoScroll = true;
tvBottomTip.setVisibility(GONE);
keepSizeUnderLimit();
} else {
// Logger.e(TAG, ResUtil.getString(R.string.avroom_widget_messageview_02));
// needAutoScroll = false;
}
}
}
});
}
private TemplateMessageAdapter getTemplateMessageAdapter() {
if (templateMessageAdapter == null) {
templateMessageAdapter = new TemplateMessageAdapter(uid -> {
if (clickConsumer != null) {
Single.just(String.valueOf(uid)).subscribe(clickConsumer);
}
});
}
return templateMessageAdapter;
}
/**
* 添加公屏消息請使用 {@link AvRoomDataManager#addChatRoomMessage(ChatRoomMessage)}
*/
public void addMessages(ChatRoomMessage msg) {
if (msg == null) return;
chatRoomMessages.add(msg);
//通知adapter 刷新
mMessageAdapter.notifyItemInserted(mMessageAdapter.getItemCount() - 1);
showTipsOrScrollToBottom();
checkAtMe(msg, false);
}
public void addMessages(List<ChatRoomMessage> messages) {
if (messages == null) return;
chatRoomMessages.addAll(messages);
//通知adapter 刷新
mMessageAdapter.notifyDataSetChanged();
showTipsOrScrollToBottom();
for (ChatRoomMessage message : messages) {
checkAtMe(message, true);
}
}
public void addHistoryMessages(List<ChatRoomMessage> messages) {
chatRoomMessages.addAll(0, messages);
mMessageAdapter.notifyDataSetChanged();
messageListView.scrollToPosition(mMessageAdapter.getItemCount() - 1);
for (ChatRoomMessage message : messages) {
checkAtMe(message, true);
}
}
private void keepSizeUnderLimit() {
while (chatRoomMessages.size() > MAX_MESSAGE_SIZE) {
Log.i("keepSizeUnderLimit", "size" + chatRoomMessages.size());
ChatRoomMessage message = chatRoomMessages.remove(0);
if (atMessages.remove(message)) {
checkShowAtTip();
}
mMessageAdapter.notifyItemRemoved(0);
}
}
private void checkShowAtTip() {
tvAtTip.setText(getContext().getString(R.string.message_at_tip, atMessages.size()));
tvAtTip.setVisibility(atMessages.size() == 0 ? GONE : VISIBLE);
}
private void checkAtMe(ChatRoomMessage msg, boolean history) {
if (msg.getMsgType() != MsgTypeEnum.text) return;
List<String> atUids = ExtensionUtil.getListExtension(msg, UserInfo.AT_UIDS);
List<String> atNames = ExtensionUtil.getListExtension(msg, UserInfo.AT_NAMES);
if (!ListUtils.isListEmpty(atUids) && !ListUtils.isListEmpty(atNames)) {
for (int i = 0; i < atUids.size(); i++) {
String uid = atUids.get(i);
// 只有當被 @ 人的數組中包含自己的時候才會去變色
if (Objects.equals(uid, String.valueOf(AuthModel.get().getCurrentUid()))) {
Map<String, Long> atMap = DemoCache.readAtMsgUuid();
if (atMap == null || !atMap.containsKey(msg.getUuid())) {
if (!atMessages.contains(msg) && (!needAutoScroll || history)) {
atMessages.add(msg);
checkShowAtTip();
}
DemoCache.saveAtMsgUuid(msg.getUuid());
}
}
}
}
}
public void showTipsOrScrollToBottom() {
if (!needAutoScroll) {
tvBottomTip.setVisibility(VISIBLE);
//超過某值後自動滾動下去
if (mMessageAdapter.getItemCount() > BLOCK_MAX_MESSAGE_SIZE) {
if (mMessageAdapter.getItemCount() > 0) {
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
}
}
return;
}
}
public void release() {
}
public void clear() {
if (mMessageAdapter != null) {
chatRoomMessages.clear();
mMessageAdapter.notifyDataSetChanged();
}
if (tvBottomTip != null) {
needAutoScroll = true;
tvBottomTip.setVisibility(GONE);
}
}
public void setNeedAutoScroll(boolean needAutoScroll) {
this.needAutoScroll = needAutoScroll;
}
public RecyclerView getMessageListView(){
return messageListView;
}
public interface OnClick {
/**
* 公屏查看公告
*/
void onShowRoomIntroduction();
}
private class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> implements OnClickListener,Function1<Drawable, ImageSpan> {
private Context mContext;
private List<ChatRoomMessage> data;
private int ITEM_TYPE_IMAGE = 1;
public MessageAdapter(Context mContext) {
this.mContext = mContext;
}
public void setData(List<ChatRoomMessage> data) {
this.data = data;
}
@Override
public int getItemViewType(int position) {
ChatRoomMessage chatRoomMessage = data.get(position);
if (chatRoomMessage.getMsgType() == MsgTypeEnum.image) {
return ITEM_TYPE_IMAGE;
}
return super.getItemViewType(position);
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_TYPE_IMAGE) {
return new MessageAdapter.MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_chatroom_msg_image, parent, false));
}
return new MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_chatrrom_msg, parent, false));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
if (getItemViewType(position) == ITEM_TYPE_IMAGE) {
convertImage(holder, data.get(position));
} else {
convert(holder, data.get(position));
}
}
@Override
public int getItemCount() {
return data.size();
}
protected void convertImage(MessageViewHolder baseViewHolder, ChatRoomMessage chatRoomMessage) {
TextView tvContent = baseViewHolder.tvContent;
tvContent.setLineSpacing(0, 1);
tvContent.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
tvContent.setOnClickListener(this);
tvContent.setTag(chatRoomMessage);
if (UiUtils.INSTANCE.isRtl(tvContent.getContext())) {
tvContent.setTextDirection(View.TEXT_DIRECTION_RTL);
}
try {
setVIPMessageBackground(chatRoomMessage, baseViewHolder.itemView);
ChatRoomMessageExtension extension = chatRoomMessage.getChatRoomMessageExtension();
TextSpannableBuilder text = new TextSpannableBuilder(tvContent);
addCommonTag(chatRoomMessage, text, tvContent);
String nickName = extension == null ? ResUtil.getString(R.string.avroom_widget_messageview_0116) : RegexUtil.getPrintableString(extension.getSenderNick());
text.append(nickName, new ForegroundColorSpan(greyColor));
tvContent.setText(text.build());
ImageView imageView = baseViewHolder.itemView.findViewById(R.id.iv_image);
ImageAttachment msgAttachment = (ImageAttachment) chatRoomMessage.getAttachment();
String path = msgAttachment.getThumbPath();
if (TextUtils.isEmpty(path)) {
path = msgAttachment.getPath();
}
if (TextUtils.isEmpty(path)) {
path = "";
}
ImageLoadUtilsV2.loadImage(imageView, path);
int[] bounds = new int[]{msgAttachment.getWidth(), msgAttachment.getHeight()};
ImageUtil.ImageSize imageSize = ImageUtil.getThumbnailDisplaySize(bounds[0], bounds[1], ChatRoomMessageViewHolderThumbBase.getImageMaxEdge(), ChatRoomMessageViewHolderThumbBase.getImageMinEdge());
ViewGroup.LayoutParams maskParams = imageView.getLayoutParams();
maskParams.width = imageSize.width;
maskParams.height = imageSize.height;
imageView.setLayoutParams(maskParams);
String finalPath = path;
imageView.setOnClickListener(v -> {
BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.pathToCustomItems(finalPath),
0, new PagerOption());
});
} catch (Exception e) {
e.printStackTrace();
}
}
protected void convert(MessageViewHolder baseViewHolder, ChatRoomMessage chatRoomMessage) {
if (chatRoomMessage == null) return;
TextView tvContent = baseViewHolder.tvContent;
tvContent.setLineSpacing(0, 1);
tvContent.setTextColor(Color.WHITE);
tvContent.setTextSize(defTextSize);
tvContent.setOnClickListener(this);
tvContent.setOnLongClickListener(null);
tvContent.setTag(chatRoomMessage);
tvContent.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
if (UiUtils.INSTANCE.isRtl(tvContent.getContext())) {
tvContent.setTextDirection(View.TEXT_DIRECTION_RTL);
}
clearBackground(tvContent);
try {
if (chatRoomMessage.getMsgType() == MsgTypeEnum.tip) {
// 房間通告
tvContent.setTextColor(ContextCompat.getColor(mContext, R.color.color_white));
tvContent.setText(chatRoomMessage.getContent());
tvContent.setBackgroundResource(R.drawable.shape_room_message_tip_bg);
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.text) {
setMsgText(chatRoomMessage, tvContent);
setVIPMessageBackground(chatRoomMessage, tvContent);
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.notification) {
// 加上勛章
setMsgNotification(chatRoomMessage, tvContent, baseViewHolder.getAdapterPosition());
setVIPMessageBackground(chatRoomMessage, tvContent);
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
if (chatRoomMessage.getAttachment() != null && chatRoomMessage.getAttachment() instanceof CustomAttachment) {
CustomAttachment attachment = (CustomAttachment) chatRoomMessage.getAttachment();
int first = attachment.getFirst();
int second = attachment.getSecond();
if (first == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED) {
if (second == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED_SUB) {
setHeadlineMsg(chatRoomMessage, tvContent, attachment);
}
} else {
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
}
} else {
tvContent.setText("");
}
}
} catch (UnsupportedOperationException e) {
e.printStackTrace();
clearBackground(tvContent);
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
} catch (Exception e) {
clearBackground(tvContent);
tvContent.setText("");
}
}
private void clearBackground(TextView textView) {
// 清除文字
textView.setText("");
// 清除聊天氣泡
textView.setBackgroundResource(R.drawable.shape_room_message_bg);
textView.setPadding(paddingWidth, paddingHeight, paddingWidth, paddingHeight);
}
private void setNullBackground(TextView textView) {
// 清除聊天氣泡
textView.setBackground(null);
textView.setPadding(0, 0, 0, 0);
}
public void setVIPMessageBackground(ChatRoomMessage chatRoomMessage, View view) {
String androidBubbleUrl = NobleUtil.getResource(UserInfo.BUBBLE_URL_ANDROID, chatRoomMessage);
if (TextUtils.isEmpty(androidBubbleUrl)) return;
view.setPadding(paddingWidth, ScreenUtil.dip2px(10), paddingWidth, ScreenUtil.dip2px(10));
ImageLoadUtils.loadNinePatchBg(view, androidBubbleUrl);
}
/**
* {badge}{level}xxx: 文字內容
*
* @param chatRoomMessage -
* @param tvContent -
*/
private void setMsgText(ChatRoomMessage chatRoomMessage, TextView tvContent) {
TextSpannableBuilder text = new TextSpannableBuilder(tvContent);
addCommonTag(chatRoomMessage, text, tvContent);
String nickName;
if (chatRoomMessage.getFromAccount() != null && chatRoomMessage.getFromAccount().equals(AuthModel.get().getCurrentUid() + "")) {
nickName = ResUtil.getString(R.string.avroom_widget_messageview_0116);
} else {
nickName = NobleUtil.getNamePlate(UserInfo.NICK, chatRoomMessage);
}
text.append(nickName, new ForegroundColorSpan(greyColor));
text.append(": " + chatRoomMessage.getContent(), new ForegroundColorSpan(getResources().getColor(R.color.white)));
List<String> atUids = ExtensionUtil.getListExtension(chatRoomMessage, UserInfo.AT_UIDS);
List<String> atNames = ExtensionUtil.getListExtension(chatRoomMessage, UserInfo.AT_NAMES);
if (!ListUtils.isListEmpty(atUids) && !ListUtils.isListEmpty(atNames)) {
for (int i = 0; i < atUids.size(); i++) {
String name = atNames.get(i);
String uid = atUids.get(i);
// 只有當被 @ 人的數組中包含自己的時候才會去變色
if (Objects.equals(uid, String.valueOf(AuthModel.get().getCurrentUid()))) {
Pattern pattern = Pattern.compile(Pattern.quote(name));
Matcher matcher = pattern.matcher(text.build().toString());
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
text.build().setSpan(new ForegroundColorSpan(getContext().getResources().getColor(R.color.color_FD85C9)),
start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
}
}
}
if (Objects.equals(chatRoomMessage.getFromAccount(), String.valueOf(AuthModel.get().getCurrentUid()))) {
tvContent.setOnLongClickListener(null);
} else {
tvContent.setOnLongClickListener(v -> {
if (onLongClickListener != null) {
onLongClickListener.onLongClick(v, chatRoomMessage.getFromAccount(), nickName);
}
return true;
});
}
MoonUtil.replaceEmoticons(getContext(), text.builder.toString(), text.builder, this);
tvContent.setText(text.build());
}
private void addCommonTag(ChatRoomMessage chatRoomMessage, @NonNull TextSpannableBuilder builder, TextView tvContent) {
ChatRoomMessageExtension extension = chatRoomMessage.getChatRoomMessageExtension();
String userLevel = NobleUtil.getLevel(UserLevelResourceType.EXPER_URL, chatRoomMessage);
boolean isOfficial = NobleUtil.getIsOfficial(UserInfo.IS_OFFICIAL, chatRoomMessage);
String vipIcon = NobleUtil.getResource(UserInfo.VIP_ICON, chatRoomMessage);
builder.append(vipIcon, expLevelHeight)
.append(isOfficial ? ResourcesCompat.getDrawable(getResources(),
R.mipmap.ic_user_official_13dp, null) : null,
badgeWidth, badgeHeight)
.append(getNewUserDrawable(chatRoomMessage), badgeWidth, badgeHeight)
.append(AvRoomDataManager.get().isSuperAdmin(chatRoomMessage.getFromAccount()) ? ResourcesCompat.getDrawable(getResources(),
R.drawable.ic_room_super_admin, null) : null,
SizeUtils.dp2px(tvContent.getContext(), 23), expLevelHeight);
// 官方主播認證
String tvOfficialMask = NobleUtil.getLevel(UserInfo.OAC_NAME, chatRoomMessage).trim();
String ivOfficialMask = NobleUtil.getLevel(UserInfo.OAC_ICON, chatRoomMessage);
if (!TextUtils.isEmpty(tvOfficialMask) && !TextUtils.isEmpty(ivOfficialMask) && extension != null) { // extension != null 表示自己
builder.appendBgAndContent(ivOfficialMask, tvOfficialMask);
} else if (!TextUtils.isEmpty(ivOfficialMask)) {
builder.append(ivOfficialMask, SizeUtils.dp2px(tvContent.getContext(), 62), expLevelHeight);
}
//等級
builder.append(userLevel, expLevelHeight);
//銘牌
String tvNamePlate = NobleUtil.getNamePlate(UserInfo.NAMEPLATE_WORD, chatRoomMessage).trim();
String ivNamePlate = NobleUtil.getNamePlate(UserInfo.NAMEPLATE_PIC, chatRoomMessage);
if (!TextUtils.isEmpty(tvNamePlate) && !TextUtils.isEmpty(ivNamePlate)) { // extension != null 表示自己
builder.appendBgAndContent(ivNamePlate, tvNamePlate);
} else if (!TextUtils.isEmpty(ivNamePlate)) {
builder.append(ivNamePlate, expLevelHeight);
}
}
private void setHeadlineMsg(ChatRoomMessage chatRoomMessage, TextView tvContent, CustomAttachment attachment) {
HeadlineChangedAttachment headlineAttachment = (HeadlineChangedAttachment) attachment;
SpannableTextBuilder builder = new SpannableTextBuilder(tvContent);
if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED_SUB) {
HeadlineBean data = headlineAttachment.getHeadlineData();
String nick = null;
if (data != null) {
nick = data.getNick();
}
if (nick == null) {
nick = "";
}
builder.appendText(String.format(ResUtil.getString(R.string.headline_message_format), nick), null, null, null, null, null, null);
builder.setTextStyle(nick, ContextCompat.getColor(getContext(), R.color.color_DE3446), null, null, null, null, null);
}
tvContent.setText(builder.build());
tvContent.setTextSize(11);
setNullBackground(tvContent);
}
/**
* {badge}xxx來了
*
* @param chatRoomMessage -
* @param tvContent -
*/
private void setMsgNotification(ChatRoomMessage chatRoomMessage, TextView tvContent, int position) {
int fromType = 0;
String fromNick = "";
String fromUid = "";
Map<String, Object> remoteExtension = chatRoomMessage.getRemoteExtension();
if (remoteExtension != null) {
fromType = (int) remoteExtension.get("fromType");
fromNick = (String) remoteExtension.get("fromNick");
fromUid = (String) remoteExtension.get("fromUid");
}
ChatRoomNotificationAttachment attachment = (ChatRoomNotificationAttachment) chatRoomMessage.getAttachment();
String senderNick = "";
List<String> nicks = attachment.getTargetNicks();
if (nicks != null && nicks.size() > 0)
senderNick = RegexUtil.getPrintableString(attachment.getTargetNicks().get(0));
if (attachment.getType() != NotificationType.ChatRoomMemberIn) return;
// 座駕
String carName = NobleUtil.getCarName(CarInfo.CAR_NAME, chatRoomMessage);
carName = TextUtils.isEmpty(carName) ? "" : "\"" + carName + "\"";
TextSpannableBuilder text = new TextSpannableBuilder(tvContent);
addCommonTag(chatRoomMessage, text, tvContent);
text.append(senderNick, new ForegroundColorSpan(roomTipColor),
new OriginalDrawStatusClickSpan() {
@Override
public void onClick(@NonNull View view) {
if (clickConsumer != null) {
Single.just(chatRoomMessage.getFromAccount())
.doOnSuccess(clickConsumer).subscribe();
}
}
});
text.append(TextUtils.isEmpty(carName) ? "" : ResUtil.getString(R.string.avroom_widget_messageview_0150), new ForegroundColorSpan(greyColor))
.append(carName, new ForegroundColorSpan(roomTipColor));
String enterText = ResUtil.getString(R.string.avroom_widget_messageview_0151);
if (fromType == AVRoomActivity.FROM_TYPE_RECOMMEND) {
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0152);
}
if (fromType == AVRoomActivity.FROM_TYPE_USER || fromType == AVRoomActivity.FROM_TYPE_HELLO) {
String finalFromUid = fromUid;
text.append(ResUtil.getString(R.string.avroom_widget_messageview_0153), new ForegroundColorSpan(whiteColor))
.append(fromNick, new ForegroundColorSpan(roomTipColor),
new OriginalDrawStatusClickSpan() {
@Override
public void onClick(@NonNull View view) {
if (clickConsumer != null) {
Single.just(finalFromUid).doOnSuccess(clickConsumer).subscribe();
}
}
});
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0154);
}
if (fromType == AVRoomActivity.FROM_TYPE_GAME_RECOMMEND) {
String finalFromUid = fromUid;
text.append(ResUtil.getString(R.string.avroom_widget_messageview_0155), new ForegroundColorSpan(whiteColor))
.append(fromNick, new ForegroundColorSpan(roomTipColor),
new OriginalDrawStatusClickSpan() {
@Override
public void onClick(@NonNull View view) {
if (clickConsumer != null) {
Single.just(finalFromUid).doOnSuccess(clickConsumer).subscribe();
}
}
});
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0156);
}
text.append(enterText, new ForegroundColorSpan(whiteColor));
tvContent.setText(text.build());
tvContent.setOnClickListener(null);
tvContent.setMovementMethod(new LinkMovementMethod());
}
@Nullable
private Drawable getNewUserDrawable(ChatRoomMessage chatRoomMessage) {
boolean newUser = NobleUtil.getIsNewUser(UserInfo.IS_NEW_USER, chatRoomMessage);
boolean isHelloUser = NobleUtil.getIsNewUser(UserInfo.IS_FROM_SAY_HELLO_CHANNEL, chatRoomMessage);
if (newUser) {
return ResourcesCompat.getDrawable(getResources(),
isHelloUser ? R.drawable.ic_new_user_hello : R.drawable.ic_new_user,
null);
}
return null;
}
@SuppressLint("CheckResult")
@Override
public void onClick(View v) {
String account = "";
ChatRoomMessage chatRoomMessage = (ChatRoomMessage) v.getTag();
if (chatRoomMessage.getMsgType() != MsgTypeEnum.tip) {
if (chatRoomMessage.getMsgType() == MsgTypeEnum.text) {
account = chatRoomMessage.getFromAccount();
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.notification) {
account = chatRoomMessage.getFromAccount();
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment attachment = (CustomAttachment) chatRoomMessage.getAttachment();
if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_ROOM_TIP) {
account = ((RoomTipAttachment) attachment).getUid() + "";
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_BOX) {
account = String.valueOf(((RoomBoxPrizeAttachment) attachment).getUid());
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_QUEUE) {
long handleUid = ((RoomQueueMsgAttachment) attachment).handleUid;
if (handleUid > 0) {
account = ((RoomQueueMsgAttachment) attachment).handleUid + "";
} else {
//ios沒用handleUid導致iOS發的自定義消息拿不到uid
account = chatRoomMessage.getFromAccount();
}
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_MONSTER_HUNTING) {
switch (attachment.getSecond()) {
case CustomAttachment.CUSTOM_MSG_SUB_TYPE_MONSTER_HUNTING:
MonsterDataBean dataBean = ((MonsterStatusAttachment) attachment).getDataBean();
RoomInfo mCurrentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (!Objects.equals(mCurrentRoomInfo.getUid(), dataBean.getAppearRoomUid())) {
AVRoomActivity.start(getContext(), dataBean.getAppearRoomUid());
} else {
SingleToastUtil.showToast("你已經在怪獸房間內");
}
break;
case CustomAttachment.CUSTOM_NOTI_SUB_GAME_RESULT:
MonsterHuntingResult result = ((MonsterHuntingResultAttachment) attachment).getResult();
UIHelper.showMonsterResult(getContext(), String.valueOf(result.getMonster().getMonsterId()));
break;
}
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MESS_HEAD_ROOM_PK) {
if (attachment.getSecond() == CustomAttachment.CUSTOM_MESS_SUB_ROOM_PK_RESULT) {
RoomTeamPKResultDialog pkResultDialog = new RoomTeamPKResultDialog(getContext(), ((RoomPkAttachment) attachment).getRoomPkData());
pkResultDialog.show();
}
} else if (attachment instanceof RoomFollowOwnerAttachment2 && !AvRoomDataManager.get().isRoomFans) {
CollectionRoomModel.get().followRoom("1", ((RoomFollowOwnerAttachment2) attachment).getOwnerUid())
.subscribe(s -> {
AvRoomDataManager.get().isRoomFans = true;
SingleToastUtil.showToast("收藏成功!");
EventBus.getDefault().post(new FollowRoomEvent());
PraiseModel.get().setFollowRoomSuccessRoomTip(JavaUtil.str2long(chatRoomMessage.getFromAccount()));
});
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MESS_TAROT) {
if (attachment instanceof TarotAttachment) {
account = ((TarotAttachment) attachment).getTarotMsgBean().getUid() + "";
}
}
}
if (TextUtils.isEmpty(account)) return;
if (clickConsumer != null) {
Single.just(account).subscribe(clickConsumer);
}
} else {
String content = chatRoomMessage.getContent();
if (!TextUtils.isEmpty(content) && content.equals(ResUtil.getString(R.string.yizhuan_xchat_android_constants_xchatconstants_08)))
if (onClick != null) {
onClick.onShowRoomIntroduction();
}
}
}
@Override
public ImageSpan invoke(Drawable drawable) {
return new CustomImageSpan(drawable);
}
class MessageViewHolder extends RecyclerView.ViewHolder {
TextView tvContent;
public MessageViewHolder(View itemView) {
super(itemView);
tvContent = itemView.findViewById(R.id.tv_content);
}
}
}
}

View File

@@ -1,111 +0,0 @@
package com.chwl.app.avroom.public_chat
import android.content.Context
import android.util.AttributeSet
import com.chwl.app.R
import com.chwl.app.public_chat.core.ChatRoomClient
import com.chwl.app.public_chat.core.ChatRoomClientManager
import com.chwl.core.im.custom.bean.HeadlineChangedAttachment
import com.chwl.core.support.room.FrameLayoutRoomWidget
import com.chwl.core.support.room.RoomView
import com.chwl.library.utils.SingleToastUtil
import com.netease.nim.uikit.api.model.NimException
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum
class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
private val messageView: PublicChatMessageView = PublicChatMessageView(context)
private var chatRoomClient: ChatRoomClient? = 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)
init {
addView(messageView, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
}
override fun onStart(roomView: RoomView) {
super.onStart(roomView)
chatRoomClient = ChatRoomClientManager.getPublicChatClient()
if (chatRoomClient == null) {
SingleToastUtil.showToast(R.string.public_chat_not_found)
}
chatRoomClient?.let {
initChatRoom(it)
}
}
private fun onReceiveMessage(message: ChatRoomMessage) {
if (!filterMessageForMessageList(message)) {
messageView.addMessages(message)
}
}
private fun initChatRoom(chatRoomClient: ChatRoomClient) {
getCompositeDisposable().add(
chatRoomClient.enterChatRoom()
.subscribe({ requestHistory(chatRoomClient) },
{
if (it is NimException) {
SingleToastUtil.showToast(context.getString(R.string.avroom_fragment_homepartyroomfragment_011) + "(${it.code})")
} else {
SingleToastUtil.showToast(R.string.avroom_fragment_homepartyroomfragment_011)
}
})
)
getCompositeDisposable().add(chatRoomClient.messageObservable.subscribe {
it.forEach { message ->
onReceiveMessage(message)
}
})
}
private fun requestHistory(chatRoomClient: ChatRoomClient) {
val typeEnums = arrayOf(MsgTypeEnum.text, MsgTypeEnum.image)
getCompositeDisposable().add(
chatRoomClient.requestRemoteMessageType(
0,
50,
QueryDirectionEnum.QUERY_OLD,
typeEnums
).subscribe({
messageView.addHistoryMessages(it.reversed())
}, {
it.printStackTrace()
})
)
}
private fun filterMessageForMessageList(message: ChatRoomMessage): Boolean {
if (message.msgType == MsgTypeEnum.custom && message.attachment is HeadlineChangedAttachment) {
val data = (message.attachment as HeadlineChangedAttachment).headlineData
if (data == null || !data.isValid()) {
return true
}
}
return false
}
fun getMessageView() = messageView
override fun onStop() {
super.onStop()
chatRoomClient = null
}
}

View File

@@ -3,6 +3,7 @@ package com.chwl.app.avroom.room_album
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent
import android.os.Build
@@ -11,6 +12,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
@@ -25,12 +29,17 @@ import com.chwl.app.ui.utils.ImageLoadUtilsV2
import com.chwl.app.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
import com.chwl.core.Constants
import com.chwl.core.gift.bean.GiftInfo
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.MyUriUtils
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.photo.PhotoProvider.photoProvider
import com.chwl.library.common.util.PhotoCompressUtil.compress
import com.chwl.library.common.util.PhotoCompressUtil.getCompressCachePath
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
@@ -45,7 +54,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
private var unlockedGift: GiftInfo? = null
private var compressJob: Job? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
val dialogManager by lazy {
DialogManager(context)
}
@@ -55,6 +64,17 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.ErbanBottomSheetDialog)
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(requireContext())) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
val file = MyUriUtils.copyFile(requireContext(),uri)
if (file != null) {
compressPhotos(mutableListOf(file.path))
}
}
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -194,7 +214,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
return@setOnClickListener
}
dialogManager.showProgressDialog(context)
// dialogManager.showProgressDialog(context)
viewModel.upload(
list,
type,
@@ -204,7 +224,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
viewModel.uploadLiveData.observe(this) {
it?.getContentIfNotHandled()?.let { success ->
dialogManager.hideProgressDialog()
// dialogManager.hideProgressDialog()
if (success) {
dismiss()
@@ -219,28 +239,37 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
requireContext(),
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
100,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
7 - photoAdapter.data.size,
true,
200,
true
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(requireActivity(),object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(requireContext(),Manifest.permission.READ_EXTERNAL_STORAGE)) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
100,
Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
7 - photoAdapter.data.size,
true,
200,
true
)
}
}
}
@Deprecated("Deprecated in Java")

View File

@@ -22,6 +22,7 @@ import androidx.annotation.Nullable;
import com.chwl.app.avroom.activity.RoomTypeSwitchActivity;
import com.chwl.core.utils.extension.StringExtensionKt;
import com.chwl.library.utils.SizeUtils;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nimlib.sdk.msg.model.RecentContact;
@@ -73,12 +74,10 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
private ImageView iconMicQueue;
private ImageView iconRoomMsg;
private ImageView iconRoomBaiShunGame;
private ImageView pkGameView;
@Nullable
private PopupWindow msgTipPopupWindow;
private PopupWindow micSetPopupWindow;
@NonNull
private final Runnable msgRunnable = this::dismissMsgPopupWindow;
@@ -108,12 +107,10 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
remoteMute = findViewById(R.id.icon_room_open_remote_mic);
faceLayout = findViewById(R.id.room_face_layout);
micLayout = findViewById(R.id.room_mic_layout);
iconRoomBaiShunGame = findViewById(R.id.icon_room_baishun_game);
iconMicQueue = (ImageView) findViewById(R.id.icon_mic_queue);
iconRoomMsg = findViewById(R.id.iv_room_message);
pkGameView = findViewById(R.id.icon_room_PK_game);
openMic.setOnClickListener(this);
sendMsgInput.setOnClickListener(this);
sendFace.setOnClickListener(this);
@@ -122,8 +119,6 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
sendMagic.setOnClickListener(this);
iconMicQueue.setOnClickListener(this);
iconRoomMsg.setOnClickListener(this);
pkGameView.setOnClickListener(this);
iconRoomBaiShunGame.setOnClickListener(this);
setMicBtnEnable(false);
setMicBtnOpen(false);
@@ -247,9 +242,6 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
}
}
public void setBaiShunBtnOpen(boolean isOpen) {
iconRoomBaiShunGame.setVisibility(isOpen ? VISIBLE : GONE);
}
public void notifyStateChanged() {
setMagicBtnEnable(true);
@@ -261,15 +253,20 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
}
public void updateGameEntrance() {
if (AvRoomDataManager.get().isManager() || SuperAdminUtil.isSuperAdmin()) {
if (!AvRoomDataManager.get().isCpRoom()) {
pkGameView.setVisibility(VISIBLE);
iconRoomBaiShunGame.setVisibility(VISIBLE);
}
} else {
pkGameView.setVisibility(GONE);
iconRoomBaiShunGame.setVisibility(GONE);
}
// game btn pk按钮游戏按钮 显示控制
// if (AvRoomDataManager.get().isManager() || SuperAdminUtil.isSuperAdmin()) {
// if (!AvRoomDataManager.get().isCpRoom()) {
// pkGameView.setVisibility(VISIBLE);
// iconRoomBaiShunGame.setVisibility(VISIBLE);
// }
// } else {
// pkGameView.setVisibility(GONE);
// iconRoomBaiShunGame.setVisibility(GONE);
// }
// if (AvRoomDataManager.get().isSingleRoom() || AvRoomDataManager.get().isDatingMode()) {
// pkGameView.setVisibility(GONE);
// }
}
public void showHomePartyDownMicBottom() {
@@ -323,6 +320,7 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
if (wrapper != null) {
wrapper.onOpenMicBtnClick();
}
// showMicSetDialog(openMic);
break;
case R.id.tv_room_send_msg_input:
@@ -371,16 +369,16 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
wrapper.onRoomMessageClick();
}
break;
case R.id.icon_room_PK_game:
if (wrapper != null) {
wrapper.onRoomGameplayClick(true);
}
break;
case R.id.icon_room_baishun_game:
if (wrapper != null) {
wrapper.onRoomGameplayClick(false);
}
break;
// case R.id.icon_room_PK_game:
// if (wrapper != null) {
// wrapper.onRoomGameplayClick(true);
// }
// break;
// case R.id.icon_room_baishun_game:
// if (wrapper != null) {
// wrapper.onRoomGameplayClick(false);
// }
// break;
default:
break;
}
@@ -462,4 +460,40 @@ public class BottomView extends LinearLayout implements View.OnClickListener {
parent.postDelayed(msgRunnable, 3000);
}
private void showMicSetDialog(View parent){
//todo do 关麦开麦
View contentView;
if (micSetPopupWindow == null) {
contentView = LayoutInflater.from(getContext()).inflate(R.layout.popup_mic_set, null);
micSetPopupWindow = new PopupWindow(contentView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
micSetPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
// micSetPopupWindow.setAnimationStyle(R.style.style_anim_mic_set);
} else {
contentView = micSetPopupWindow.getContentView();
}
ImageView micOff = contentView.findViewById(R.id.micOff);
ImageView micMusic = contentView.findViewById(R.id.micMusic);
ImageView micOn = contentView.findViewById(R.id.micOn);
micOff.setOnClickListener(v -> {
micSetPopupWindow.dismiss();
});
micMusic.setOnClickListener(v -> {
micSetPopupWindow.dismiss();
});
micOn.setOnClickListener(v -> {
micSetPopupWindow.dismiss();
});
int[] vLoc = new int[2];
parent.getLocationInWindow(vLoc);
try {
micSetPopupWindow.showAsDropDown(parent,0, -ScreenUtil.dip2px(180),Gravity.CENTER_HORIZONTAL);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -23,6 +23,8 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.chwl.core.utils.ComboUtil;
import com.chwl.core.auth.AuthModel;
import com.example.lib_utils.UiUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
@@ -89,6 +91,7 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
private int mScreenWidth;
private int mScreenHeight;
private Keyframe[] keyScale;
private Keyframe[] keyScaleCombo;
private Keyframe[] keyTrans;
private SvgaObjectPool mMagicViewPool;
@@ -126,6 +129,13 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
keyScale[4] = (Keyframe.ofFloat(0.5f, 2f));
keyScale[5] = (Keyframe.ofFloat(0.8f, 2f));
keyScale[6] = (Keyframe.ofFloat(1f, 1f));
keyScaleCombo = new Keyframe[4];
keyScaleCombo[0] = (Keyframe.ofFloat(0f, 0.25f));
keyScaleCombo[1] = (Keyframe.ofFloat(0.25f, 0.5f));
keyScaleCombo[2] = (Keyframe.ofFloat(0.5f, 0.75f));
keyScaleCombo[3] = (Keyframe.ofFloat(1f, 1f));
keyTrans = new Keyframe[3];
keyTrans[0] = (Keyframe.ofFloat(0f, 0));
keyTrans[1] = (Keyframe.ofFloat(0.2f, 0));
@@ -255,6 +265,14 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
}
Point senderPoint = micViewPoint.get(senderPosition);
Point receivePoint = micViewPoint.get(receivePosition);
// 连击 特殊动画
if (giftReceiveInfo.getUid() == AuthModel.get().getCurrentUid()){
if (ComboUtil.INSTANCE.isChangePoint()) {
senderPoint = ComboUtil.INSTANCE.getPoint();
}
}
//设置动画结束的位置
if (receivePoint == null || isGameRoomMoreThan6People()) { //这种情况就是接收者已经不在麦上
//礼物送到中间的位置
@@ -627,6 +645,7 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
return;
}
GiftInfo giftInfo = giftReceiveInfo.getGift();
giftInfo.uid = giftReceiveInfo.getUid();
if (giftInfo == null) {
return;
}
@@ -668,8 +687,24 @@ public class GiftV2View extends FrameLayout implements GiftEffectView.GiftEffect
PropertyValuesHolder p1 = PropertyValuesHolder.ofKeyframe("translationY", keyTrans[0], keyTrans[1], keyTrans[2], keyTransY3, keyTransY4, keyTransY5);
PropertyValuesHolder p2 = PropertyValuesHolder.ofKeyframe("scaleX", keyScale);
PropertyValuesHolder p3 = PropertyValuesHolder.ofKeyframe("scaleY", keyScale);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, p2, p3, p1, p0);
objectAnimator.setDuration(4000);
PropertyValuesHolder p0c = PropertyValuesHolder.ofKeyframe("translationX", keyTrans[0], keyTransX5);
PropertyValuesHolder p1c = PropertyValuesHolder.ofKeyframe("translationY", keyTrans[0], keyTransY5);
PropertyValuesHolder p2c = PropertyValuesHolder.ofKeyframe("scaleX", keyScaleCombo);
PropertyValuesHolder p3c = PropertyValuesHolder.ofKeyframe("scaleY", keyScaleCombo);
long time;
ObjectAnimator objectAnimator;
// 连击 特殊动画
if (ComboUtil.INSTANCE.isChangePoint() && giftInfo.uid == AuthModel.get().getCurrentUid()){
objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, p2c, p3c, p1c, p0c);
time = 600;
}else {
objectAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, p2, p3, p1, p0);
time = 2000;
}
objectAnimator.setDuration(time);
objectAnimator.start();
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override

View File

@@ -1442,6 +1442,7 @@ class RoomEffectView @JvmOverloads constructor(
enterRoomEffects = remoteExtension[UserInfo.ENTER_ROOM_EFFECTS] as String?
}
val wrapNick = "" + targetNicks[0].subAndReplaceDot(7) + "" + enterText
if (!TextUtils.isEmpty(enterRoomEffects)) {
playMemberInAnimByUrl(wrapNick, enterRoomEffects)
} else {
@@ -1495,7 +1496,11 @@ class RoomEffectView @JvmOverloads constructor(
private fun playMemberInAnim(text: String, svgaVideoEntity: SVGAVideoEntity) {
binding.roomMenberInSvga.visibility = VISIBLE
binding.roomMenberInSvga.loops = 1
if (svgaVideoEntity.frames == 1) {
binding.roomMenberInSvga.loops = 50
} else {
binding.roomMenberInSvga.loops = 1
}
binding.roomMenberInSvga.clearsAfterStop = true
val dynamicEntity = SVGADynamicEntity()
val textPaint = TextPaint()

View File

@@ -0,0 +1,118 @@
package com.chwl.app.avroom.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.customview.widget.ViewDragHelper;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
/**
* 侧滑FrameLayout
* 子View左滑删除右滑弹起后复位
*/
public class VDHLayout extends FrameLayout {
private final ViewDragHelper mDragHelper;
private final Point mAutoBackOriginPos = new Point();
private OnViewGoneListener listener;
public VDHLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
mAutoBackOriginPos.x = child.getLeft();
mAutoBackOriginPos.y = child.getTop();
return true;
}
/**
* view的left
*/
@Override
public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
return left;
}
/**
* view的top
*/
@Override
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
return child.getTop();
}
//手指释放的时候回调
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
//mAutoBackView手指释放时可以自动回去
if (releasedChild.getLeft() < 0 && ((Math.abs(releasedChild.getLeft()) >= releasedChild.getMeasuredWidth() * 0.2))) {
releasedChild.setEnabled(false);
releasedChild.animate()
.setDuration(100L)
.translationX(-ScreenUtil.getDisplayWidth())
.alpha(0F)
.withEndAction(() -> {
releasedChild.setVisibility(GONE);
if(listener != null){
listener.onViewGone();
}
}).start();
} else {
mDragHelper.settleCapturedViewAt(mAutoBackOriginPos.x, mAutoBackOriginPos.y);
ViewCompat.postInvalidateOnAnimation(VDHLayout.this);
}
}
//在边界拖动时回调
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
}
@Override
public int getViewHorizontalDragRange(@NonNull View child) {
return child.getMeasuredWidth();
}
});
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return mDragHelper.shouldInterceptTouchEvent(event);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
invalidate();
}
}
public void setListener(OnViewGoneListener listener) {
this.listener = listener;
}
public interface OnViewGoneListener{
void onViewGone();
}
}

View File

@@ -28,6 +28,7 @@ import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
@@ -46,6 +47,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chwl.app.notify.GlobalNotifyManager;
import com.chwl.library.language.LanguageHelper;
import com.example.lib_utils.UiUtils;
import com.google.gson.Gson;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMSDK;
@@ -236,6 +238,21 @@ public abstract class BaseActivity extends RxAppCompatActivity
}
}
public void initVipCenterBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
mTitleBar.setTitle(title);
mTitleBar.setImmersive(false);
mTitleBar.setTitleColor(getResources().getColor(R.color.color_FFE3AF));
mTitleBar.setLeftImageResource(R.drawable.vip_center_back_button);
mTitleBar.setBackgroundResource(R.color.transparent);
mTitleBar.setLeftClickListener(v -> onLeftClickListener());
if(UiUtils.INSTANCE.isRtl(context)){
mTitleBar.leftTextViewUpdateScaleXForRTL();
}
}
}
public void initWhiteTitleBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
@@ -248,6 +265,18 @@ public abstract class BaseActivity extends RxAppCompatActivity
}
}
public void initBlackTitleBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
mTitleBar.setTitle(title);
mTitleBar.setImmersive(false);
mTitleBar.setTitleColor(getResources().getColor(R.color.white));
mTitleBar.setLeftImageResource(R.drawable.icon_user_back);
mTitleBar.setBackgroundResource(R.color.transparent);
mTitleBar.setLeftClickListener(v -> onLeftClickListener());
}
}
public void initTitleBar(String title, TitleBar.Action action) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {

View File

@@ -4,6 +4,8 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -18,6 +20,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.chwl.app.application.App;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.trello.rxlifecycle3.components.support.RxFragment;
import com.chwl.app.R;
@@ -585,17 +588,33 @@ public abstract class BaseFragment extends RxFragment implements KeyEvent.Callba
}
protected DialogManager getDialogManager() {
FragmentActivity activity = getActivity();
if (activity instanceof BaseMvpActivity) {
return ((BaseMvpActivity) activity).getDialogManager();
} else if (activity instanceof BaseActivity) {
return ((BaseActivity) activity).getDialogManager();
} else {
if (dialogManager == null) {
dialogManager = new DialogManager(activity);
try {
if (activity instanceof BaseMvpActivity) {
return ((BaseMvpActivity) activity).getDialogManager();
} else if (activity instanceof BaseActivity) {
return ((BaseActivity) activity).getDialogManager();
}
return dialogManager;
} catch (Exception e) {
e.printStackTrace();
}
Activity topActivity = App.gStack.getTopActivity();
if (dialogManager == null && topActivity != null) {
dialogManager = new DialogManager(topActivity);
}
FragmentActivity fragmentActivity = requireActivity();
if (dialogManager == null && fragmentActivity != null) {
dialogManager = new DialogManager(fragmentActivity);
}
if (dialogManager == null) {
dialogManager = new DialogManager(activity);
}
return dialogManager;
}
public BaseActivity getBaseActivity() {

View File

@@ -63,6 +63,10 @@ public class TitleBar extends ViewGroup implements View.OnClickListener {
private LayoutInflater mInflater;
public void leftTextViewUpdateScaleXForRTL() {
mLeftText.setScaleX(-1);
}
public TitleBar(Context context) {
super(context);
init(context);

View File

@@ -1,279 +0,0 @@
package com.chwl.app.common.dialog
import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.view.Gravity
import android.view.Window
import android.view.WindowManager
import com.hjq.toast.ToastUtils
import com.chwl.app.R
import com.chwl.app.application.App
import com.chwl.app.databinding.PhotoDialogBinding
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.library.common.base.BaseDialogFragment
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.easypermisssion.EasyPermissions
import kotlinx.coroutines.Job
/**
* 该对话框的功能提供拍摄和选择图片
*/
class PhotoDialog : BaseDialogFragment<PhotoDialogBinding>(), EasyPermissions.PermissionCallbacks {
private var mOnResultCallBack: OnResultCallBack? = null
private var mJob: Job? = null
companion object {
private const val PERMISSION_CODE_CAMERA = 100
private const val REQUEST_CODE_CAMERA = 101
private const val PERMISSION_CODE_STORAGE_1 = 200
private const val REQUEST_CODE_STORAGE_1 = 201
private const val PERMISSION_CODE_STORAGE_2 = 202
private const val REQUEST_CODE_STORAGE_2 = 203
private const val REQUEST_CODE_OPEN_PHOTO_PROVIDER = 103
private const val REQUEST_CODE_OPEN_CAMERA_PROVIDER = 104
}
override fun initBefore(savedInstanceState: Bundle?) {
super.initBefore(savedInstanceState)
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
}
override fun setListener() {
binding?.tvTakePhoto?.setOnClickListener {
checkCameraPermission()
}
binding?.tvChoicePicture?.setOnClickListener {
checkStoragePermission1()
}
}
private fun initDialog() {
dialog?.window?.also {
it.decorView.setPadding(0, 0, 0, 0)
it.attributes = it.attributes.apply {
gravity = Gravity.BOTTOM
width = WindowManager.LayoutParams.MATCH_PARENT
}
it.setBackgroundDrawableResource(R.drawable.photo_dialog_bg)
}
}
override fun onStart() {
super.onStart()
initDialog()
}
private fun checkStoragePermission1() {
if (!EasyPermissions.hasPermissions(
App.gContext, if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE_1,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
PhotoProvider.photoProvider(this, resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER)
}
}
private fun checkCameraPermission() {
if (!EasyPermissions.hasPermissions(
App.gContext,
Manifest.permission.CAMERA
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_camera_rationale),
PERMISSION_CODE_CAMERA,
Manifest.permission.CAMERA
)
} else {
checkStoragePermission2()
}
}
private fun checkStoragePermission2() {
if (!EasyPermissions.hasPermissions(
App.gContext, if (Build.VERSION.SDK_INT >= 33)
Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE_2,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
PhotoProvider.photoCamera(this, REQUEST_CODE_OPEN_CAMERA_PROVIDER)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
if (requestCode == PERMISSION_CODE_CAMERA) {
checkCameraPermission()
} else if (requestCode == PERMISSION_CODE_STORAGE_1) {
checkStoragePermission1()
} else if (requestCode == PERMISSION_CODE_STORAGE_2) {
checkStoragePermission2()
}
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2 || requestCode == PERMISSION_CODE_CAMERA) {
val requestTip: String =
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2) {
getString(R.string.permission_storage_denied)
} else {
getString(R.string.permission_camera_denied)
}
val mPrivacyDialog = CommonTipDialog(context)
mPrivacyDialog.setTipMsg(requestTip)
mPrivacyDialog.setOkText(getString(R.string.room_perform_go_update))
mPrivacyDialog.setOnActionListener(
object : CommonTipDialog.OnActionListener {
override fun onOk() {
//同意跳到应用详情页面
val packageUri =
Uri.parse("package:${activity?.packageName}")
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
packageUri
)
if (requestCode == PERMISSION_CODE_STORAGE_1) {
startActivityForResult(
intent, REQUEST_CODE_STORAGE_1
)
} else if (requestCode == PERMISSION_CODE_STORAGE_2) {
startActivityForResult(
intent,
REQUEST_CODE_STORAGE_2
)
} else {
startActivityForResult(
intent, REQUEST_CODE_CAMERA
)
}
}
override fun onCancel() {
super.onCancel()
//取消跳到应用详情页面
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2) {
ToastUtils.show(getString(R.string.permission_storage_refused))
} else {
ToastUtils.show(getString(R.string.permission_camera_refused))
}
}
}
)
mPrivacyDialog.show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_STORAGE_1) {
checkStoragePermission1()
} else if (requestCode == REQUEST_CODE_STORAGE_2) {
checkStoragePermission2()
} else if (requestCode == REQUEST_CODE_CAMERA) {
checkCameraPermission()
} else
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CODE_OPEN_CAMERA_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { paths ->
val list = paths?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
val path = list[0]
if (!TextUtils.isEmpty(path)) {
mJob?.cancel()
mJob = PhotoCompressUtil.compress(
App.gContext,
path,
PhotoCompressUtil.getCompressCachePath(),
object : PhotoCompressCallback {
override fun onSuccess(compressedImg: String) {
mOnResultCallBack?.takePhotoCallBack(compressedImg)
}
override fun onFail(e: Throwable) {
mOnResultCallBack?.takePhotoCallBack(path)
}
})
} else {
mOnResultCallBack?.takePhotoCallBack(path)
}
}
}
REQUEST_CODE_OPEN_PHOTO_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { list ->
val paths = list?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
if (paths.isEmpty()) {
mOnResultCallBack?.choicePhotoCallBack(paths)
} else {
mJob?.cancel()
mJob = PhotoCompressUtil.compress(
App.gContext,
paths,
PhotoCompressUtil.getCompressCachePath(),
object : PhotosCompressCallback {
override fun onSuccess(compressedImgList: ArrayList<String>) {
mOnResultCallBack?.choicePhotoCallBack(compressedImgList)
}
override fun onFail(e: Throwable) {
mOnResultCallBack?.choicePhotoCallBack(paths)
}
})
}
}
}
}
dismissAllowingStateLoss()
}
}
fun setOnResultCallBack(onResultCallBack: OnResultCallBack) {
mOnResultCallBack = onResultCallBack
}
override fun onWillDestroy() {
mJob?.cancel()
super.onWillDestroy()
}
interface OnResultCallBack {
fun takePhotoCallBack(path: String?)
fun choicePhotoCallBack(paths: List<String>?)
}
}

View File

@@ -6,10 +6,13 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.chwl.app.BuildConfig;
import com.chwl.app.application.App;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.utils.LogUtils;
import com.chwl.library.common.util.CoreUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
/**
* Activity生命周期工具类
@@ -27,6 +30,9 @@ public class AppLifeCycleHelper implements Application.ActivityLifecycleCallback
@Override
public void onActivityStarted(@NonNull Activity activity) {
if (BuildConfig.DEBUG) {
LogUtils.d("当前Activity : "+ activity.getClass().getSimpleName());
}
if (++AppLifeCycleHelper.sActivityReferences == 1 && !AppLifeCycleHelper.sIsActivityChangingConfigurations) {
AppLifeCycleHelper.onForeground();

View File

@@ -0,0 +1,10 @@
package com.chwl.app.constants;
public @interface UserInfoConstants {
public @interface CpSet{
//1-cp头像是否展示2-cp动画
int cpAvatar = 1;
int cpAnim = 2;
}
}

View File

@@ -11,7 +11,15 @@ import com.chwl.app.databinding.ItemMyUserCardWearBinding;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.core.decoration.headwear.bean.HeadWearInfo;
import com.chwl.core.decoration.headwear.bean.UserCardWearInfo;
import com.chwl.library.download.DownloadException;
import com.chwl.library.download.DownloadManager;
import com.chwl.library.download.DownloadRequest;
import com.chwl.library.download.DownloadTask;
import com.chwl.library.download.FileDownloadListener;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.PathHelper;
import java.io.File;
/**
* Created by huangmeng1 on 2018/5/11.
@@ -27,7 +35,24 @@ public class MyUserCardWearAdapter extends BaseAdapter<UserCardWearInfo> {
protected void convert(@NonNull BindingViewHolder helper, UserCardWearInfo item) {
super.convert(helper, item);
ItemMyUserCardWearBinding binding = (ItemMyUserCardWearBinding) helper.getBinding();
ImageLoadUtils.loadImage(mContext, item.getPic(), binding.ivUserCardWear);
binding.ivUserCardWearMp4.setLoop(Integer.MAX_VALUE);
String filePath = PathHelper.INSTANCE.generateResourcesFilePath(item.getPic());
DownloadRequest request = DownloadRequest.Companion.build(item.getPic(), filePath, "gift_effect_download", null, 60000L);
DownloadManager.INSTANCE.download(request, new FileDownloadListener() {
@Override
public void onDownloadCompleted(@NonNull DownloadTask task) {
String path = task.getRequest().getPath();
binding.ivUserCardWearMp4.startPlay(new File(path));
}
@Override
public void onDownloadError(@NonNull DownloadException exception) {
ImageLoadUtils.loadImage(mContext, item.getPic(), binding.ivUserCardWear);
}
});
helper.addOnClickListener(R.id.tv_used);
if (item.getLabelType() == HeadWearInfo.LABEL_TYPE_NORMAL) {

View File

@@ -93,18 +93,18 @@ public class MyUserCardWearFragment extends BaseBindingFragment<FrgMyDecorationC
String cardId = headWearInfo.isUsed() ? null : headWearInfo.getCardId();
wearVm.userHeadWear(cardId)
.compose(bindUntilEvent(FragmentEvent.DESTROY))
.doOnError(throwable -> {
toast(throwable.getMessage());
})
.subscribe(s -> {
for (int i = 0; i < shopAdapter.getData().size(); i++) {
shopAdapter.getData().get(i).setUsed(Objects.equals(cardId,shopAdapter.getData().get(i).getCardId()));
}
shopAdapter.notifyDataSetChanged();
//更新用户信息
UserModel.get().updateCurrentUserInfo().subscribe();
});
.compose(bindUntilEvent(FragmentEvent.DESTROY))
.doOnError(throwable -> {
toast(throwable.getMessage());
})
.subscribe(s -> {
for (int i = 0; i < shopAdapter.getData().size(); i++) {
shopAdapter.getData().get(i).setUsed(Objects.equals(cardId,shopAdapter.getData().get(i).getCardId()));
}
shopAdapter.notifyDataSetChanged();
//更新用户信息
UserModel.get().updateCurrentUserInfo().subscribe();
});
}
}

View File

@@ -129,9 +129,9 @@ class ConvertDiamondActivity : BaseViewBindingActivity<ActivityConvertDiamondBin
}
binding.tvConvert.setOnClickListener { view ->
if (binding.edDiamond.text.toString().toLong() < it.minDiamonds) {
if (binding.edGold.text.toString().toLong() < it.minDiamonds) {
toast(getString(R.string.convert_diamonds_01).format(it.minDiamonds))
} else if (binding.edDiamond.text.toString().toLong() > it.maxDiamonds) {
} else if (binding.edGold.text.toString().toLong() > it.maxDiamonds) {
toast(getString(R.string.convert_diamonds_02).format(it.minDiamonds))
} else {
//去掉小数凑整:不管小数是多少,都进一

View File

@@ -13,8 +13,8 @@ class HomeMessageViewModel : BaseViewModel() {
safeLaunch(needLoading = false, onError = {
topPublicChatMessageLiveData.postValue(BeanResult.failed(it))
}) {
val value = PublicChatModel.getTopMessage()
topPublicChatMessageLiveData.postValue(BeanResult.success(value ?: emptyList()))
// val value = PublicChatModel.getTopMessage()
// topPublicChatMessageLiveData.postValue(BeanResult.success(value ?: emptyList()))
}
}

View File

@@ -21,8 +21,8 @@ public class HomeIndicatorAdapter extends CommonNavigatorAdapter {
private final Context mContext;
private final List<? extends CharSequence> mTitleList;
private int textSize = 21;
private float minScale = 0.857f;
private int textSize = 20;
private float minScale = 0.8f;
private boolean showIndicator = true;
private OnItemSelectListener mOnItemSelectListener;
@@ -39,8 +39,8 @@ public class HomeIndicatorAdapter extends CommonNavigatorAdapter {
@Override
public IPagerTitleView getTitleView(Context context, final int i) {
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_990C1D18));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_0C1D18));
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_313131));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_313131));
scaleTransitionPagerTitleView.setMinScale(minScale);
scaleTransitionPagerTitleView.setTextSize(textSize);
int padding = UIUtil.dip2px(context, 13);
@@ -62,7 +62,7 @@ public class HomeIndicatorAdapter extends CommonNavigatorAdapter {
indicator.setLineHeight(context.getResources().getDimensionPixelOffset(R.dimen.dp_4));
indicator.setRoundRadius(context.getResources().getDimensionPixelOffset(R.dimen.dp_2));
indicator.setLineWidth(context.getResources().getDimensionPixelOffset(R.dimen.dp_13));
indicator.setColors(context.getResources().getColor(R.color.color_002512));
indicator.setColors(context.getResources().getColor(R.color.color_e29030));
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// lp.bottomMargin = mBottomMargin;
indicator.setLayoutParams(lp);

View File

@@ -1,58 +0,0 @@
package com.chwl.app.home.adapter
import android.text.style.ImageSpan
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.loadAvatar
import com.chwl.core.public_chat_hall.bean.PublicChatMessageBean
import com.netease.nim.uikit.api.NimUIKit
import com.netease.nim.uikit.business.session.emoji.MoonUtil
class PublicChatLaneAdapter(private val data: MutableList<PublicChatMessageBean>) :
RecyclerView.Adapter<BaseViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
return BaseViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.public_chat_lane_item, null)
)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val item = getItem(position)
val textView = holder.getView<TextView>(R.id.tv_message)
MoonUtil.identifyFaceExpressionSmall(
NimUIKit.getContext(),
textView,
item?.content ?: "",
ImageSpan.ALIGN_CENTER
)
val avatarView = holder.getView<ImageView>(R.id.iv_avatar)
avatarView.loadAvatar(item?.fromAvatar ?: "")
}
override fun getItemCount(): Int {
return Int.MAX_VALUE
}
fun getRealItemCount(): Int {
return data.size
}
fun setNewData(list: List<PublicChatMessageBean>) {
data.clear()
data.addAll(list)
notifyDataSetChanged()
}
private fun getItem(position: Int): PublicChatMessageBean? {
if (data.isEmpty()) {
return null
}
return data[position % data.size]
}
}

View File

@@ -19,7 +19,6 @@ import com.chwl.app.avroom.adapter.CommonVPAdapter
import com.chwl.app.base.BaseViewBindingFragment
import com.chwl.app.databinding.FragmentContactListBinding
import com.chwl.app.home.HomeMessageViewModel
import com.chwl.app.home.adapter.PublicChatLaneAdapter
import com.chwl.app.home.helper.AutoScrollTask
import com.chwl.app.public_chat.ui.message.PublicChatRoomMessageActivity
import com.chwl.app.support.FragmentVisibleStateHelper
@@ -42,7 +41,6 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
MainTabContentView {
private val viewModel: HomeMessageViewModel by activityViewModels()
private val publicChatAdapter = PublicChatLaneAdapter(ArrayList())
private val stateHelper = FragmentVisibleStateHelper(this).start {
onVisibleChanged(it)
@@ -64,7 +62,6 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
} else {
2
}
binding.recyclerViewPublicChat.scrollBy(x, 0)
}
override fun init() {
@@ -86,6 +83,8 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
tagList.add(getString(R.string.layout_fragment_contact_list_04))
val commonNavigator = CommonNavigator(context)
commonNavigator.setTitleWrapContent(false)
commonNavigator.rightPadding = 20
commonNavigator.leftPadding = 20
val magicIndicatorAdapter = ContactsIndicatorAdapter(context, tagList)
magicIndicatorAdapter.setOnItemSelectListener { position: Int, view: TextView? ->
binding.viewPager.currentItem = position
@@ -159,37 +158,20 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
return true
}
})
binding.layoutPublicChat.singleClick {
PublicChatRoomMessageActivity.start(requireContext())
}
binding.recyclerViewPublicChat.setOnTouchListener { v, event ->
gestureDetectorCompat.onTouchEvent(event)
}
binding.recyclerViewPublicChat.layoutManager =
StaggeredGridLayoutManager(2, RecyclerView.HORIZONTAL)
binding.recyclerViewPublicChat.adapter = publicChatAdapter
viewModel.topPublicChatMessageLiveData.observe(this) {
val newList = it.data
if (it.isSuccess && !newList.isNullOrEmpty()) {
publicChatAdapter.setNewData(newList)
switchPublicChatMessageScrollState(stateHelper.isVisible)
}
binding.recyclerViewPublicChat.isVisible = (publicChatAdapter.getRealItemCount() > 0)
}
}
private fun switchPublicChatMessageScrollState(isVisible: Boolean) {
if (isVisible && publicChatAdapter.getRealItemCount() > 0) {
autoScrollTask.start()
} else {
autoScrollTask.stop()
}
// if (isVisible && publicChatAdapter.getRealItemCount() > 0) {
// autoScrollTask.start()
// } else {
// autoScrollTask.stop()
// }
}
private fun onVisibleChanged(isVisible: Boolean) {
switchPublicChatMessageScrollState(isVisible)
if (isVisible) {
viewModel.getTopPublicChatMessageIfNull()
}
// switchPublicChatMessageScrollState(isVisible)
// if (isVisible) {
// viewModel.getTopPublicChatMessageIfNull()
// }
}
}

View File

@@ -56,7 +56,7 @@ class HomeFragment : BaseViewBindingFragment<FragmentHomeBinding>(), View.OnClic
titleList.add(getString(R.string.main_tab_recommend))
titleList.add(getString(R.string.main_me))
val commonNavigator = CommonNavigator(context)
commonNavigator.setTitleWrapContent(false)
commonNavigator.setTitleWrapContent(true)
val magicIndicatorAdapter = HomeIndicatorAdapter(context, titleList)
magicIndicatorAdapter.setOnItemSelectListener { position: Int, view: TextView? ->
binding.viewPager.currentItem = position

View File

@@ -16,6 +16,8 @@ import com.chwl.app.UIHelper
import com.chwl.app.application.IReportConstants
import com.chwl.app.application.ReportManager
import com.chwl.app.avroom.activity.AVRoomActivity
import com.chwl.app.avroom.dialog.RoomNotifyCpBindDialog
import com.chwl.app.avroom.dialog.RoomNotifyLevelUpDialog
import com.chwl.app.base.BaseActivity
import com.chwl.app.base.BaseFragment
import com.chwl.app.databinding.FragmentMeBinding
@@ -35,9 +37,10 @@ import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.ui.wallet.WalletActivity
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.view.GenderAgeTextView
import com.chwl.app.vip.VipMainActivity
import com.chwl.app.vip.VipCenterActivity
import com.chwl.app.vip.VipViewModel
import com.chwl.core.auth.AuthModel
import com.chwl.core.gift.bean.CpMsgBean
import com.chwl.core.initial.InitialModel
import com.chwl.core.level.UserLevelVo
import com.chwl.core.manager.IMNetEaseManager
@@ -318,11 +321,12 @@ class MeFragment : BaseFragment(), View.OnClickListener {
override fun onClick(v: View) {
when (v.id) {
R.id.iv_user_head, R.id.rl_user_info ->
R.id.iv_user_head, R.id.rl_user_info ->{
mUserInfo?.let { UIHelper.showUserInfoAct(mContext, it.uid) }
R.id.iv_edit ->
mUserInfo?.let { UIHelper.showUserInfoModifyAct(mContext, it.uid) }
}
//
// R.id.iv_edit ->
// mUserInfo?.let { UIHelper.showUserInfoModifyAct(mContext, it.uid) }
R.id.ll_user_attentions -> startActivity(
Intent(
@@ -353,7 +357,7 @@ class MeFragment : BaseFragment(), View.OnClickListener {
}
R.id.iv_vip -> {
VipMainActivity.start(mContext)
VipCenterActivity.start(mContext)
//进入贵族中心埋点
val goldWalletInfo = PayModel.get().currentWalletInfo
val map = HashMap<String, Any>(5)

View File

@@ -15,7 +15,7 @@ import com.chwl.core.room.bean.RoomInfo;
public class NotificationClickReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//todo 跳转之前要处理的逻辑
//TODO 跳转之前要处理的逻辑
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
AVRoomActivity.start(context, roomInfo.getUid());

View File

@@ -4,7 +4,11 @@ import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.ImageView.ScaleType
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -16,10 +20,14 @@ import com.chwl.app.ui.utils.load
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.core.file.FileModel
import com.chwl.core.home.bean.FeedbackTypeBean
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.MyUriUtils
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.photo.PhotoProvider.photoProvider
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.easyphoto.utils.settings.SettingsUtils
import com.chwl.library.utils.ResUtil
@@ -35,6 +43,7 @@ import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
import com.hjq.toast.ToastUtils
import com.netease.nim.uikit.StatusBarUtil
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -52,6 +61,21 @@ class FeedbackActivity : BaseViewBindingActivity<FeedbackActivityBinding>(),
private var imagePath: String? = null
private var imageUrl: String? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
val file = MyUriUtils.copyFile(this,uri)
if (file != null) {
compressPhotos(mutableListOf(file.path))
}
}
}
}
}
override fun init() {
initWhiteTitleBar(ResUtil.getString(R.string.feedback_title))
initView()
@@ -262,26 +286,37 @@ class FeedbackActivity : BaseViewBindingActivity<FeedbackActivityBinding>(),
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
1,
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(
this,Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
1,
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
)
}
}
}

View File

@@ -9,6 +9,7 @@ import com.chwl.app.earn.activity.EarnRecordActivity;
import com.chwl.app.pay.activity.GiveGoldActivity;
import com.chwl.app.ui.feedback.FeedbackActivity;
import com.chwl.app.ui.game_team.record.GameTeamRecordActivity;
import com.chwl.app.vip.VipCenterActivity;
import com.chwl.core.module_hall.hall.bean.H5FamilyInfo;
import com.chwl.core.module_hall.hall.bean.UserClanInfo;
import com.trello.rxlifecycle3.components.support.RxAppCompatActivity;
@@ -38,7 +39,6 @@ import com.chwl.app.ui.pay.ChargeActivity;
import com.chwl.app.ui.setting.ModifyPwdActivity;
import com.chwl.app.ui.user.activity.UserInfoActivity;
import com.chwl.app.ui.webview.CommonWebViewActivity;
import com.chwl.app.vip.VipMainActivity;
import com.chwl.core.DemoCache;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.community.event.SquareTaskEvent;
@@ -216,7 +216,7 @@ public class RouterHandler {
ModifyPwdActivity.start(context, ModifyPwdActivity.LOGIN_PWD);
break;
case RouterType.VIP_MAIN:
VipMainActivity.start(context);
VipCenterActivity.start(context);
break;
case RouterType.CP_INVITE:
CpInviteRecordActivity.Companion.start(context, false);
@@ -297,6 +297,9 @@ public class RouterHandler {
case RouterType.GAME_TEAM_RECORD:
GameTeamRecordActivity.Companion.start(context);
break;
case RouterType.MY_DRESS_ITEM:
MyDecorationActivity.start(context, 0);
break;
default:
SingleToastUtil.showToast(ResUtil.getString(R.string.ui_im_routerhandler_07));
return false;

View File

@@ -79,9 +79,9 @@ public abstract class RecentViewHolder extends RecyclerViewHolder<BaseQuickAdapt
protected void updateBackground(NIMBaseViewHolder holder, RecentContact recent, int position) {
if ((recent.getTag() & RecentContactsFragment.RECENT_TAG_STICKY) == 0) {
holder.getConvertView().setBackgroundResource(R.color.transparent);
// holder.getConvertView().setBackgroundResource(R.drawable.shape_white_10dp_round);
} else {
holder.getConvertView().setBackgroundResource(R.color.transparent);
holder.getConvertView().setBackgroundResource(R.drawable.shape_white_10dp_round);
}
}

View File

@@ -37,10 +37,12 @@ enum class PermissionEntity(
STORAGE(
ResUtil.getString(R.string.setting_bean_permissionentity_011), ResUtil.getString(R.string.setting_bean_permissionentity_012), R.drawable.icon_permission_storage,
arrayOf(
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE
)
);
companion object {
fun fetchPermission(name: String): PermissionEntity? {
if (CoreTextUtils.isEmptyText(name)) return null

View File

@@ -0,0 +1,192 @@
package com.chwl.app.ui.user.activity
import android.content.Context
import android.content.Intent
import android.view.View
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.base.TitleBar
import com.chwl.app.base.TitleBar.ImageAction
import com.chwl.app.common.EmptyViewHelper
import com.chwl.app.common.widget.dialog.DialogManager
import com.chwl.app.common.widget.dialog.DialogManager.OkCancelDialogListener
import com.chwl.app.databinding.ActivityUserCpListBinding
import com.chwl.app.ui.user.adapter.UserCpListAdapter
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.core.UriProvider
import com.chwl.core.bean.response.ServiceResult
import com.chwl.core.user.bean.UserCPListBean
import com.chwl.core.utils.LogUtils
import com.chwl.core.utils.net.DontWarnObserver
import com.chwl.core.utils.net.RxHelper
import com.chwl.library.net.rxnet.RxNet
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.ktx.getString
import com.google.gson.JsonElement
import com.hjq.toast.ToastUtils
import com.netease.nim.uikit.StatusBarUtil
import com.trello.rxlifecycle3.android.ActivityEvent
import io.reactivex.Single
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
class UserCpListActivity : BaseViewBindingActivity<ActivityUserCpListBinding>() {
lateinit var mAdapter : UserCpListAdapter
var mPageNum = 1;
var mPageSize = 20;
companion object{
fun start(context: Context) {
val intent = Intent(context, UserCpListActivity::class.java)
context.startActivity(intent)
}
}
override fun init() {
StatusBarUtil.transparencyBar(this)
StatusBarUtil.StatusBarLightMode(this)
initTitle()
initRvList()
loadData()
}
private fun initTitle() {
initBlackTitleBar(ResUtil.getString(R.string.My_Cp))
val titleBar = findViewById<View>(R.id.title_bar) as TitleBar
titleBar.addAction(object : ImageAction(R.drawable.ic_cp_list_more) {
override fun performAction(view: View?) {
CommonWebViewActivity.start(this@UserCpListActivity, UriProvider.getCpRule())
}
})
}
private fun initRvList(){
mAdapter = UserCpListAdapter(R.layout.item_user_cp_list,1)
binding.rvList.layoutManager = LinearLayoutManager(context,RecyclerView.VERTICAL,false)
binding.rvList.adapter = mAdapter
mAdapter.setOnItemChildClickListener { adapter, view, position ->
when (view.id) {
R.id.cancel -> {
mAdapter.data.getOrNull(position)?.let {
cancelCp(position, it)
}
}
R.id.userAvatarCp -> {
mAdapter.data.getOrNull(position)?.let {
UserInfoActivity.Companion.start(context, it.cpUid)
}
}
else -> {}
}
}
mAdapter.setOnLoadMoreListener {
loadData(true)
}
mAdapter.setEmptyView(EmptyViewHelper.createEmptyTextView(this@UserCpListActivity,R.string.empty_data.getString()))
}
private fun loadData(isAdd: Boolean = false) {
if (!isAdd) {
mPageNum = 1
}
getCpList()
.compose(bindToLifecycle())
.doOnSuccess {
if (mPageNum == 1) {
mAdapter.setNewData(it)
} else {
mAdapter.addData(it)
}
if (it.size == mPageSize) {
mPageNum += 1
mAdapter.setEnableLoadMore(true)
binding.noMore.isVisible = false
} else {
mAdapter.setEnableLoadMore(false)
if (mAdapter?.data?.isEmpty() == true){
binding.noMore.isVisible = true
}
}
mAdapter.loadMoreComplete()
}
.doOnError {
LogUtils.d(" error = ${it.message}")
mAdapter.loadMoreEnd()
}
.subscribe()
}
private fun cancelCp(position: Int, data: UserCPListBean) {
val mDialogManager = DialogManager(context)
mDialogManager?.showOkCancelDialog(ResUtil.getString(R.string.CP_Cancel,data.cancelGoldNum,data.cpNick), true, object :
OkCancelDialogListener {
override fun onCancel() {
mDialogManager?.dismissDialog()
}
override fun onOk() {
postCpCancel(data.uid,data.cpUid,data.cancelGoldNum)
.compose(bindToLifecycle())
.doOnSuccess {
mAdapter.remove(position)
toast(ResUtil.getString(R.string.CP_Cancel_Success,data.cpNick))
}
.subscribe()
mDialogManager?.dismissDialog()
}
})
}
/**
* 获-cp列表
*/
private fun getCpList(): Single<List<UserCPListBean>> {
return api.getCpList(mPageNum,mPageSize)
.compose(RxHelper.handleBeanData())
.compose(RxHelper.handleSchedulers())
}
private fun postCpCancel(uid: Long,loverUid: Long,goldNum: Long): Single<String> {
return api.postCpCancel(uid,loverUid,goldNum)
.compose(RxHelper.handleIgnoreData())
.compose(RxHelper.handleSchedulers())
}
private val api: Api = RxNet.create(Api::class.java);
interface Api {
/**
* 获-cp列表
* page=1
* pageSize=10
*/
@GET("/user/cp/list")
fun getCpList(@Query("page") page: Int,@Query("pageSize") pageSize: Int=20): Single<ServiceResult<List<UserCPListBean>>>
/**
* 取消cp----
* Long uid
* Long loverUid
* Long goldNum //金币列表有返回该字段cancelGoldNum
*/
@POST("/user/cp/cancel")
fun postCpCancel(@Query("uid") uid: Long,@Query("loverUid") loverUid: Long,@Query("goldNum") goldNum: Long): Single<ServiceResult<JsonElement>>
}
}

View File

@@ -7,6 +7,10 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -14,6 +18,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.Fragment;
@@ -24,13 +29,17 @@ import com.chwl.app.avroom.adapter.CommonVPAdapter;
import com.chwl.app.ui.user.adapter.UserInfoTopAlbumAdapter;
import com.chwl.app.ui.user.fragment.UserInfoDataFragment;
import com.chwl.app.ui.user.fragment.UserInfoDynamicFragment;
import com.chwl.app.ui.utils.CpUtils;
import com.chwl.app.utils.AppBarStateChangeListener;
import com.chwl.app.utils.AvatarHelper;
import com.chwl.core.utils.LogUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.widget.SVGAView;
import com.chwl.core.decoration.headwear.bean.HeadWearInfo;
import com.example.lib_utils.UiUtils;
import com.google.android.material.appbar.AppBarLayout;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.impl.cache.NimUserInfoCache;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
@@ -74,6 +83,9 @@ import com.chwl.core.user.bean.UserPhoto;
import com.chwl.core.user.event.LoginUserInfoUpdateEvent;
import com.chwl.core.utils.CoreLogger;
import com.chwl.library.annatation.ActLayoutRes;
import com.tencent.qgame.animplayer.inter.IFetchResource;
import com.tencent.qgame.animplayer.mix.Resource;
import com.tencent.qgame.animplayer.util.ScaleType;
import com.zhpan.bannerview.constants.IndicatorGravity;
import org.greenrobot.eventbus.EventBus;
@@ -81,8 +93,12 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
/**
* create by lvzebiao on 2018/8/31
*/
@@ -98,13 +114,15 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
private UserInfo userInfo;
private boolean mIslike = false;
private int flag = 0;
private LinearLayout bottomViewLayout = null;
private TextView sendMsgLayout;
private TextView attentionLayout;
private ImageView ivOfficialMask;
private TextView tvOfficialMask;
private LinearLayout sendMsgLayout;
private LinearLayout attentionLayout;
private TextView attentionText;
private ImageView attentionImg;
private UserInfoViewModel viewModel;
private boolean isFirst = true;
@SuppressLint("CheckResult")
@Override
@@ -131,6 +149,7 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
viewModel.getUserInfoData().observe(this, infoBean -> {
userInfo = infoBean;
initData(userInfo);
viewModel.getUserInfoDetail();
});
}
@@ -138,7 +157,7 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
protected void onResume() {
super.onResume();
viewModel.getUserInfo();
viewModel.getUserInfoDetail();
}
private void initAttentionView() {
@@ -157,11 +176,14 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
if (bottomViewLayout == null) {
View view = mBinding.vsBottomLayout.getViewStub().inflate();
bottomViewLayout = view.findViewById(R.id.bottom_view_layout);
sendMsgLayout = view.findViewById(R.id.send_msg_layout);
attentionLayout = view.findViewById(R.id.attention_layout);
sendMsgLayout = view.findViewById(R.id.sendMsgLayout);
attentionLayout = view.findViewById(R.id.attentionLayout);
attentionText = view.findViewById(R.id.attentionText);
attentionImg = view.findViewById(R.id.attentionImg);
sendMsgLayout.setOnClickListener(this);
attentionLayout.setOnClickListener(this);
}
bottomViewLayout.setVisibility(View.VISIBLE);
}
}
@@ -171,6 +193,8 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
mBinding.ivEdit.setOnClickListener(this);
mBinding.tvEdit.setOnClickListener(this);
mBinding.layoutLive.setOnClickListener(this);
mBinding.cpCardMore.setOnClickListener(this);
mBinding.userInfoAnim.setOnClickListener(this);
// mBinding.ivTagArrow.setOnClickListener(this);
}
@@ -244,6 +268,10 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
viewModel.getUserInfoDetailData().observe(this, dataBean -> {
initPhoto(dataBean.getPrivatePhoto());
setWhereVisible();
setCpInfo(dataBean);
});
viewModel.getUserInfoDetailError().observe(this, String -> {
finish();
});
}
@@ -253,9 +281,11 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
private void onFindViews() {
mBinding.tbUserInfo.setTitle("");
ivOfficialMask = mBinding.inOfficialMask.findViewById(R.id.iv_official_mask);
tvOfficialMask = mBinding.inOfficialMask.findViewById(R.id.tv_official_mask);
mBinding.ivHeadWear.bindCache(SVGAView.newCache(1));
if (userId == AuthModel.get().getCurrentUid()) {
mBinding.cpCardMore.setVisibility(View.VISIBLE);
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -267,19 +297,10 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
}
private void initData(UserInfo userInfo) {
LogUtils.d(" userinfo initData ");
if (null != userInfo) {
ImageLoadUtilsV2.loadImage(mBinding.ivUserHead, userInfo.getAvatar());
HeadWearInfo headWearInfo = userInfo.getUserHeadwear();
if (headWearInfo != null && headWearInfo.getFirstUrl() != null) {
AvatarHelper.loadAvatarFrame(mBinding.ivHeadWear, headWearInfo.getFirstUrl(), headWearInfo.getType());
mBinding.ivUserHead.setPadding(0, 0, 0, 0);
mBinding.ivUserHead.setStrokeWidth(0);
} else {
int padding = getResources().getDimensionPixelOffset(R.dimen.dp_0_5);
mBinding.ivUserHead.setPadding(padding, padding, padding, padding);
mBinding.ivUserHead.setStrokeWidth(getResources().getDimensionPixelOffset(R.dimen.dp_1));
mBinding.ivHeadWear.setVisibility(View.GONE);
}
//设置昵称
String nick = RegexUtil.getPrintableString(userInfo.getNick());
mBinding.tvNick.setText(nick);
@@ -294,14 +315,12 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
mBinding.tvFollowCount.setText(String.valueOf(userInfo.getFollowNum()));
mBinding.tvErbanId.setText(String.valueOf(userInfo.getErbanNo()));
if (userInfo.isHasPrettyErbanNo()) {
mBinding.ivId.setVisibility(View.GONE);
mBinding.tvErbanId.setTextColor(ContextCompat.getColor(context, R.color.color_FEFFBF));
mBinding.tvErbanId.setTextColor(ContextCompat.getColor(context, R.color.white));
mBinding.tvErbanId.setBackgroundResource(R.drawable.user_info_bg_good_id);
setMarginTop(mBinding.layoutRegion, getResources().getDimensionPixelOffset(R.dimen.dp_5));
} else {
mBinding.tvErbanId.setTextColor(ContextCompat.getColor(context, R.color.color_CC191919));
mBinding.tvErbanId.setTextColor(ContextCompat.getColor(context, R.color.white));
mBinding.tvErbanId.setBackgroundDrawable(null);
mBinding.ivId.setVisibility(View.VISIBLE);
setMarginTop(mBinding.layoutRegion, getResources().getDimensionPixelOffset(R.dimen.dp_8));
}
@@ -323,18 +342,98 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
setUserLevel(userInfo.getUserLevelVo());
//铭牌
setOfficialMask(userInfo.getNameplateWord(), userInfo.getNameplatePic());
if (AuthModel.get().getCurrentUid() != userInfo.getUid()) {
PraiseModel.get().isPraised(AuthModel.get().getCurrentUid(), userInfo.getUid()).subscribe();
}
mBinding.ivChargeAgent.setVisibility(userInfo.isRechargeUser() ? View.VISIBLE : View.GONE);
mBinding.llId.setOnClickListener(view -> {
mBinding.idLayout.setOnClickListener(view -> {
copyName();
});
}
}
//cp
private void setCpInfo(UserDetailInfo.DataBean dataBean) {
UserDetailInfo.DataBean.RelationUserVO cpInfo = dataBean.getRelationUserVO();
//头像
if (cpInfo!= null && cpInfo.cpAvatar != null && !cpInfo.cpAvatar.isEmpty() && cpInfo.showCpAvatar){
//cp 头像
mBinding.cpViews.setVisibility(View.VISIBLE);
mBinding.ivHeadWear.loadFile(CpUtils.INSTANCE.getHeadSvga(cpInfo.cpLevel));
mBinding.ivHeadWearCp.loadFile(CpUtils.INSTANCE.getHeadSvga(cpInfo.cpLevel));
mBinding.ivHeadWearCpFlag.setImageResource(CpUtils.INSTANCE.getFlag(cpInfo.cpLevel));
ImageLoadUtils.loadImage(mBinding.ivUserHeadCp, cpInfo.cpAvatar);
mBinding.ivUserHeadCp.setOnClickListener(v -> {
UserInfoActivity.Companion.start(context,cpInfo.cpUid);
});
}else {
mBinding.cpViews.setVisibility(View.INVISIBLE);
//正常头像
HeadWearInfo headWearInfo = userInfo.getUserHeadwear();
if (headWearInfo != null && headWearInfo.getFirstUrl() != null) {
AvatarHelper.loadAvatarFrame(mBinding.ivHeadWear, headWearInfo.getFirstUrl(), headWearInfo.getType());
mBinding.ivUserHead.setPadding(0, 0, 0, 0);
mBinding.ivHeadWear.setVisibility(View.VISIBLE);
} else {
int padding = getResources().getDimensionPixelOffset(R.dimen.dp_0_5);
mBinding.ivUserHead.setPadding(padding, padding, padding, padding);
mBinding.cpViews.setVisibility(View.INVISIBLE);
mBinding.ivHeadWear.setVisibility(View.INVISIBLE);
}
}
//cp 卡片
if (cpInfo!= null && cpInfo.cpAvatar != null && !cpInfo.cpAvatar.isEmpty()) {
mBinding.cpCardDay.setText(cpInfo.cpDay + ""+ ResUtil.getString(R.string.days));
mBinding.cpCardDay.setVisibility(cpInfo.cpDay > 0? View.VISIBLE : View.INVISIBLE);
mBinding.cpCardLevel.setImageResource(CpUtils.INSTANCE.getLevelImg(cpInfo.cpLevel));
mBinding.cpCardLevel.setVisibility(View.VISIBLE);
mBinding.cpCardLevelEmpty.setVisibility(View.INVISIBLE);
ImageLoadUtilsV2.loadImage(mBinding.cpCardUserAvatar, userInfo.getAvatar());
ImageLoadUtilsV2.loadImage(mBinding.cpCardUserAvatarCp, cpInfo.cpAvatar);
mBinding.cpCardUserHeadCp.setVisibility(View.VISIBLE);
mBinding.cpCardUserAvatarCp.setOnClickListener(v -> {
UserInfoActivity.Companion.start(context,cpInfo.cpUid);
});
}else {
mBinding.cpCardDay.setVisibility(View.INVISIBLE);
mBinding.cpCardLevelEmpty.setVisibility(View.VISIBLE);
mBinding.cpCardLevel.setVisibility(View.INVISIBLE);
mBinding.cpCardUserAvatarCp.setImageResource(R.drawable.ic_user_info_cp_def_avatar);
mBinding.cpCardUserAvatarCp.setOnClickListener(null);
mBinding.cpCardUserHeadCp.setVisibility(View.INVISIBLE);
ImageLoadUtilsV2.loadImage(mBinding.cpCardUserAvatar, userInfo.getAvatar());
}
//cp 动画
if (cpInfo != null && cpInfo.showCpAnim && isFirst) {
String animUrl = CpUtils.INSTANCE.getUserInfoAnim(cpInfo.cpLevel);
HashMap<String, String> imgMap = new HashMap<>();
imgMap.put("avatar1", cpInfo.avatar);
imgMap.put("avatar2", cpInfo.cpAvatar);
if (animUrl != null) {
CpUtils.INSTANCE.loadVap(
mBinding.userInfoAnim,
animUrl,
imgMap,null
);
}
}else {
mBinding.userInfoAnim.setVisibility(View.GONE);
}
isFirst = false;
}
private void setMarginTop(View view, int top) {
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
@@ -398,13 +497,26 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
.setOnPageClickListener((clickedView, position) -> {
showUserPhoto(position);
})
.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
try {
if (mBinding.bannerViewIndex.getTag() != null) {
int itemCount = (int) mBinding.bannerViewIndex.getTag();
mBinding.bannerViewIndex.setText((position+1)+"/"+itemCount);
}
} catch (Exception e) {
}
}
})
.setRTLMode(isRTL)
.setIndicatorHeight(width)
.setIndicatorGravity(isRTL ? IndicatorGravity.START : IndicatorGravity.END)
.setIndicatorSliderWidth(width, width * 2)
.setIndicatorSliderGap(context.getResources().getDimensionPixelOffset(R.dimen.dp_6))
.setIndicatorMargin(isRTL ? marginEnd : 0, 0, isRTL ? 0 : marginEnd, context.getResources().getDimensionPixelOffset(R.dimen.dp_71))
.setAdapter(adapter).create();
.setAdapter(adapter)
.create();
}
/**
@@ -413,8 +525,13 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
private void initPhoto(List<UserDetailInfo.DataBean.PrivatePhotoBean> list) {
if (list == null) {
mBinding.bannerView.refreshData(new ArrayList());
mBinding.bannerViewIndex.setTag(0);
mBinding.bannerViewIndex.setVisibility(View.INVISIBLE);
} else {
mBinding.bannerView.refreshData(list);
mBinding.bannerViewIndex.setTag(list.size());
mBinding.bannerViewIndex.setText(1+"/"+list.size());
mBinding.bannerViewIndex.setVisibility(View.VISIBLE);
}
}
@@ -450,10 +567,11 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
@Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
if (state == State.COLLAPSED) {
mBinding.ivUserBack.setImageResource(R.drawable.icon_user_back_black);
mBinding.tbUserInfo.setBackgroundColor(getResources().getColor(R.color.white));
// mBinding.ivUserBack.setImageResource(R.drawable.icon_user_back_black);
mBinding.ivUserBack.setImageResource(R.drawable.icon_user_back);
mBinding.tbUserInfo.setBackgroundColor(getResources().getColor(R.color.color_08151a));
setTitleVisible(true);
setEditButton(identityState, true);
setEditButton(identityState, false);
}else{
mBinding.ivUserBack.setImageResource(R.drawable.icon_user_back);
mBinding.tbUserInfo.setBackgroundColor(getResources().getColor(R.color.transparent));
@@ -494,11 +612,15 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
mBinding.tvEdit.setVisibility(View.GONE);
}
if (isExpanded) {
mBinding.ivEdit.setImageResource(R.drawable.user_info_ic_more_black);
mBinding.tvEdit.setImageResource(R.drawable.user_info_ic_edit_black);
mBinding.ivEdit.setImageTintList(ColorStateList.valueOf(Color.BLACK));
mBinding.tvEdit.setImageTintList(ColorStateList.valueOf(Color.BLACK));
// mBinding.ivEdit.setImageResource(R.drawable.user_info_ic_more_black);
// mBinding.tvEdit.setImageResource(R.drawable.user_info_ic_edit_black);
} else {
mBinding.ivEdit.setImageResource(R.drawable.user_info_ic_more);
mBinding.tvEdit.setImageResource(R.drawable.user_info_ic_edit);
// mBinding.ivEdit.setImageResource(R.drawable.user_info_ic_more);
// mBinding.tvEdit.setImageResource(R.drawable.user_info_ic_edit);
mBinding.ivEdit.setImageTintList(ColorStateList.valueOf(Color.WHITE));
mBinding.tvEdit.setImageTintList(ColorStateList.valueOf(Color.WHITE));
}
}
@@ -567,16 +689,18 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
// UserLabelDialog.newInstance(userInfo.getLabels(), userId).show(this);
// break;
case R.id.iv_user_back:
case R.id.ivUserBack:
finish();
break;
case R.id.tv_edit:
case R.id.iv_edit:
case R.id.tvEdit:
case R.id.ivEdit:
editClick(identityState);
break;
case R.id.send_msg_layout:
case R.id.sendMsgLayout:
NimUserInfo nimUserInfo = NimUserInfoCache.getInstance().getUserInfo(String.valueOf(userId));
if (nimUserInfo != null) {
NimP2PMessageActivity.start(this, String.valueOf(userId));
@@ -594,7 +718,7 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
}
break;
case R.id.attention_layout:
case R.id.attentionLayout:
if (userInfo == null) {
toast(getString(R.string.me_user_information_is_empty));
return;
@@ -622,7 +746,7 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
PraiseModel.get().praise(userInfo.getUid(), true).subscribe();
}
break;
case R.id.layout_live:
case R.id.layoutLive:
if (userInfo == null) {
toast(getString(R.string.me_user_information_is_empty));
return;
@@ -632,6 +756,15 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
AVRoomActivity.FROM_TYPE_USER, userInfo.getNick(), String.valueOf(userInfo.getUid()));
}
break;
case R.id.cpCardMore:
UserCpListActivity.Companion.start(this);
break;
case R.id.userInfoAnim:
mBinding.userInfoAnim.stopPlay();
mBinding.userInfoAnim.clearAnimation();
mBinding.userInfoAnim.setVisibility(View.GONE);
break;
}
}
@@ -642,7 +775,9 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
private void setLikedText(boolean isliked) {
mIslike = isliked;
attentionLayout.setText(getString((isliked) ? R.string.already_attention : R.string.follow));
attentionLayout.setBackgroundResource((isliked) ? R.drawable.user_info_follow_ed : R.drawable.user_info_follow_n);
attentionText.setText(getString((isliked) ? R.string.already_attention : R.string.follow));
attentionImg.setBackgroundResource((isliked) ? R.drawable.ic_user_info_followed : R.drawable.ic_user_info_follow);
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -661,13 +796,13 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
}
private void setOfficialMask(String name, String icon) {
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(icon)) {
if( userInfo.isCustomWord() && !TextUtils.isEmpty(icon)){
mBinding.inOfficialMask.setVisibility(View.VISIBLE);
if (tvOfficialMask != null && ivOfficialMask != null) {
tvOfficialMask.setText(name);
ImageLoadUtils.loadImage(this, icon, ivOfficialMask);
}
ImageLoadUtils.loadImage(this, icon, mBinding.ivOfficialMask);
}else if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(icon)) {
mBinding.inOfficialMask.setVisibility(View.VISIBLE);
mBinding.tvOfficialMask.setText(name);
ImageLoadUtils.loadImage(this, icon, mBinding.ivOfficialMask);
} else {
mBinding.inOfficialMask.setVisibility(View.GONE);
}

View File

@@ -10,6 +10,10 @@ import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.fourmob.datetimepicker.date.DatePickerDialog
@@ -25,6 +29,7 @@ import com.chwl.app.UIHelper
import com.chwl.app.application.App
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.common.util.BitmapUtil
import com.chwl.app.constants.UserInfoConstants
import com.chwl.app.databinding.ActivityUserInfoModifyBinding
import com.chwl.app.ui.login.ModifyInfoActivity
import com.chwl.app.ui.user.adapter.UserPhotoAdapter
@@ -36,16 +41,22 @@ import com.chwl.app.utils.RegexUtil
import com.chwl.core.auth.AuthModel
import com.chwl.core.file.FileModel
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.UserDetailInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.user.bean.UserPhoto
import com.chwl.core.utils.CoreLogger
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.LogUtils
import com.chwl.library.common.file.FileHelper
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.TimeUtils
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import io.reactivex.Completable
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
@@ -92,10 +103,18 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
userId = intent.getLongExtra("userId", 0)
}
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
UserModel.get().getUserInfo(userId).subscribe(userInfoUpdateObserver)
PhotoCompressUtil.clearCompressCache()
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
crop(uri, 1, mUri)
}
}
}
override fun click(position: Int, userPhoto: UserPhoto, isOwner: Boolean) {
@@ -133,6 +152,12 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
binding.rvPhotos.visibility = View.GONE
}
binding.tvArea.text = userInfo.region
//cp 设置获取
UserModel.get().getUserInfoDetail(userId).compose(bindToLifecycle()).doOnSuccess {
setSwitchView(binding.swCpShow,it?.data?.relationUserVO?.showCpAvatar?:false)
setSwitchView(binding.swCpAnim,it?.data?.relationUserVO?.showCpAnim?:false)
}.subscribe()
}
}
@@ -143,6 +168,8 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
binding.layoutPhotos.setOnClickListener(this)
binding.llDesc.setOnClickListener(this)
binding.layoutArea.setOnClickListener(this)
binding.swCpAnim.setOnClickListener(this)
binding.swCpShow.setOnClickListener(this)
val mLayoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true)
binding.rvPhotos.layoutManager = mLayoutManager
}
@@ -284,11 +311,68 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
toast(e.message)
}
})
} R.id.layout_area -> {
dialogManager.showProgressDialog(
this@UserInfoModifyActivity,
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_02)
)
UserModel.get().areaInfo.subscribe(object : SingleObserver<List<String>> {
override fun onSubscribe(d: Disposable) {
mCompositeDisposable.add(d)
}
override fun onSuccess(areaList: List<String>) {
dialogManager.dismissDialog()
if (areaList.isNotEmpty()) {
UserAreaDialog.newInstance(areaList)
.apply {
setAction {
reportArea(it)
}
}.show(this@UserInfoModifyActivity)
}
}
override fun onError(e: Throwable) {
dialogManager.dismissDialog()
toast(e.message)
}
})
}
R.id.swCpAnim -> {
postUpDateCpSwitch(binding.swCpAnim,UserInfoConstants.CpSet.cpAnim)
}
R.id.swCpShow -> {
postUpDateCpSwitch(binding.swCpShow,UserInfoConstants.CpSet.cpAvatar)
}
else -> {}
}
}
//post update set
private fun postUpDateCpSwitch(view: ImageView,type:Int){
val tag = view.tag
if (tag != null && tag is Boolean){
val tagVal = !tag
UserModel.get().userCpSettingUpdate(type,tagVal)
.compose(bindToLifecycle())
.doOnSuccess {
setSwitchView(view,tagVal,true)
}.subscribe()
}
}
// set view
private fun setSwitchView(view: ImageView, on:Boolean,notify:Boolean=false){
view.setImageResource(if (on) R.drawable.ic_user_edit_sw_on else R.drawable.ic_user_edit_sw_off)
view.tag = on
if (notify) {
//通知 cp设置改变 todo do
}
}
private fun reportArea(area: String) {
binding.tvArea.text = area
dialogManager.showProgressDialog(
@@ -358,24 +442,30 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(this,Manifest.permission.READ_EXTERNAL_STORAGE)) {
EasyPermissions.requestPermissions(this, getString(R.string.permission_storage_rationale), PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(this, resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER)
}
}
}
private fun getNowTime(): String {
@@ -488,14 +578,16 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
toast(R.string.text_bitmap_too_large)
return
}
if (sourceSize > 0) {
//不能上传图片的最小文件大小
CoreLogger.debug(TAG, "sourceSize: $sourceSize")
if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
toast(R.string.text_bitmap_too_small)
return
}
}
// if (sourceSize > 0) {
// //不能上传图片的最小文件大小
// CoreLogger.debug(TAG, "sourceSize: $sourceSize")
// if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
// toast(R.string.text_bitmap_too_small)
// return
// }
// }
val options = UCrop.Options().apply {
setCompressionQuality(100)
setShowCropGrid(false)

View File

@@ -11,6 +11,9 @@ import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.widget.GridView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import com.hjq.toast.ToastUtils
import com.jph.takephoto.app.TakePhotoActivity
@@ -30,13 +33,17 @@ import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.user.bean.UserPhoto
import com.chwl.core.utils.CoreLogger
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.net.BeanObserver
import com.chwl.library.common.file.FileHelper
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.utils.ResUtil
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
import java.io.FileNotFoundException
import java.text.SimpleDateFormat
@@ -57,6 +64,8 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
private var mUri: Uri? = null
private var mJob: Job? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
companion object {
const val FLAG_CHANGE = "isChanged"
private const val TAG = "UserModifyPhotosActivit"
@@ -95,6 +104,14 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
if (userInfo != null) {
updateView()
}
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
crop(it, 0, mUri)
}
}
}
}
private fun initView() {
@@ -219,24 +236,38 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(
this, Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
}
}
}
private fun getNowTime(): String {
@@ -309,14 +340,14 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
toast(R.string.text_bitmap_too_large)
return
}
if (sourceSize > 0) {
//不能上传图片的最小文件大小
CoreLogger.debug(TAG, "sourceSize: $sourceSize")
if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
toast(R.string.text_bitmap_too_small)
return
}
}
// if (sourceSize > 0) {
// //不能上传图片的最小文件大小
// CoreLogger.debug(TAG, "sourceSize: $sourceSize")
// if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
// toast(R.string.text_bitmap_too_small)
// return
// }
// }
val options = UCrop.Options().apply {
setCompressionQuality(100)
setShowCropGrid(false)

View File

@@ -1,6 +1,7 @@
package com.chwl.app.ui.user.adapter;
import android.content.Context;
import android.graphics.Typeface;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -14,14 +15,16 @@ import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
import com.chwl.library.language.LanguageHelper;
import com.tencent.qgame.animplayer.mix.Resource;
import java.util.List;
public class ContactsIndicatorAdapter extends CommonNavigatorAdapter {
private final List<? extends CharSequence> mTitleList;
private int textSize = 16;
private float minScale = 1f;
private int textSize = 20;
private float minScale = 0.8f;
private boolean showIndicator = true;
private OnItemSelectListener mOnItemSelectListener;
@@ -37,10 +40,14 @@ public class ContactsIndicatorAdapter extends CommonNavigatorAdapter {
@Override
public IPagerTitleView getTitleView(Context context, final int i) {
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_84868A));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_1E1E1F));
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_313131));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_313131));
scaleTransitionPagerTitleView.setMinScale(minScale);
scaleTransitionPagerTitleView.setTextSize(textSize);
if (LanguageHelper.INSTANCE.getCurrentLanguageType().equals("EN")) {
scaleTransitionPagerTitleView.setTextSize(textSize);
} else {
scaleTransitionPagerTitleView.setTextSize(textSize-2);
}
int padding = UIUtil.dip2px(context, 16);
scaleTransitionPagerTitleView.setPadding(padding, 0, padding, 0);
scaleTransitionPagerTitleView.setText(mTitleList.get(i));

View File

@@ -0,0 +1,51 @@
package com.chwl.app.ui.user.adapter
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.chwl.app.R
import com.chwl.app.bindadapter.BaseAdapter
import com.chwl.app.bindadapter.BindingViewHolder
import com.chwl.app.databinding.ItemUserCpListBinding
import com.chwl.app.ui.utils.CpUtils.getHeadSvga
import com.chwl.app.ui.utils.CpUtils.getLevelImg
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.utils.NumberUtils
import com.chwl.core.user.bean.UserCPListBean
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.ktx.getString
class UserCpListAdapter : BaseAdapter<UserCPListBean> {
constructor(layoutResId: Int, brid: Int) : super(layoutResId, brid)
override fun convert(helper: BindingViewHolder, data: UserCPListBean?) {
super.convert(helper, data)
if (data == null ) return
val mViewBinding = helper.binding as ItemUserCpListBinding
mViewBinding.cpLevel.setImageResource(getLevelImg(data.cpLevel))
ImageLoadUtils.loadImage(mViewBinding.userAvatar,data.avatar)
ImageLoadUtils.loadImage(mViewBinding.userAvatarCp,data.cpAvatar)
val max = (data.endExp - data.startExp)
val current = (data.currentExp.toFloat() / max.toFloat()) * 100f
mViewBinding.cpPro.max = 100
mViewBinding.cpPro.progress = current.toInt()
mViewBinding.cpProVal.text = "${NumberUtils.format(data.currentExp)} / ${NumberUtils.format(data.endExp)}"
mViewBinding.cpNeedVal.text = ResUtil.getString(R.string.CP_Need_tips,NumberUtils.format((data.endExp - data.currentExp)))
mViewBinding.cpDay.text = "${data.cpDay}${R.string.days.getString()}"
mViewBinding.cpDay.isVisible = data.cpDay > 0
helper.addOnClickListener(mViewBinding.cancel.id)
helper.addOnClickListener(mViewBinding.userAvatarCp.id)
}
}

View File

@@ -12,6 +12,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -65,6 +66,8 @@ public class UserInfoDynamicAdapter extends BaseQuickAdapter<WorldDynamicBean, B
*/
private int divider;
public boolean isUserInfo = false;
public UserInfoDynamicAdapter(Context context) {
super(R.layout.item_userinfo_dynamic);
this.context = context;
@@ -174,6 +177,16 @@ public class UserInfoDynamicAdapter extends BaseQuickAdapter<WorldDynamicBean, B
//跳转去详情
helper.itemView.setOnClickListener(toDetailListener);
helper.setGone(R.id.line_bottom, getItemCount() - 1 != helper.getLayoutPosition());
if (isUserInfo) {
helper.setTextColor(R.id.tv_time, ContextCompat.getColor(context,R.color.white));
helper.setTextColor(R.id.expandable_text, ContextCompat.getColor(context,R.color.white));
helper.setTextColor(R.id.tv_mini_world_name, ContextCompat.getColor(context,R.color.white));
helper.setTextColor(R.id.tv_like, ContextCompat.getColor(context,R.color.white_tran_60));
helper.setTextColor(R.id.tv_comment, ContextCompat.getColor(context,R.color.white_tran_60));
helper.setVisible(R.id.line_bottom, false);
}
}
private void setLikeCount(BaseViewHolder helper, int likeCount, boolean isLike, boolean isAnim) {

View File

@@ -12,16 +12,14 @@ import com.chwl.core.user.bean.GiftWallInfo
class UserInfoGiftAdapter(private val itemBgRes: Int = R.drawable.user_info_bg_gift) :
BaseQuickAdapter<GiftWallInfo, BaseViewHolder>(R.layout.user_info_item_gift) {
override fun onCreateDefViewHolder(parent: ViewGroup?, viewType: Int): BaseViewHolder {
return super.onCreateDefViewHolder(parent, viewType).apply {
getView<ImageView>(R.id.iv_bg).setImageResource(itemBgRes)
}
return super.onCreateDefViewHolder(parent, viewType)
}
override fun convert(helper: BaseViewHolder, item: GiftWallInfo) {
helper.setText(R.id.tv_name, item.giftName)
helper.setText(R.id.tv_count, "x${item.reciveCount}")
val iconView = helper.getView<ImageView>(R.id.iv_icon)
iconView.load(item.picUrl)
iconView.load(item.picUrl,0f,R.drawable.transparent_draw)
val rankView = helper.itemView.findViewById<ImageView>(R.id.iv_rank)
if (helper.bindingAdapterPosition == 0) {
rankView.setImageResource(R.drawable.ic_gift_one)

View File

@@ -1,6 +1,7 @@
package com.chwl.app.ui.user.adapter;
import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -21,7 +22,7 @@ import java.util.List;
public class UserInfoIndicatorAdapter extends CommonNavigatorAdapter {
private final List<? extends CharSequence> mTitleList;
private int textSize = 20;
private int textSize = 18;
private float minScale = 0.9f;
private boolean showIndicator = true;
private OnItemSelectListener mOnItemSelectListener;
@@ -38,8 +39,8 @@ public class UserInfoIndicatorAdapter extends CommonNavigatorAdapter {
@Override
public IPagerTitleView getTitleView(Context context, final int i) {
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_7F191919));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_191919));
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.white_tran_60));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.white));
scaleTransitionPagerTitleView.setMinScale(minScale);
scaleTransitionPagerTitleView.setTextSize(textSize);
int padding = context.getResources().getDimensionPixelOffset(R.dimen.dp_12);
@@ -60,7 +61,7 @@ public class UserInfoIndicatorAdapter extends CommonNavigatorAdapter {
indicator.setLineHeight(UIUtil.dip2px(context, 3));
indicator.setRoundRadius(UIUtil.dip2px(context, 1.5));
indicator.setLineWidth(UIUtil.dip2px(context, 17));
indicator.setColors(context.getResources().getColor(R.color.color_26CC9C));
indicator.setColors(Color.parseColor("#04d5c6"));
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// lp.bottomMargin = mBottomMargin;
indicator.setLayoutParams(lp);

View File

@@ -6,11 +6,59 @@ import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.load
import com.chwl.core.user.bean.MedalBean
import com.chwl.library.download.DownloadManager
import com.chwl.library.download.DownloadRequest
import com.chwl.library.download.DownloadTask
import com.chwl.library.download.FileDownloadListener
import com.chwl.library.utils.PathHelper
import com.tencent.qgame.animplayer.AnimConfig
import com.tencent.qgame.animplayer.AnimView
import com.tencent.qgame.animplayer.inter.IAnimListener
import com.tencent.qgame.animplayer.util.ScaleType
import java.io.File
class UserInfoMedalAdapter :
BaseQuickAdapter<MedalBean, BaseViewHolder>(R.layout.user_info_item_medal) {
override fun convert(helper: BaseViewHolder, item: MedalBean) {
val imageView = helper.getView<ImageView>(R.id.iv_image)
imageView.load(item.picUrl)
item.picUrl?.let {
if (it.replace("\n", "").lowercase().endsWith("mp4")) {
val mp4View = helper.getView<AnimView>(R.id.iv_mp4)
mp4View.setScaleType(ScaleType.FIT_XY)
mp4View.setLoop(Int.MAX_VALUE)
mp4View.setAnimListener(object : IAnimListener {
override fun onFailed(errorType: Int, errorMsg: String?) {
}
override fun onVideoComplete() {
}
override fun onVideoDestroy() {
}
override fun onVideoRender(frameIndex: Int, config: AnimConfig?) {
}
override fun onVideoStart() {
}
})
val filePath = PathHelper.generateResourcesFilePath(it)
val request = DownloadRequest.build(it, filePath, "", null, 600000L)
DownloadManager.download(request, object : FileDownloadListener() {
override fun onDownloadCompleted(task: DownloadTask) {
val path = task.getRequest().getPath()
mp4View.startPlay(File(path))
}
})
} else {
val imageView = helper.getView<ImageView>(R.id.iv_image)
imageView.load(item.picUrl,0f,R.drawable.transparent_draw)
}
}
helper.setText(R.id.medalName,item.medalName)
}
}

View File

@@ -2,9 +2,9 @@ package com.chwl.app.ui.user.fragment
import android.content.Intent
import android.view.View
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingFragment
import com.chwl.app.databinding.UserInfoDataFragmentBinding
@@ -16,12 +16,17 @@ import com.chwl.app.ui.user.activity.UserModifyPhotosActivity
import com.chwl.app.ui.user.adapter.UserInfoAlbumAdapter
import com.chwl.app.ui.user.adapter.UserInfoGameTeamAdapter
import com.chwl.app.ui.user.adapter.UserInfoGiftAdapter
import com.chwl.app.ui.user.adapter.UserInfoIndicatorAdapter
import com.chwl.app.ui.user.adapter.UserInfoMedalAdapter
import com.chwl.app.ui.user.viewmodel.UserInfoViewModel
import com.chwl.app.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
import com.chwl.app.ui.utils.load
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
import com.chwl.app.ui.widget.recyclerview.decoration.SpacingDecoration
import com.chwl.core.game_team.UserGameTeamInfo
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.UserPhoto
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.ktx.getString
class UserInfoDataFragment : BaseViewBindingFragment<UserInfoDataFragmentBinding>() {
@@ -30,9 +35,10 @@ class UserInfoDataFragment : BaseViewBindingFragment<UserInfoDataFragmentBinding
override fun init() {
initGameTeam()
initAlbum()
initOther()
initMedal()
initGift()
initLuckyGift()
setGuild()
FragmentVisibleStateHelper(this).apply {
this.start {
onVisibleChanged(it, isFirstVisible)
@@ -40,6 +46,38 @@ class UserInfoDataFragment : BaseViewBindingFragment<UserInfoDataFragmentBinding
}
}
private fun initOther() {
val tagList =
arrayListOf(ResUtil.getString(R.string.medal), ResUtil.getString(R.string.gift_action))
val commonNavigator = CommonNavigator(context)
commonNavigator.setTitleWrapContent(false)
val magicIndicatorAdapter = UserInfoIndicatorAdapter(context, tagList)
magicIndicatorAdapter.textSize = 16
magicIndicatorAdapter.setOnItemSelectListener { position: Int, view: TextView? ->
binding.magicIndicator.onPageSelected(position)
onOtherTabChange(view?.text?.toString() ?: "")
}
commonNavigator.adapter = magicIndicatorAdapter
binding.magicIndicator.setNavigator(commonNavigator)
}
private fun onOtherTabChange(str: String) {
when (str) {
ResUtil.getString(R.string.medal) -> {
binding.layoutGift.isVisible = false
binding.layoutMedal.isVisible = true
}
ResUtil.getString(R.string.gift_action) -> {
binding.layoutGift.isVisible = true
binding.layoutMedal.isVisible = false
}
else -> {}
}
}
private fun initGameTeam() {
val adapter = UserInfoGameTeamAdapter(viewModel.isMe)
binding.recyclerViewGameTeam.addItemDecoration(
@@ -96,74 +134,81 @@ class UserInfoDataFragment : BaseViewBindingFragment<UserInfoDataFragmentBinding
binding.recyclerViewMedal.adapter = medalAdapter
viewModel.userInfoDetailData.observe(this) {
val list = it.medals?.userMedals
binding.tvMedalCount.text = "(${list?.size ?: 0})"
if (medalAdapter.itemCount > 0) return@observe
medalAdapter.setNewData(list)
binding.layoutMedal.isVisible = !list.isNullOrEmpty()
binding.tvMedalStatus.isVisible = list.isNullOrEmpty()
}
}
var isMiniMode = true
private fun initGift() {
val giftAdapter = UserInfoGiftAdapter()
var isMiniMode = true
binding.ivGiftMore.setOnClickListener {
isMiniMode = !isMiniMode
val list = viewModel.giftListLiveData.value ?: emptyList()
loadListData(giftAdapter, 4, isMiniMode, list, binding.ivGiftMore)
loadListData(giftAdapter, 4, isMiniMode, binding.ivGiftMore)
binding.ivGiftMore.animate().rotationBy(180f).start()
}
binding.recyclerViewGift.addItemDecoration(
GridSpacingItemNewDecoration(
resources.getDimensionPixelOffset(R.dimen.dp_12),
resources.getDimensionPixelOffset(R.dimen.dp_2),
false
)
)
binding.recyclerViewGift.adapter = giftAdapter
viewModel.giftListLiveData.observe(this) {
loadListData(giftAdapter, 4, isMiniMode, it, binding.ivGiftMore)
binding.tvGiftStatus.isVisible = it.isNullOrEmpty()
loadListData(giftAdapter, 4, isMiniMode, binding.ivGiftMore)
}
viewModel.requestGiftList()
}
private fun initLuckyGift() {
val luckyGiftAdapter = UserInfoGiftAdapter(R.drawable.user_info_bg_lucku_gift)
var isMiniMode = true
binding.ivLuckyGiftMore.setOnClickListener {
isMiniMode = !isMiniMode
val list = viewModel.luckyGiftListLiveData.value ?: emptyList()
loadListData(luckyGiftAdapter, 4, isMiniMode, list, binding.ivLuckyGiftMore)
binding.ivLuckyGiftMore.animate().rotationBy(180f).start()
}
binding.recyclerViewLuckyGift.addItemDecoration(
GridSpacingItemNewDecoration(
resources.getDimensionPixelOffset(R.dimen.dp_12),
resources.getDimensionPixelOffset(R.dimen.dp_2),
false
)
)
binding.recyclerViewLuckyGift.adapter = luckyGiftAdapter
viewModel.luckyGiftListLiveData.observe(this) {
loadListData(luckyGiftAdapter, 4, isMiniMode, it, binding.ivLuckyGiftMore)
binding.tvLuckyGiftStatus.isVisible = it.isNullOrEmpty()
loadListData(giftAdapter, 4, isMiniMode, binding.ivGiftMore)
}
viewModel.requestLuckyGiftList()
viewModel.loadUserInfoGiftWallData()
}
private fun <T> loadListData(
adapter: BaseQuickAdapter<T, *>,
private fun setGuild() {
UserModel.get().getUserInfoDetailCache(viewModel.userId).compose(bindToLifecycle())
.doOnSuccess {
it?.data?.guildInfo?.let {
//guildName
binding.guildName.text = "${R.string.Guild_Nick.getString()}:${it.guildName}"
//guildId
binding.guildId.text = "${R.string.Guild_ID.getString()}:${it.guildId}"
//guildAgentId
binding.guildAgentId.text = "${R.string.Agent_ID.getString()}:${it.erbanNo}"
//guildImg
binding.guildImg.load(it.avatar)
binding.guildLayout.isVisible = true
}
}.subscribe()
}
private fun loadListData(
adapter: UserInfoGiftAdapter,
miniCount: Int,
miniOrFull: Boolean,
list: List<T>,
moreView: View
) {
val finalList = if (miniOrFull) {
list.take(miniCount)
if (viewModel.luckyGiftIsRead && viewModel.giftIsRead) {
if (!viewModel.giftWallIsRead) {
val gift = viewModel.giftListLiveData.value ?: emptyList()
val luckyGift = viewModel.luckyGiftListLiveData.value ?: emptyList()
viewModel.userInfoGiftWallData.addAll(gift)
viewModel.userInfoGiftWallData.addAll(luckyGift)
viewModel.userInfoGiftWallData.sortBy { it.reciveCount }
viewModel.giftWallIsRead = true
}
} else {
list
return
}
val finalList = if (miniOrFull) {
viewModel.userInfoGiftWallData.take(miniCount)
} else {
viewModel.userInfoGiftWallData
}
adapter.setNewData(finalList)
moreView.isVisible = list.size > miniCount
moreView.isVisible = viewModel.userInfoGiftWallData.size > miniCount
binding.tvGiftStatus.isVisible = finalList.isEmpty()
}
private fun showPhotoPreview(list: ArrayList<UserPhoto>, position: Int) {
@@ -175,10 +220,8 @@ class UserInfoDataFragment : BaseViewBindingFragment<UserInfoDataFragmentBinding
private fun onVisibleChanged(isVisible: Boolean, isFirstVisible: Boolean) {
if (isVisible && !isFirstVisible) {
if (viewModel.giftListLiveData.value.isNullOrEmpty()) {
if (viewModel.userInfoGiftWallData.isEmpty()) {
viewModel.requestGiftList()
}
if (viewModel.luckyGiftListLiveData.value.isNullOrEmpty()) {
viewModel.requestLuckyGiftList()
}
}

View File

@@ -36,6 +36,7 @@ class UserInfoDynamicFragment : BaseViewBindingFragment<UserInfoDynamicFragmentB
private fun initView() {
adapter = UserInfoDynamicAdapter(requireContext())
adapter?.isUserInfo = true
adapter?.setEnableLoadMore(false)
adapter?.emptyView = layoutInflater.inflate(R.layout.user_info_tab_empty, null)
binding.recyclerView.adapter = adapter

View File

@@ -26,12 +26,19 @@ class UserInfoViewModel : BaseViewModel() {
val userInfoData: LiveData<UserInfo> = _userInfoData
private val _userInfoDetailData = MutableLiveData<UserDetailInfo.DataBean>()
private val _userInfoDetailError = MutableLiveData<String>()
val userInfoDetailData: LiveData<UserDetailInfo.DataBean> = _userInfoDetailData
val userInfoDetailError: LiveData<String> = _userInfoDetailError
val userClanData = MutableLiveData<UserClanInfo>()
val giftListLiveData = MutableLiveData<List<GiftWallInfo>>()
val luckyGiftListLiveData = MutableLiveData<List<GiftWallInfo>>()
val userInfoGiftWallData = mutableListOf<GiftWallInfo>()
var luckyGiftIsRead = false
var giftIsRead = false
var giftWallIsRead = false
fun getUserInfo() {
UserModel.get().getUserInfoFromServer(userId)
@@ -55,6 +62,7 @@ class UserInfoViewModel : BaseViewModel() {
.subscribe(object : BeanObserver<UserDetailInfo?>() {
override fun onErrorMsg(error: String) {
error.toast()
_userInfoDetailError.postValue(error)
}
override fun onSuccess(info: UserDetailInfo) {
@@ -85,14 +93,32 @@ class UserInfoViewModel : BaseViewModel() {
}
fun requestGiftList() {
addDisposable(UserModel.get().requestUserGiftWall(userId, 1, 2).subscribe { it ->
giftListLiveData.postValue(it)
})
addDisposable(UserModel.get().requestUserGiftWall(userId, 1, 2)
.doOnError {
giftIsRead=true
}
.subscribe { it ->
giftIsRead=true
giftListLiveData.postValue(it)
})
}
fun requestLuckyGiftList() {
addDisposable(UserModel.get().requestUserGiftWall(userId, 2, 2).subscribe { it ->
luckyGiftListLiveData.postValue(it)
})
addDisposable(UserModel.get().requestUserGiftWall(userId, 2, 2)
.doOnError {
luckyGiftIsRead=true
}
.subscribe { it ->
luckyGiftListLiveData.postValue(it)
luckyGiftIsRead=true
})
}
fun loadUserInfoGiftWallData(){
giftIsRead = false
luckyGiftIsRead = false
userInfoGiftWallData.clear()
requestGiftList()
requestLuckyGiftList()
}
}

View File

@@ -0,0 +1,168 @@
package com.chwl.app.ui.utils
import android.graphics.Bitmap
import android.view.View
import android.view.View.OnAttachStateChangeListener
import androidx.core.view.isVisible
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestFutureTarget
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.chwl.app.R
import com.chwl.app.application.App
import com.chwl.app.application.GlobalHandleManager
import com.chwl.core.utils.LogUtils
import com.chwl.library.utils.ResUtil
import com.netease.nim.uikit.support.glide.GlideApp
import com.tencent.qgame.animplayer.AnimConfig
import com.tencent.qgame.animplayer.AnimView
import com.tencent.qgame.animplayer.inter.IAnimListener
import com.tencent.qgame.animplayer.inter.IFetchResource
import com.tencent.qgame.animplayer.mix.Resource
import com.tencent.qgame.animplayer.util.ScaleType
object CpUtils {
fun getHeadSvga(level: Int) : String {
return "svga/cp_list_head_$level.svga"
}
fun getUserInfoAnim(level: Int) : String? {
if (level < 3) return null
return "mp4/cp_userinfo_anim_$level.mp4"
}
var flags = arrayListOf(
R.drawable.ic_user_info_cp_avatar_flag_0,
R.drawable.ic_user_info_cp_avatar_flag_1,
R.drawable.ic_user_info_cp_avatar_flag_2,
R.drawable.ic_user_info_cp_avatar_flag_3,
R.drawable.ic_user_info_cp_avatar_flag_4,
R.drawable.ic_user_info_cp_avatar_flag_5,
)
var levels = arrayListOf(
R.drawable.ic_cp_list_level_0,
R.drawable.ic_cp_list_level_1,
R.drawable.ic_cp_list_level_2,
R.drawable.ic_cp_list_level_3,
R.drawable.ic_cp_list_level_4,
R.drawable.ic_cp_list_level_5,
)
var levelBgs = arrayListOf(
R.drawable.transparent_draw,
R.drawable.ic_cp_level_up_bg_1,
R.drawable.ic_cp_level_up_bg_2,
R.drawable.ic_cp_level_up_bg_3,
R.drawable.ic_cp_level_up_bg_4,
R.drawable.ic_cp_level_up_bg_5
)
var cpLevelUpStr = arrayListOf(
R.string.Sweet_Duo,
R.string.Dynamic_Duo,
R.string.Ldeal_Duo,
R.string.Dream_Duo,
R.string.Perfect_Duo,
R.string.Divine_Duo
)
fun getFlag(level: Int) : Int{
return flags.getOrNull(level)?:R.drawable.ic_user_info_cp_avatar_flag_0
}
fun getLevelImg(level: Int) : Int{
return levels.getOrNull(level)?:R.drawable.ic_cp_list_level_0
}
fun getCpLevelUpTextBg(level: Int) : Int{
return levelBgs.getOrNull(level)?:R.drawable.ic_cp_level_up_bg_1
}
fun getCpLevelUpStr(level: Int) : String{
return ResUtil.getString(cpLevelUpStr.getOrNull(level)?:R.string.Sweet_Duo)
}
fun downLoadAvatar(url:String?, onResourceReady:(resource: Bitmap?)->Unit) {
if (url.isNullOrEmpty()) return
try {
val futureTarget = RequestFutureTarget<Bitmap>(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
GlideApp.with(App.instance())
.asBitmap()
.circleCrop()
.load(url)
.addListener(object : RequestListener<Bitmap?> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap?>?, isFirstResource: Boolean): Boolean {
onResourceReady(null)
return true
}
override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap?>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
onResourceReady(resource)
return true
}
})
.into(futureTarget)
.get()
} catch (e: Exception) {
}
}
fun loadVap(animView: AnimView, url :String?, imgUrlMap: HashMap<String,String>?=null , textMap: HashMap<String,String>?=null) {
if (url == null) return
animView.visibility = View.VISIBLE
var index = 0
val bitmapMap = hashMapOf<String,Bitmap?>()
if (!imgUrlMap.isNullOrEmpty()){
imgUrlMap.keys.forEach { key ->
downLoadAvatar(imgUrlMap[key]) { resource ->
index++
bitmapMap[key] = resource
if (index == imgUrlMap.keys.size){
animView.setFetchResource(object : IFetchResource {
override fun fetchImage(resource: Resource, result: (Bitmap?) -> Unit) {
if (bitmapMap.isEmpty()) {
result(null)
} else {
var bitmap : Bitmap?=null
bitmapMap.keys.forEach {
if (resource.tag == it){
bitmap = bitmapMap[it]
}
}
result(bitmap)
}
}
override fun fetchText(resource: Resource, result: (String?) -> Unit) {
if (textMap.isNullOrEmpty()) {
result(null)
} else {
var text = ""
textMap.keys.forEach {
if (resource.tag == it){
text = textMap[it].toString()
}
}
result(text)
}
}
override fun releaseResource(resources: List<Resource>) {
resources?.forEach {
it?.bitmap?.recycle()
}
}
})
LogUtils.d(" animViewSetAnimListener startPlay url = $url")
animView.startPlay(animView.context.assets, url)
}
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,22 @@
package com.chwl.app.ui.utils
import com.chwl.app.R
object VipUtil {
val vipIcons = arrayListOf(
R.drawable.vip_center_identification_vipidentity_lv1,
R.drawable.vip_center_identification_vipidentity_lv2,
R.drawable.vip_center_identification_vipidentity_lv3,
R.drawable.vip_center_identification_vipidentity_lv4,
R.drawable.vip_center_identification_vipidentity_lv5,
R.drawable.vip_center_identification_vipidentity_lv6,
R.drawable.vip_center_identification_vipidentity_lv7,
R.drawable.vip_center_identification_vipidentity_lv8,
R.drawable.vip_center_identification_vipidentity_lv9
)
fun getVipIcon(level: Int) {
vipIcons.getOrNull(level)?:R.drawable.vip_center_identification_vipidentity_lv1
}
}

View File

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

View File

@@ -0,0 +1,352 @@
package com.chwl.app.ui.widget
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.chwl.app.R
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.app.ui.utils.SoftPool
import com.chwl.core.gift.bean.BonsellaJoinAttack
import com.chwl.core.gift.bean.GiftMultiReceiverInfo
import com.chwl.core.gift.bean.GiftType
import com.chwl.core.utils.LogUtils
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.UiUtils
import java.util.LinkedList
class BonsellaJoinAttackLayout @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes){
private val showingList = LinkedList<BonsellaJoinAttack>()
private val waitingList = LinkedList<BonsellaJoinAttack>()
private val comboMap = linkedMapOf<BonsellaJoinAttack, View>()
private val cacheView = SoftPool<View>(2)
private val inflater = LayoutInflater.from(context)
private val handle = Handler(Looper.getMainLooper()) {
if (it.what == 1) {
viewOut(it.obj as? BonsellaJoinAttack, false)
}
true
}
init {
if(isInEditMode){
inflater.inflate(R.layout.item_bonsella_join_attack_view, this, true)
inflater.inflate(R.layout.item_bonsella_join_attack_view, this, true)
}
orientation = VERTICAL
}
/**
* 创建
*/
private fun getComboChildView(): View {
val view = cacheView.acquire {
inflater.inflate(R.layout.item_bonsella_join_attack_view, this, false)
}.apply {
createViewHolder(this)
isVisible = true
}
return view
}
/**
* add data
*/
fun add(bonsellaJoinAttack: BonsellaJoinAttack?) {
//没有绑定之前不能添加
if (!isAttachedToWindow) {
return
}
if (bonsellaJoinAttack == null) {
return
}
var addToWaiting = true
for (comboInfo in showingList) {
if(comboInfo.sentUserid == bonsellaJoinAttack.sentUserid && comboInfo.giftId == bonsellaJoinAttack.giftId){
comboInfo.giftNumber = bonsellaJoinAttack.giftNumber
comboInfo.comboCount = bonsellaJoinAttack.comboCount
comboInfo.receiverNumber = bonsellaJoinAttack.receiverNumber
updateNum(comboInfo)
addToWaiting = false
}
}
for (comboInfo in waitingList) {
if(comboInfo.sentUserid == bonsellaJoinAttack.sentUserid && comboInfo.giftId == bonsellaJoinAttack.giftId){
comboInfo.giftNumber = bonsellaJoinAttack.giftNumber
comboInfo.comboCount = bonsellaJoinAttack.comboCount
comboInfo.receiverNumber = bonsellaJoinAttack.receiverNumber
addToWaiting = false
}
}
if(addToWaiting){
waitingList.add(bonsellaJoinAttack)
}
showNext()
}
/**
* 更新数量
*/
private fun updateNum(bonsellaJoinAttack: BonsellaJoinAttack) {
val view = comboMap[bonsellaJoinAttack] ?: return
val viewHolder = getViewHolder(view)
viewHolder?.refreshNum(bonsellaJoinAttack, true)
handle.removeMessages(1, bonsellaJoinAttack)
handle.sendMessageDelayed(Message.obtain(handle, 1, bonsellaJoinAttack), COMBO_STAY_TIME * 1000L)
}
/**
* 显示下一个
*/
private fun showNext() {
if(waitingList.isEmpty()){
return
}
val comboChildView = getComboChildView()
addView(comboChildView,0)
val giftComboInfo = waitingList.remove()
showingList.add(giftComboInfo)
comboMap[giftComboInfo] = comboChildView
val viewHolder = getViewHolder(comboChildView)
viewHolder?.showUi(giftComboInfo)
viewAnimationIn(comboChildView)
handle.sendMessageDelayed(Message.obtain(handle, 1, giftComboInfo), COMBO_STAY_TIME * 1000L)
if(showingList.size > MAX_SHOWING){
handle.removeMessages(1, showingList[0])
viewOut(showingList.remove(), true)
return
}
}
/**
* 移除动画
*/
private fun viewOut(bonsellaJoinAttack: BonsellaJoinAttack?, isDirectRemove: Boolean) {
bonsellaJoinAttack ?: return
val comboView = comboMap.remove(bonsellaJoinAttack) ?: return
val runnable = {
val viewHolder = getViewHolder(comboView)
viewHolder?.clear()
if(!isDirectRemove){
showingList.remove(bonsellaJoinAttack)
}
removeView(comboView)
cacheView.release(comboView)
showNext()
}
if(isDirectRemove){
comboView.isGone = true
post(runnable)
}else{
val animOut = AnimationUtils.loadAnimation(context, R.anim.alpha_out)
animOut.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
post(runnable)
}
override fun onAnimationRepeat(animation: Animation?) {
}
})
comboView.startAnimation(animOut)
}
}
/**
* 飞入动画
*/
private fun viewAnimationIn(view: View) {
view.alpha = 1f
val animIn = AnimationUtils.loadAnimation(context,if (UiUtils.isRtl(context)) R.anim.left_to_right else R.anim.right_to_left )
// animIn.fillAfter = true
// animIn.isFillEnabled = true
view.startAnimation(animIn)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if(isInEditMode) return
// RoomMsgManager.addCustomMsgListener(this)
}
fun onRoomCustomMsg(giftInfo: GiftMultiReceiverInfo?) {
LogUtils.d(" GiftComboLayout onRoomCustomMsg " )
if (giftInfo==null) return
if (giftInfo.comboCount == 0) return
if (giftInfo.gift != null && giftInfo.gift.giftType == GiftType.GIFT_TYPE_NORMAL || giftInfo.gift.giftType == GiftType.GIFT_TYPE_SUPER_LUCKY || giftInfo.gift.giftType == GiftType.GIFT_TYPE_LUCKY_24) {
val comboInfo = BonsellaJoinAttack().apply {
giftId = giftInfo.giftId
sentUserid = giftInfo.uid
sentUserName = giftInfo.nick
sentAvatar = giftInfo.avatar
receiverUserName = giftInfo.targetUsers?.getOrNull(0)?.nick?:""
receiverNumber = giftInfo.targetUsers?.size?: giftInfo.targetUids?.size?: 1
giftNumber = giftInfo.giftNum
giftImgUrl = giftInfo.gift?.giftUrl?:""
comboCount = giftInfo.comboCount
isMulti = giftInfo.isMulti
}
add(comboInfo)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
handle.removeCallbacksAndMessages(null)
// RoomMsgManager.removeCustomMsgListener(this)
}
private fun createViewHolder(view: View) {
getViewHolder(view) ?: ViewHolder(view)
}
private fun getViewHolder(view: View): ViewHolder? {
return view.tag as? ViewHolder
}
private inner class ViewHolder(view: View) {
var tvNumber: AppCompatTextView = view.findViewById(R.id.giftComboNumber)
var ivGift: ImageView = view.findViewById(R.id.giftImg)
var tvNick: TextView = view.findViewById(R.id.sentUserName)
var tvReceiverNick: TextView = view.findViewById(R.id.receiverUserName)
var ivAvatar: ImageView = view.findViewById(R.id.sentUserAvatar)
var ivLayoutBg: ImageView = view.findViewById(R.id.layoutBg)
init {
view.tag = this
}
@SuppressLint("SetTextI18n")
fun showUi(bonsellaJoinAttack: BonsellaJoinAttack) {
if (UiUtils.isRtl(context)){
ivLayoutBg.scaleX = -1f
}
refreshNum(bonsellaJoinAttack)
tvNick.text = bonsellaJoinAttack.sentUserName
if (bonsellaJoinAttack.receiverNumber == 1) {
tvReceiverNick.text = bonsellaJoinAttack.receiverUserName
} else {
if (bonsellaJoinAttack.isMulti) {
tvReceiverNick.text = ResUtil.getString(R.string.Multiplayer)
} else {
tvReceiverNick.text = ResUtil.getString(R.string.All_mic)
}
}
// tvNumber.text = "x${giftComboInfo.giftNumber * giftComboInfo.receiverNumber * giftComboInfo.comboCount}"
ImageLoadUtils.loadImage(ivGift, bonsellaJoinAttack.giftImgUrl)
ImageLoadUtils.loadImage(ivAvatar, bonsellaJoinAttack.sentAvatar)
ivAvatar.tag = bonsellaJoinAttack
}
/**
* 用于刷新数量
*/
@SuppressLint("SetTextI18n")
fun refreshNum(bonsellaJoinAttack: BonsellaJoinAttack, isAnim: Boolean = false) {
val num = bonsellaJoinAttack.giftNumber * bonsellaJoinAttack.receiverNumber * bonsellaJoinAttack.comboCount
if(num == 0){
tvNumber.isVisible = false
return
}
// val old = tvNumber.tag as? Int
// //兼容上一个比下一个数还要大
// if (old != null && old > num) {
// return
// }
tvNumber.isVisible = true
tvNumber.tag = num
tvNumber.text = "x$num"
if (isAnim) {
tvNumber.animate().cancel()
tvNumber.requestLayout()
post {
val scaleUp: ObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(
tvNumber,
PropertyValuesHolder.ofFloat(SCALE_X, 1f, 1.3f, 1f),
PropertyValuesHolder.ofFloat(SCALE_Y, 1f, 1.3f, 1f)
)
scaleUp.setDuration(100)
scaleUp.start()
}
}
}
/**
* 清空UI数据
*/
fun clear() {
LogUtils.d(" ComboView clear -- clear ")
tvNumber.animate().cancel()
tvNumber.scaleX = 1f
tvNumber.scaleY = 1f
tvNumber.tag = 0
ivAvatar.tag = null
}
}
companion object {
/**
* 最大显示个数
*/
const val MAX_SHOWING = 2
/**
* 连击停留时间
*/
const val COMBO_STAY_TIME = 5
}
// override fun onClick(v: View) {
// val giftComboInfo = v.tag as? GiftComboInfo ?: return
// val sendUid = giftComboInfo.senderUid
// if (sendUid == 0L) {
// return
// }
// RoomUserInfoDialog.show(sendUid)
// }
}

View File

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

View File

@@ -1,5 +1,16 @@
package com.chwl.app.ui.widget;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_COUNTRY;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_CP;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_CUSTOM;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_LUCKY;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_NOBLE;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_NORMAL;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_SING_ROOM;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_SUPER_LUCKY;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_SUPER_LUCKY_24;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_WEEK;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
@@ -35,9 +46,12 @@ import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.ui.adapter.StarWeekAdapter;
import com.chwl.app.ui.webview.DialogWebViewActivity;
import com.chwl.app.vip.VipCenterActivity;
import com.chwl.core.UriProvider;
import com.chwl.core.gift.bean.LuckyBagNoticeInfo;
import com.chwl.core.gift.bean.SimpleUserInfo;
import com.chwl.core.gift.bean.TagsInfo;
import com.chwl.core.home.bean.TabInfo;
import com.chwl.core.room.anotherroompk.ShowUserInfoDialogEvent;
import com.chwl.core.utils.extension.StringExtensionKt;
import com.example.lib_utils.UiUtils;
@@ -64,7 +78,6 @@ import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.ui.widget.recyclerview.decoration.VerticalDecoration;
import com.chwl.app.utils.RegexUtil;
import com.chwl.app.utils.SpannableBuilder;
import com.chwl.app.vip.VipMainActivity;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.bean.RoomQueueInfo;
import com.chwl.core.gift.GiftModel;
@@ -438,13 +451,16 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
sendGiftButton.setOnClickListener(this);
giftNumLayout = root.findViewById(R.id.gift_number_layout);
giftNumLayout.setOnClickListener(this);
List<GiftTab> tabInfoList = new ArrayList<>();
tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NORMAL, ResUtil.getString(R.string.ui_widget_giftdialog_01), ResUtil.getString(R.string.ui_widget_giftdialog_02)));
tabInfoList.add(new GiftTab(GiftIndicator.TYPE_LUCKY, ResUtil.getString(R.string.ui_widget_giftdialog_03), ResUtil.getString(R.string.ui_widget_giftdialog_04)));
tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NOBLE, ResUtil.getString(R.string.ui_widget_giftdialog_05), ResUtil.getString(R.string.ui_widget_giftdialog_06)));
tabInfoList.add(new GiftTab(GiftIndicator.TYPE_WEEK, ResUtil.getString(R.string.ui_widget_giftdialog_07), ResUtil.getString(R.string.ui_widget_giftdialog_08)));
List<GiftTab> tabInfoList = updateTabs();
// MARK: 获取到新 API 数据后tab 按这里的方式更新
// List<GiftTab> tabInfoList = new ArrayList<>();
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NORMAL, ResUtil.getString(R.string.ui_widget_giftdialog_01), ResUtil.getString(R.string.ui_widget_giftdialog_02)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_LUCKY, ResUtil.getString(R.string.ui_widget_giftdialog_03), ResUtil.getString(R.string.ui_widget_giftdialog_04)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_NOBLE, ResUtil.getString(R.string.ui_widget_giftdialog_05), ResUtil.getString(R.string.ui_widget_giftdialog_06)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_WEEK, ResUtil.getString(R.string.ui_widget_giftdialog_07), ResUtil.getString(R.string.ui_widget_giftdialog_08)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_DRAW_GIFT, ResUtil.getString(R.string.ui_widget_giftdialog_09), ResUtil.getString(R.string.ui_widget_giftdialog_010)));
tabInfoList.add(new GiftTab(GiftIndicator.TYPE_SING_ROOM, ResUtil.getString(R.string.ui_widget_giftdialog_hot), ResUtil.getString(R.string.ui_widget_giftdialog_hot)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_SING_ROOM, ResUtil.getString(R.string.ui_widget_giftdialog_hot), ResUtil.getString(R.string.ui_widget_giftdialog_hot)));
// tabInfoList.add(new GiftTab(GiftIndicator.TYPE_KNAP, ResUtil.getString(R.string.ui_widget_giftdialog_011), ResUtil.getString(R.string.ui_widget_giftdialog_012)));
giftIndicator = root.findViewById(R.id.gift_indicator);
giftIndicator.initTab(
@@ -503,24 +519,30 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
if (giftId == 0) {
// 更新所有礼物
giftIndicator.setPosition(GiftIndicator.TYPE_NORMAL);
giftIndicator.setPosition(TYPE_NORMAL);
updateGiftView(giftIndicator.getCurrrentType());
} else {
int indicatorType = GiftIndicator.TYPE_NORMAL;
int indicatorType = TYPE_NORMAL;
GiftInfo giftInfo = GiftModel.get().findGiftInfoById(giftId);
if (giftInfo != null) {
switch (giftInfo.getGiftType()) {
case GiftType.GIFT_TYPE_NORMAL:
indicatorType = GiftIndicator.TYPE_NORMAL;
indicatorType = TYPE_NORMAL;
break;
case GiftType.GIFT_TYPE_LUCKY:
indicatorType = GiftIndicator.TYPE_LUCKY;
break;
case GiftType.GIFT_TYPE_SUPER_LUCKY:
indicatorType = TYPE_SUPER_LUCKY;
break;
case GiftType.GIFT_TYPE_VIP:
indicatorType = GiftIndicator.TYPE_NOBLE;
indicatorType = TYPE_NOBLE;
break;
case GiftType.GIFT_TYPE_COUNTRY:
indicatorType = TYPE_COUNTRY;
break;
case GiftType.GIFT_TYPE_WEEK_STAR:
indicatorType = GiftIndicator.TYPE_WEEK;
indicatorType = TYPE_WEEK;
break;
}
}
@@ -581,6 +603,42 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
});
}
private List<GiftTab> updateTabs() {
List<GiftTab> tabInfoList = new ArrayList<>();
if (GiftModel.get().getTabList() != null) {
for (TagsInfo info: GiftModel.get().getTabList()) {
tabInfoList.add(new GiftTab(swithGiftTypeToTabType(info), info.tagName(), info.tagName()));
}
}
return tabInfoList;
}
private int swithGiftTypeToTabType(TagsInfo info) {
switch (info.tagGiftType()) {
case GiftType.GIFT_TYPE_NORMAL:
return TYPE_NORMAL;
case GiftType.GIFT_TYPE_LUCKY:
return TYPE_LUCKY;
case GiftType.GIFT_TYPE_SUPER_LUCKY:
return TYPE_SUPER_LUCKY;
case GiftType.GIFT_TYPE_VIP:
return TYPE_NOBLE;
case GiftType.GIFT_TYPE_WEEK_STAR:
return TYPE_WEEK;
case GiftType.GIFT_TYPE_COUNTRY:
return TYPE_COUNTRY;
case GiftType.GIFT_TYPE_SINGLE_ROOM:
return TYPE_SING_ROOM;
case GiftType.GIFT_TYPE_LUCKY_24:
return TYPE_SUPER_LUCKY_24;
case GiftType.GIFT_TYPE_CP:
return TYPE_CP;
case GiftType.GIFT_TYPE_CUSTOM:
return TYPE_CUSTOM;
}
return TYPE_NORMAL;
}
private void showLoadingAnimation() {
Animation rotateAnimation = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f,
@@ -656,31 +714,39 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
List<GiftInfo> nobleGiftInfos = getNobleGiftInfos();
if (position == GiftIndicator.TYPE_KNAP) {
currentGiftInfoList = GiftModel.get().getKnapList();
} else if (position == GiftIndicator.TYPE_NOBLE) {
} else if (position == TYPE_NOBLE) {
currentGiftInfoList = nobleGiftInfos;
} else if (position == GiftIndicator.TYPE_NORMAL) {
} else if (position == TYPE_NORMAL) {
currentGiftInfoList = getNormalGiftInfos();
} else if (position == GiftIndicator.TYPE_LUCKY) {
currentGiftInfoList = getLuckyGiftInfos();
} else if (position == GiftIndicator.TYPE_WEEK) {
} else if (position == TYPE_WEEK) {
currentGiftInfoList = getWeekStarGiftInfos();
} else if (position == GiftIndicator.TYPE_DRAW_GIFT) {
currentGiftInfoList = getDrawGiftInfos();
} else if (position == GiftIndicator.TYPE_SING_ROOM) {
currentGiftInfoList = getSingleRoomGiftInfos();
} else if (position == TYPE_SUPER_LUCKY) {
currentGiftInfoList = getSuperLuckyGiftInfos();
} else if (position == TYPE_COUNTRY) {
currentGiftInfoList = getCountryGiftInfos();
}else if (position == TYPE_CP) {
currentGiftInfoList = getCpGiftInfos();
}else if (position == TYPE_CUSTOM) {
currentGiftInfoList = getCustomGiftInfos();
}
// 有贵族礼物才显示贵族礼物的tab
if (ListUtils.isListEmpty(nobleGiftInfos)) {
giftIndicator.hidePosition(GiftIndicator.TYPE_NOBLE);
giftIndicator.hidePosition(TYPE_NOBLE);
} else {
giftIndicator.showPosition(GiftIndicator.TYPE_NOBLE);
giftIndicator.showPosition(TYPE_NOBLE);
}
// 有塗鴉礼物才显示塗鴉礼物的tab
if (ListUtils.isListEmpty(getDrawGiftInfos())) {
giftIndicator.hidePosition(GiftIndicator.TYPE_DRAW_GIFT);
} else {
giftIndicator.showPosition(GiftIndicator.TYPE_DRAW_GIFT);
}
// if (ListUtils.isListEmpty(getDrawGiftInfos())) {
// giftIndicator.hidePosition(GiftIndicator.TYPE_DRAW_GIFT);
// } else {
// giftIndicator.showPosition(GiftIndicator.TYPE_DRAW_GIFT);
// }
//是否背包礼物
final boolean isKnap = (position == GiftIndicator.TYPE_KNAP);
initEasyPop(isKnap);
@@ -690,9 +756,11 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
// tvGiftValue.setVisibility(View.VISIBLE);
showEmptyView();
} else if (position == GiftIndicator.TYPE_LUCKY ||
position == GiftIndicator.TYPE_WEEK ||
position == TYPE_SUPER_LUCKY ||
position == TYPE_WEEK ||
position == GiftIndicator.TYPE_SING_ROOM ||
position == GiftIndicator.TYPE_DRAW_GIFT) {
position == GiftIndicator.TYPE_DRAW_GIFT ||
position == TYPE_COUNTRY) {
showEmptyView();
updateWeekStarDesc();
isShowDrawGiftModel = false;
@@ -707,7 +775,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
if (currentGiftInfo.isSendMsg()) {
etSendMessage.setVisibility(View.VISIBLE);
}
pagerList = beanTransformVm(context, currentGiftInfoList, isKnap, position == GiftIndicator.TYPE_WEEK ? 4 : 8, currentGiftInfo);
pagerList = beanTransformVm(context, currentGiftInfoList, isKnap, position == TYPE_WEEK ? 4 : 8, currentGiftInfo);
setGridViewData(pagerList);
if (isKnap) {
// tvGiftValue.setVisibility(View.VISIBLE);
@@ -723,10 +791,13 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
updateWeekStarDesc();
updateDrawGift();
giftIndicator.post(() -> {
if (position < GiftIndicator.TYPE_WEEK) {
giftIndicator.fullScroll(View.FOCUS_LEFT);
boolean isRTL = UiUtils.INSTANCE.isRtl(getContext());
// if (position < TYPE_WEEK) { GiftModel.get().getTabList().size()/2;
int centerIndex = GiftModel.get().getTabList().size()/2;
if (position < centerIndex) {
giftIndicator.fullScroll(isRTL ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
} else {
giftIndicator.fullScroll(View.FOCUS_RIGHT);
giftIndicator.fullScroll(isRTL ? View.FOCUS_LEFT : View.FOCUS_RIGHT);
}
});
}
@@ -797,7 +868,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
private void updateWeekStarDesc() {
if (giftIndicator.getCurrrentType() == GiftIndicator.TYPE_WEEK) {
if (giftIndicator.getCurrrentType() == TYPE_WEEK) {
flLuckyDesc.setVisibility(View.GONE);
llStarWeek.setVisibility(View.GONE);
mStarWeekBanner.setVisibility(View.VISIBLE);
@@ -1116,6 +1187,11 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
return giftInfos;
}
private List<TagsInfo> getAllTabsAndGiftInfos() {
List<TagsInfo> tagsInfos = null;
return tagsInfos;
}
private List<GiftInfo> getNormalGiftInfos() {
List<GiftInfo> giftInfos = loadGiftInfoList();
List<GiftInfo> infos = new ArrayList<>();
@@ -1152,6 +1228,29 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
GiftType.GIFT_TYPE_SINGLE_ROOM);
}
private List<GiftInfo> getSuperLuckyGiftInfos() {
return GiftModel.get().getGiftInfosByType(
String.valueOf(AvRoomDataManager.get().getRoomUid()),
GiftType.GIFT_TYPE_SUPER_LUCKY);
}
private List<GiftInfo> getCountryGiftInfos() {
return GiftModel.get().getGiftInfosByType(
String.valueOf(AvRoomDataManager.get().getRoomUid()),
GiftType.GIFT_TYPE_COUNTRY);
}
private List<GiftInfo> getCpGiftInfos() {
return GiftModel.get().getGiftInfosByType(
String.valueOf(AvRoomDataManager.get().getRoomUid()),
GiftType.GIFT_TYPE_CP);
}
private List<GiftInfo> getCustomGiftInfos() {
return GiftModel.get().getGiftInfosByType(
String.valueOf(AvRoomDataManager.get().getRoomUid()),
GiftType.GIFT_TYPE_CUSTOM);
}
private List<GiftInfo> getNobleGiftInfos() {
return GiftModel.get().getGiftInfoList(GiftType.GIFT_TYPE_VIP);
}
@@ -1394,7 +1493,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
showEasyPopup();
break;
case R.id.iv_open_noble:
VipMainActivity.start(context);
VipCenterActivity.start(context);
//进入贵族中心埋点
HashMap<String, Object> map = new HashMap<>(5);
map.put(IReportConstants.PAYPAGE_TYPE, IReportConstants.THREE);
@@ -1449,10 +1548,10 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
if (needShowLoading) showLoadingView();
int currentType = giftIndicator.getCurrrentType();
switch (currentType) {
case GiftIndicator.TYPE_NORMAL:
case TYPE_NORMAL:
case GiftIndicator.TYPE_LUCKY:
case GiftIndicator.TYPE_NOBLE:
case GiftIndicator.TYPE_WEEK:
case TYPE_NOBLE:
case TYPE_WEEK:
String roomUid = null;
if (isInRoom) {
if (AvRoomDataManager.get().getRoomUid() > 0) {
@@ -1702,4 +1801,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
void onFail();
}
public void sendGift(){
sendGiftButton.performClick();
}
}

View File

@@ -4,13 +4,16 @@ import static com.chwl.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_DRAGON_BA
import static com.chwl.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_DRAGON_BAR_CANCEL;
import static com.chwl.core.manager.RoomEvent.DRAGON_BAR_CANCEL;
import static com.chwl.library.utils.ResUtil.getString;
import static com.netease.nim.uikit.common.util.log.LogUtil.log;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -21,6 +24,8 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialog;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.recyclerview.widget.GridLayoutManager;
@@ -28,6 +33,13 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.utils.AvatarHelper;
import com.chwl.core.vip.bean.UserVipInfo;
import com.chwl.library.download.DownloadException;
import com.chwl.library.download.DownloadManager;
import com.chwl.library.download.DownloadRequest;
import com.chwl.library.download.DownloadTask;
import com.chwl.library.download.FileDownloadListener;
import com.chwl.library.utils.PathHelper;
import com.chwl.library.widget.SVGAView;
import com.google.android.flexbox.FlexboxLayout;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
@@ -92,11 +104,16 @@ import com.chwl.library.net.rxnet.callback.CallBack;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.config.BasicConfig;
import com.tencent.qgame.animplayer.AnimConfig;
import com.tencent.qgame.animplayer.AnimView;
import com.tencent.qgame.animplayer.inter.IAnimListener;
import com.tencent.qgame.animplayer.util.ScaleType;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -141,6 +158,7 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
private AppCompatImageView mIvUserLevel;
private AppCompatImageView mIvUserCharm;
private ImageView ivUserCardWear;
private AnimView ivUserCardWearMP4;
private TextView tvFamilyNameLabel;
private TextView tvFamilyName;
private FlexboxLayout flexbox;
@@ -258,6 +276,42 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
mIvUserCharm = findViewById(R.id.iv_user_charm);
ivUserCardWear = findViewById(R.id.iv_user_card_wear);
ivUserCardWearMP4 = findViewById(R.id.iv_user_card_wear_mp4);
ivUserCardWearMP4.setScaleType(ScaleType.CENTER_CROP);
ivUserCardWearMP4.setLoop(Integer.MAX_VALUE);
ivUserCardWearMP4.setAnimListener(new IAnimListener() {
@Override
public boolean onVideoConfigReady(@NonNull AnimConfig animConfig) {
return true;
}
@Override
public void onVideoStart() {
log( "onVideoStart: ");
}
@Override
public void onVideoRender(int i, @Nullable AnimConfig animConfig) {
}
@Override
public void onVideoComplete() {
log( "onVideoComplete: ");
}
@Override
public void onVideoDestroy() {
}
@Override
public void onFailed(int i, @Nullable String s) {
}
});
tvFamilyNameLabel = (TextView) findViewById(R.id.tv_family_name_label);
tvFamilyName = (TextView) findViewById(R.id.tv_family_name);
tvSelectHim = findViewById(R.id.tv_select_him);
@@ -543,9 +597,11 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
//资料卡装扮
if (!TextUtils.isEmpty(userInfo.getUserInfoCardPic())) {
ImageLoadUtils.loadImage(context, userInfo.getUserInfoCardPic(), ivUserCardWear);
drawVAPEffect(userInfo.getUserInfoCardPic());
// drawVAPEffect("https://image.pekolive.com/v7.mp4");
} else {
ivUserCardWear.setImageDrawable(null);
ivUserCardWearMP4.setVisibility(View.GONE);
}
if (null != findHimView) {
@@ -602,6 +658,23 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
}
}
private void drawVAPEffect(String url) {
String filePath = PathHelper.INSTANCE.generateResourcesFilePath(url);
DownloadRequest request = DownloadRequest.Companion.build(url, filePath, "gift_effect_download", null, 60000L);
DownloadManager.INSTANCE.download(request, new FileDownloadListener() {
@Override
public void onDownloadCompleted(@NonNull DownloadTask task) {
String path = task.getRequest().getPath();
ivUserCardWearMP4.startPlay(new File(path));
}
@Override
public void onDownloadError(@NonNull DownloadException exception) {
ImageLoadUtils.loadImage(context, userInfo.getUserInfoCardPic(), ivUserCardWear);
}
});
}
private void copyName() {
try {
ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -677,7 +750,8 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
private void updateNobleView() {
// 防止访问数据库和网络同时刷新出现图标跳动
NobleInfo nobleInfo = userInfo.getNobleInfo();
// NobleInfo nobleInfo = userInfo.getNobleInfo();
UserVipInfo vipInfo = userInfo.getUserVipInfoVO();
HeadWearInfo userHeadwear = userInfo.getUserHeadwear();
boolean havaHead = false;
// 设置普通人
@@ -688,31 +762,46 @@ public class UserInfoDialog extends AppCompatDialog implements View.OnClickListe
AvatarHelper.loadAvatarFrame(ivAvatarHeadWear, avatarFrame, userHeadwear.getType());
}
}
if (nobleInfo == null || TextUtils.isEmpty(nobleInfo.getCardBg())) {
//如果没贵族信息,就加载头像作为背景
if (vipInfo != null && !vipInfo.getUserCardBG().isEmpty()) {
// findViewById(R.id.transition_mask).setVisibility(View.GONE);
ivAvatarBg.setScaleType(ImageView.ScaleType.MATRIX);
ImageLoadUtils.loadImage(
context,
vipInfo.getUserCardBG().replace("\n",""),
ivAvatarBg,
R.drawable.default_avatar
);
} else {
if (avatarBg == null || !avatarBg.equals(userInfo.getAvatar())) {
avatarBg = userInfo.getAvatar();
ImageLoadUtils.loadImageWithBlur(context, userInfo.getAvatar(), ivAvatarBg, 10, 1);
}
return;
}
// 卡片背景
if (!TextUtils.isEmpty(nobleInfo.getCardBg()) && !topBg.equals(nobleInfo.getCardBg())) {
topBg = nobleInfo.getCardBg();
NobleUtil.loadResource(nobleInfo.getCardBg(), ivAvatarBg, R.drawable.bg_user_info_dialog_top);
}
if (!TextUtils.isEmpty(nobleInfo.getHeadWear())) {
// 头饰
if (!havaHead) {
NobleUtil.loadResource(nobleInfo.getHeadWear(), ivAvatarHeadWear);
}
}
if (!TextUtils.isEmpty(nobleInfo.getBadge())) {
// 勋章
ivBadge.setVisibility(View.VISIBLE);
NobleUtil.loadResource(nobleInfo.getBadge(), ivBadge);
}
// if (nobleInfo == null || TextUtils.isEmpty(nobleInfo.getCardBg())) {
// //如果没贵族信息,就加载头像作为背景
// if (avatarBg == null || !avatarBg.equals(userInfo.getAvatar())) {
// avatarBg = userInfo.getAvatar();
// ImageLoadUtils.loadImageWithBlur(context, userInfo.getAvatar(), ivAvatarBg, 10, 1);
// }
// return;
// }
// // 卡片背景
// if (!TextUtils.isEmpty(nobleInfo.getCardBg()) && !topBg.equals(nobleInfo.getCardBg())) {
// topBg = nobleInfo.getCardBg();
// NobleUtil.loadResource(nobleInfo.getCardBg(), ivAvatarBg, R.drawable.bg_user_info_dialog_top);
// }
// if (!TextUtils.isEmpty(nobleInfo.getHeadWear())) {
// // 头饰
// if (!havaHead) {
// NobleUtil.loadResource(nobleInfo.getHeadWear(), ivAvatarHeadWear);
// }
// }
// if (!TextUtils.isEmpty(nobleInfo.getBadge())) {
// // 勋章
// ivBadge.setVisibility(View.VISIBLE);
// NobleUtil.loadResource(nobleInfo.getBadge(), ivBadge);
// }
}

View File

@@ -14,7 +14,6 @@ import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import com.example.lib_utils.ktx.getColorById
import com.example.lib_utils.ktx.singleClick
import com.example.lib_utils.ktx.toStringRes
import com.example.lib_utils.spannable.SpannableTextBuilder
import com.chwl.app.R
import com.chwl.app.avroom.activity.AVRoomActivity
@@ -51,8 +50,7 @@ class AllServiceGiftLevelDialog : BaseDialog {
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)
val inflate = LayoutInflater.from(context).inflate(R.layout.dialog_gift_all_service_level, null)
setContentView(inflate.rootView)
setCancelable(true)
setCanceledOnTouchOutside(true)

View File

@@ -16,12 +16,12 @@ import android.widget.TextView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.chwl.app.vip.VipCenterActivity;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.chwl.app.R;
import com.chwl.library.common.util.Utils;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.vip.VipMainActivity;
import com.chwl.core.market_verify.MarketVerifyModel;
import com.chwl.core.room.event.FaceIsReadyEvent;
import com.chwl.core.room.face.DynamicFaceModel;
@@ -309,7 +309,7 @@ public class DynamicFaceDialog extends BottomSheetDialog
tvNormalTab.setSelected(true);
}
} else if (v.getId() == R.id.iv_open_noble) {
VipMainActivity.start(context);
VipCenterActivity.start(context);
}
}

View File

@@ -67,6 +67,28 @@ public class GiftIndicator extends LinearLayout {
*/
public static final int TYPE_SING_ROOM = 6;
/**
* 国家礼物
*/
public static final int TYPE_COUNTRY = 7;
/**
* 超级幸运礼物
*/
public static final int TYPE_SUPER_LUCKY = 8;
/**
* 超级幸运24礼物
*/
public static final int TYPE_SUPER_LUCKY_24 = 9;
/**
* cp礼物
*/
public static final int TYPE_CP = 10;
/**
* 定制礼物
*/
public static final int TYPE_CUSTOM = 11;
private List<GiftTab> tabList = new ArrayList<>();
@Getter

View File

@@ -16,7 +16,7 @@ import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IMeasu
* 博客: http://hackware.lucode.net
* Created by hackware on 2016/6/26.
*/
public class SimplePagerTitleView extends TextView implements IMeasurablePagerTitleView {
public class SimplePagerTitleView extends androidx.appcompat.widget.AppCompatTextView implements IMeasurablePagerTitleView {
protected int mSelectedColor;
protected int mNormalColor;

View File

@@ -0,0 +1,81 @@
package com.chwl.app.utils;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.animation.Animation;
public class GiftAnimUtil {
public static void showAnimation(View view) {
// 透明度从0到1
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", 1f, 1f);
fadeIn.setDuration(1000);
// 尺寸从0%到100%
ObjectAnimator scaleUp = ObjectAnimator.ofPropertyValuesHolder(
view,
PropertyValuesHolder.ofFloat(View.SCALE_X, 0f, 1.2f,1f),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 0f, 1.2f,1f)
);
scaleUp.setDuration(1000);
// 组合动画
AnimatorSet appearSet = new AnimatorSet();
appearSet.playTogether(fadeIn, scaleUp);
// // 设置动画结束监听器
// appearSet.addListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// // 显示动画结束后触发扩展动画
// expandAnimation(view);
// }
// });
// 开始显示动画
appearSet.start();
}
public static void expandAnimation(View view) {
// 尺寸从100%到120%
ObjectAnimator scaleExpand = ObjectAnimator.ofPropertyValuesHolder(
view,
PropertyValuesHolder.ofFloat(View.SCALE_X, 1f, 1.2f,1f),
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1f, 1.2f,1f)
);
scaleExpand.setDuration(500);
// 循环执行3秒
// scaleExpand.setRepeatCount(1);
// scaleExpand.setRepeatMode(ValueAnimator.RESTART);
// scaleExpand.setStartDelay(3000); // 确保在3秒后开始重复
// 设置动画结束监听器
// scaleExpand.addListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// // 扩展动画结束后触发退出动画
// fadeOutAnimation(view);
// }
// });
// 开始扩展动画
scaleExpand.start();
}
public static void fadeOutAnimation(View view) {
// 透明度从1到0
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);
fadeOut.setDuration(500);
// 开始退出动画
fadeOut.start();
}
}

View File

@@ -0,0 +1,108 @@
package com.chwl.app.utils
import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.Locale
import kotlin.math.roundToLong
/**
* @Author Vance
* Date2023/12/05 0005 13:59
*/
object NumberUtils {
private val df = DecimalFormat("0.##", DecimalFormatSymbols.getInstance(Locale.US))
private val df2 = DecimalFormat("###,##0.##", DecimalFormatSymbols.getInstance(Locale.US))
@JvmStatic
fun format(num:Long):String{
return format(num.toDouble())
}
@JvmStatic
fun format(num:Int):String{
return format(num.toLong())
}
@JvmStatic
fun format(num:Double):String{
val longValue = num.roundToLong()
return if(num < 10000){
if(num - num.toLong() > 0){
num.toString()
}else {
longValue.toString()
}
}else if(longValue < 1000000){
format(longValue, "K")
}else if(longValue < 1000000000){
format(longValue/1000, "M")
}else
format(longValue/1000000, "B")
}
@JvmStatic
fun format(numOfK:Long, suffix:String, roundUp:Boolean = true):String{
df.roundingMode = if(roundUp) RoundingMode.HALF_UP else RoundingMode.DOWN
return df.format(numOfK/1000.0)+suffix
}
/**
* 用逗号分隔
*/
@JvmStatic
@JvmOverloads
fun formatCommaSplit(number:Double, roundUp:Boolean = true):String {
df.roundingMode = if(roundUp) RoundingMode.HALF_UP else RoundingMode.DOWN
return df2.format(number)
}
@JvmStatic
fun formatCommaSplit(number:Long):String {
return df2.format(number)
}
@JvmStatic
@JvmOverloads
fun parseLong(str:String?, def:Long = 0):Long{
if(str.isNullOrEmpty()){
return def
}
return try {
str.toLong()
} catch (e: Exception) {
return def
}
}
@JvmStatic
@JvmOverloads
fun parseInt(str:String?, def:Int = 0):Int{
if(str.isNullOrEmpty()){
return def
}
return try {
str.toInt()
} catch (e: Exception) {
return def
}
}
@JvmStatic
@JvmOverloads
fun parseDouble(str:String?, def:Double = 0.0):Double{
if(str.isNullOrEmpty()){
return def
}
return try {
str.toDouble()
} catch (e: Exception) {
return def
}
}
}

View File

@@ -0,0 +1,81 @@
package com.chwl.app.utils
import com.chwl.app.application.GlobalHandleManager
import com.chwl.app.avroom.dialog.BaseRoomNotifyDialog
import com.chwl.app.avroom.dialog.RoomNotifyCpBindDialog
import com.chwl.app.avroom.dialog.RoomNotifyCpGiftDialog
import com.chwl.app.avroom.dialog.RoomNotifyLevelUpDialog
import com.chwl.app.avroom.dialog.RoomNotifyLuckGiftDialog
import com.chwl.core.gift.bean.CpMsgBean
import com.chwl.core.gift.bean.LuckyGiftMsgAllBean
import com.chwl.core.gift.bean.RoomNotifyDialogBean
import com.chwl.core.im.custom.bean.CustomAttachment
import java.util.LinkedList
object RoomNotifyManager {
private val queue = LinkedList<RoomNotifyDialogBean>()
private var dialog : BaseRoomNotifyDialog<*>?=null
fun addDialog(data : RoomNotifyDialogBean) {
queue.add(data)
showNextDialog()
}
private fun showNextDialog() {
if (dialog?.isShowing == true){
return
}
if (queue.isNotEmpty()) {
val data = queue.removeAt(0)
dialog = createDialog(data)
dialog?.mCallBack = object : BaseRoomNotifyDialog.CallBack {
override fun onHide() {
showNextDialog()
}
}
dialog?.showDialog()
}
}
private fun createDialog(bean: RoomNotifyDialogBean): BaseRoomNotifyDialog<*>?{
var dialog : BaseRoomNotifyDialog<*>? = null
val activity = GlobalHandleManager.get().activity ?: return null
if (bean.first == CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE) {
if (bean.second == CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_ROOM || bean.second == CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_ALL){
if (bean.data is LuckyGiftMsgAllBean){
dialog = RoomNotifyLuckGiftDialog(activity)
dialog.luckyGiftMsgBean = bean.data as LuckyGiftMsgAllBean
return dialog
}
}
} else if(bean.first == CustomAttachment.CP_FIRST){
if (bean.data is CpMsgBean){
if (bean.second == CustomAttachment.CP_SECOND_GIFT){
dialog = RoomNotifyCpGiftDialog(activity).apply {
cpMsgBean = bean.data as CpMsgBean
}
}else if (bean.second == CustomAttachment.CP_SECOND_UPGRADE){
dialog = RoomNotifyLevelUpDialog(activity).apply {
cpMsgBean = bean.data as CpMsgBean
}
}else if (bean.second == CustomAttachment.CP_SECOND_BIND){
dialog = RoomNotifyCpBindDialog(activity).apply {
cpMsgBean = bean.data as CpMsgBean
}
}
}
}
return dialog
}
fun clear() {
dialog?.clearDialog()
dialog = null
queue.clear()
}
}

View File

@@ -0,0 +1,62 @@
package com.chwl.app.utils
import androidx.core.util.Pools.Pool
import java.lang.ref.WeakReference
import java.util.LinkedList
/**
* @Author Vance
* Date2023/12/22 0022 14:26
*/
class WeakPool<T : Any>(private var maxPoolSize: Int):Pool<T> {
init {
if(maxPoolSize <= 0){
maxPoolSize = 8
}
}
private var mPool = LinkedList<WeakReference<T>>()
fun acquire(getIfEmpty :()->T): T {
return acquire() ?: getIfEmpty()
}
override fun acquire(): T? {
if (mPool.size == 0) {
return null
}
while (true){
val item = mPool.poll() ?: return null
if(item.get() != null){
return item.get()
}
}
}
override fun release(instance: T): Boolean {
if(mPool.size > maxPoolSize){
if(getRealSize() > maxPoolSize){
return false
}
}
mPool.addFirst(WeakReference(instance))
return true
}
private fun getRealSize():Int{
val iterator = mPool.listIterator()
while (iterator.hasNext()){
val item = iterator.next().get()
if(item == null){
iterator.remove()
}
}
return mPool.size
}
fun clear(){
mPool.clear()
}
}

View File

@@ -0,0 +1,493 @@
package com.chwl.app.vip
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.base.TitleBar
import com.chwl.app.common.EmptyViewHelper
import com.chwl.app.databinding.ActivityVipCenterBinding
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.utils.RVDelegate
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.vip.adapter.OnItemClickListener
import com.chwl.app.vip.adapter.VipAuthAdapter
import com.chwl.app.vip.adapter.VipCenterBannerAdapter
import com.chwl.app.vip.adapter.VipCenterIdentificationsAdapter
import com.chwl.app.vip.adapter.VipMagicIndicatorAdapter
import com.chwl.app.vip.adapter.VipRebateAdapter
import com.chwl.app.vip.dialog.SelectPayTypeDialog
import com.chwl.app.vip.dialog.VipAuthDetailsDialog
import com.chwl.core.UriProvider
import com.chwl.core.pay.PayModel
import com.chwl.core.pay.bean.ChargeBean
import com.chwl.core.utils.extension.toast
import com.chwl.core.vip.bean.VipAuthInfo
import com.chwl.core.vip.bean.VipInfo
import com.example.lib_utils.AppUtils
import com.example.lib_utils.UiUtils
import com.example.matisse.internal.utils.UIUtils
import com.example.module_base.support.billing.IBillingService
import com.example.module_base.support.billing.IProductDetails
import com.example.module_base.support.billing.IPurchase
import com.netease.nim.uikit.StatusBarUtil
import com.youth.banner.Banner
import com.youth.banner.adapter.BannerImageAdapter
import com.youth.banner.holder.BannerImageHolder
import com.youth.banner.indicator.CircleIndicator
import com.youth.banner.transformer.AlphaPageTransformer
import com.youth.banner.transformer.DepthPageTransformer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import com.youth.banner.listener.OnPageChangeListener
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.Calendar
import java.util.Locale
class VipCenterActivity : BaseViewBindingActivity<ActivityVipCenterBinding>(),
VipMagicIndicatorAdapter.OnItemSelectListener, OnItemClickListener, IBillingService.Listener {
private val authAdapter = VipAuthAdapter() // 用户权限
private val vipViewModel: VipViewModel by viewModels()
private var chargeList: List<ChargeBean>? = null
private var authInfoList: List<VipAuthInfo>? = null
private val rebateAdapter = VipRebateAdapter()
private var currentChargeInfo: ChargeBean? = null
private lateinit var rvDelegate: RVDelegate<VipAuthInfo>
private lateinit var banner:Banner<VipInfo, VipCenterBannerAdapter>
private lateinit var recyclerView: RecyclerView
private lateinit var vipIdentificationsAdapter: VipCenterIdentificationsAdapter
private var currentIndex = 0
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, VipCenterActivity::class.java)
context.startActivity(starter)
}
private const val BIND_CODE_GOLD = 200
private const val TAG = "VipCenterActivity"
}
@SuppressLint("SetTextI18N")
override fun init() {
EventBus.getDefault().register(this)
initVipCenterBar(getString(R.string.vip_center))
updateVipCenterBar()
initView()
initObserve()
rvDelegate = RVDelegate.Builder<VipAuthInfo>()
.setLayoutManager(GridLayoutManager(this, 3))
.setRecyclerView(binding.recyclerViewBottom)
.setEmptyView(
EmptyViewHelper.createEmptyTextView(
context,
getString(R.string.me_no_search_results)
)
)
.setAdapter(authAdapter)
.build()
handleAuthAdapter()
handleViewModel()
handleBinding()
requestChargeList{
loadChargeList(it)
}
}
private fun initView() {
banner = findViewById(R.id.banner_view)
banner.setBannerGalleryEffect(20, 20, 15)
banner.addOnPageChangeListener(object : OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
// 页面滑动中
}
override fun onPageSelected(position: Int) {
// 页面被选中position 已更新
currentIndex = position
vipViewModel.onItemSelect(position)
refreshBottomArea()
}
override fun onPageScrollStateChanged(state: Int) {
// 页面滚动状态改变
}
})
recyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = GridLayoutManager(this, 2)
}
private fun updateVipCenterBar() {
mTitleBar = findViewById(R.id.title_bar)
// if (mTitleBar != null) {
// mTitleBar.addAction(object : TitleBar.ImageAction(R.drawable.vip_center_help_button) {
// override fun performAction(view: View) {
// CommonWebViewActivity.start(
// this@VipCenterActivity,
// UriProvider.getVipHelpUrl())
// }
// })
// }
}
private fun handleAuthAdapter() {
authAdapter.setOnItemClickListener { _, _, position ->
authAdapter.getItem(position)?.let {
VipAuthDetailsDialog.newInstance(it.descPic, it.authName, it.authIntro).show(this)
}
}
}
private fun handleBinding() {
binding.layoutOpenVip.setOnClickListener {
checkBuyVip {
buyVip()
}
}
binding.recyclerViewBottom.isNestedScrollingEnabled = false
}
@SuppressLint("NotifyDataSetChanged")
private fun handleViewModel() {
vipViewModel.getVipPageInfo()
vipViewModel.loadingLiveData.observe(this) {
if (it == true) {
dialogManager.showProgressDialog(this)
} else {
dialogManager.dismissDialog()
}
}
vipViewModel.authInfosLiveData.observe(this) {
// ArrayList[VipAuthInfo] // 全部特权列表
it?.let {
val filteredList = it.filter { authInfo ->
authInfo.authType == 4 || authInfo.authType == 6 || authInfo.authType == 10 || authInfo.authType == 14 || authInfo.authType == 15 || authInfo.authType == 12 || authInfo.authType == 13
}
authInfoList = filteredList
authAdapter.setNewData(filteredList)
vipIdentificationsAdapter = VipCenterIdentificationsAdapter(this, it, this)
recyclerView.adapter = vipIdentificationsAdapter
}
// authAdapter.setNewData(it)
// it?.let {
// vipIdentificationsAdapter = VipCenterIdentificationsAdapter(this, it, this)
// recyclerView.adapter = vipIdentificationsAdapter
// }
}
vipViewModel.pageLiveData.observe(this) {
it?.let { // 当前显示的 index
// TODO 处理轮播组件 index 更新
currentIndex = it
}
}
vipViewModel.vipInfosLiveData.observe(this) {
it?.let { // ArrayList[VipInfo] 每个等级的 VIP 内容
// TODO 初始化轮播组件
}
}
vipViewModel.myVipInfoLiveData.observe(this) {
val adapter = vipViewModel.vipInfosLiveData.value?.let { it1 ->
VipCenterBannerAdapter(this,
it1, it)
}
banner.setAdapter(adapter, false)
it?.let {
// lifecycleScope.launch {
// delay(500)
banner?.postDelayed(object : Runnable {
override fun run() {
banner.setCurrentItem(it.vipLevel-1)
}
}, 200)
// }
if (it.ownAuthTypes?.contains(13) == true && mTitleBar.actionCount == 1) {
mTitleBar.addAction(object : TitleBar.ImageAction(R.drawable.ic_vip_setting) {
override fun performAction(view: View?) {
VipSettingActivity.start(this@VipCenterActivity)
}
}, 0)
}
} ?: run {
// binding.layoutLevelInfo.isVisible = false
// binding.layoutLevelProgress.isVisible = false
binding.slAuth.isVisible = true
// binding.tvNotOpen.text = getString(R.string.me_no_aristocracy_yet)
}
}
vipViewModel.currVipInfoLiveData.observe(this) {
it?.let { // VipInfo
if (it.comingSoon == 2) {
/// 处理敬请期待情况, 补充显示 SVGA
binding.slAuth.isVisible = false
// binding.bannerView.isVisible = false
binding.layoutBottomPanel.isVisible = false
} else {
val myVipInfo = vipViewModel.myVipInfoLiveData.value
// TODO 根据当前显示的 VIP 信息更新 UI
authAdapter.setVipInfo(it)
authAdapter.notifyDataSetChanged()
handleIdentificationAreaContent(it)
vipIdentificationsAdapter.setVipInfo(it)
refreshBottomArea()
}
} ?: run {
getString(R.string.me_failed_to_get_aristocrat_data).toast()
}
}
}
override fun onItemClick(position: Int) {
authAdapter.getItem(position)?.let {
VipAuthDetailsDialog.newInstance(it.descPic, it.authName, it.authIntro).show(this)
}
}
private fun handleIdentificationAreaContent(vipInfo: VipInfo) {
val exclusivePrivilegesTitle = findViewById<TextView>(R.id.center_title_2)
var count = 0
authInfoList?.map { info ->
if (vipInfo?.ownAuthTypes?.contains(info.authType) == true) {
count ++
}
}
"${getString(R.string.vip_center_4)}\n(${count}/${authInfoList?.size})".also {
binding.centerTitle2.text = it
}
// exclusivePrivilegesTitle.text = R.string.vip_center_4.toString()
}
@SuppressLint("CheckResult")
private fun requestChargeList(call: (List<ChargeBean>) -> Unit) {
PayModel.get().vipList
.compose(bindToLifecycle())
.subscribe(
{
call.invoke(it)
}, {
it.printStackTrace()
}
)
}
private fun initObserve(){
lifecycleScope.launch(Dispatchers.Main) {
vipViewModel.getVipRebateSuccessFlow.collect {
rebateAdapter.notifyItemRangeChanged(0, rebateAdapter.itemCount, true)
}
}
}
private fun loadChargeList(list: List<ChargeBean>) {
this.chargeList = list
refreshBottomArea()
}
private fun checkBuyVip(block: () -> Unit) {
val myVipInfo = vipViewModel.myVipInfoLiveData.value
val currentVipInfo = vipViewModel.vipInfosLiveData.value?.get(currentIndex)
if (currentVipInfo != null &&
myVipInfo != null &&
currentVipInfo.vipLevel > myVipInfo.vipLevel) {
val message = context.getString(R.string.vip_buy_tips).format(
myVipInfo.vipName,currentVipInfo.vipName
)
dialogManager.showOkCancelDialog(message,
context.getString(R.string.miniworld_activity_mwteamroommessageact_07),
context.getString(R.string.miniworld_activity_mwteamroommessageact_08),
true
) { block.invoke() }
} else {
block.invoke()
}
}
private fun buyVip() {
val currentVipInfo = vipViewModel.vipInfosLiveData.value?.get(currentIndex)
currentVipInfo?.let {
val googleUnavailable = ((currentChargeInfo?.productDetails?.getOneTimePurchaseOfferDetails()
?.getPriceAmountMicros()
?: "0") == "0")
var text =
currentChargeInfo?.productDetails?.getOneTimePurchaseOfferDetails()?.getFormattedPrice()
if (text.isNullOrEmpty()) {
text = it.buyAmount.toString()
}
SelectPayTypeDialog.newInstance(
text,
!googleUnavailable,
it.buyAmount
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond(
currentChargeInfo?.getProdDesc()?.toIntOrNull() ?: -1
)
}
setOnGoogleChargeClick {
if (googleUnavailable) {
toast(getString(R.string.Recharge_failure))
return@setOnGoogleChargeClick
}
currentChargeInfo?.let { charge ->
buyProduct(charge.productDetails)
}
}
setOnChargeClick {
ChargeActivity.start(this@VipCenterActivity)
}
}
.show(context)
}
}
/*购买商品*/
@SuppressLint("CheckResult")
fun buyProduct(productDetails: IProductDetails?) {
if (productDetails != null) {
Log.d(VipCenterActivity.TAG, "BuyProduct:" + productDetails.getProductId())
// PayModel.get().placeOrder(productDetails.getProductId())
// .compose(bindToLifecycle())
// .subscribe(
// { recordId: PayRecordId ->
// billingManager?.initiatePurchaseFlow(
// productDetails,
// recordId.recordId
// )
// }
// ) { throwable: Throwable ->
// SingleToastUtil.showToast(
// throwable.message
// )
// }
} else {
Log.w(VipCenterActivity.TAG, "skuDetails ==null")
}
}
private fun refreshBottomArea() {
val currentPageVipInfo = vipViewModel.vipInfosLiveData.value?.get(currentIndex)
currentPageVipInfo?.let {
currentChargeInfo = chargeList?.firstOrNull {
it.prodDesc?.toIntOrNull() == currentPageVipInfo.vipLevel
}
if (it.buyAmount == 0) {
binding.tvNoticeText.visibility = View.VISIBLE
binding.tvOpenVip.visibility = View.GONE
binding.layoutOpenVip.visibility = View.GONE
binding.tvIcon.visibility = View.GONE
getString(R.string.vip_center_9).format(
currentPageVipInfo.vipLevel
).also { binding.tvNoticeText.text = it }
} else {
var myVipIsHighLevel = false
val myVipInfo = vipViewModel.myVipInfoLiveData.value
myVipInfo?.let {
myVipIsHighLevel = myVipInfo.vipLevel >= currentPageVipInfo.vipLevel
}
binding.tvNoticeText.visibility = View.GONE
binding.tvOpenVip.visibility = View.VISIBLE
binding.layoutOpenVip.visibility = View.VISIBLE
binding.tvIcon.visibility = View.VISIBLE
"${it.buyAmount} ${
getString(R.string.vip_center_5).format(
" / 30"
)
}".also { binding.tvOpenVip.text = it }
}
}
}
private fun refreshOpenVipState() {
val currentVipInfo = vipViewModel.currVipInfoLiveData.value
val myVipInfo = vipViewModel.myVipInfoLiveData.value
if (currentVipInfo != null) {
currentChargeInfo = chargeList?.firstOrNull {
it.prodDesc?.toIntOrNull() == currentVipInfo.vipLevel
}
if (currentChargeInfo != null){
"${vipViewModel.myVipInfoLiveData.value?.buyAmount} ${
getString(R.string.vip_center_5).format(
" / 30"
)
}".also { binding.tvOpenVip.text = it }
}
} else {
currentChargeInfo = null
// binding.layoutOpenVip.isVisible = false
}
// if (binding.layoutOpenVip.isVisible && binding.layoutLevelProgress.isVisible) {
// binding.layoutBottomPanel.setBackgroundDrawable(binding.layoutLevelProgress.background)
// } else {
// binding.layoutBottomPanel.setBackgroundDrawable(null)
// }
}
override fun onItemSelect(position: Int, view: TextView?) {
TODO("Not yet implemented")
}
override fun onBillingClientSetupFinished() {
TODO("Not yet implemented")
}
override fun onPurchasesUpdated(purchases: List<IPurchase>) {
TODO("Not yet implemented")
}
override fun onConsumeFinished(token: String?, result: Int) {
TODO("Not yet implemented")
}
override fun onFailedHandle(result: Int) {
TODO("Not yet implemented")
}
override fun needSteepStateBar() = true
override fun setStatusBar() {
super.setStatusBar()
StatusBarUtil.transparencyBar(this)
}
}

View File

@@ -1,622 +0,0 @@
package com.chwl.app.vip
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.viewModels
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.example.module_base.support.billing.IBillingResult
import com.example.module_base.support.billing.IBillingService
import com.example.module_base.support.billing.IProductDetails
import com.example.module_base.support.billing.IPurchase
import com.example.module_base.support.google.IGoogleService
import com.netease.nim.uikit.StatusBarUtil
import com.netease.nim.uikit.common.util.sys.TimeUtil
import com.opensource.svgaplayer.SVGADrawable
import com.opensource.svgaplayer.SVGAImageView
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.base.TitleBar
import com.chwl.app.common.EmptyViewHelper
import com.chwl.app.databinding.ActivityVipMainBinding
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.setting.ModifyPwdActivity
import com.chwl.app.ui.utils.RVDelegate
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
import com.chwl.app.vip.adapter.VipAuthAdapter
import com.chwl.app.vip.adapter.VipMagicIndicatorAdapter
import com.chwl.app.vip.adapter.VipRebateAdapter
import com.chwl.app.vip.dialog.SelectPayTypeDialog
import com.chwl.app.vip.dialog.VipAuthDetailsDialog
import com.chwl.app.vip.dialog.VipRemainTimeDialog
import com.chwl.core.UriProvider
import com.chwl.core.pay.PayModel
import com.chwl.core.pay.bean.ChargeBean
import com.chwl.core.pay.bean.PayRecordId
import com.chwl.core.utils.net.IgnoreException
import com.chwl.core.vip.bean.VipAuthInfo
import com.chwl.core.vip.bean.VipInfo
import com.chwl.core.utils.extension.toast
import com.chwl.core.vip.VipOpenEvent
import com.chwl.library.utils.SingleToastUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.net.MalformedURLException
import java.net.URL
class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
VipMagicIndicatorAdapter.OnItemSelectListener, IBillingService.Listener {
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, VipMainActivity::class.java)
context.startActivity(starter)
}
private const val BIND_CODE_GOLD = 200
private const val TAG = "VipMainActivity"
}
private val authAdapter = VipAuthAdapter()
private lateinit var rvDelegate: RVDelegate<VipAuthInfo>
private val vipViewModel: VipViewModel by viewModels()
private var billingManager: IBillingService? = null
private var currentChargeInfo: ChargeBean? = null
private var chargeList: List<ChargeBean>? = null
private val rebateAdapter = VipRebateAdapter()
@SuppressLint("SetTextI18n")
override fun init() {
EventBus.getDefault().register(this)
initWhiteTitleBar(getString(R.string.vip_center))
mTitleBar.addAction(object : TitleBar.ImageAction(R.drawable.ic_vip_help) {
override fun performAction(view: View) {
CommonWebViewActivity.start(this@VipMainActivity, UriProvider.getVipHelpUrl())
}
})
initView()
initObserve()
binding.ivRankList.setOnClickListener {
CommonWebViewActivity.start(this@VipMainActivity, UriProvider.getRankListUrl())
}
binding.ivTimeHelp.setOnClickListener {
VipRemainTimeDialog.newInstance().show(this)
}
rvDelegate = RVDelegate.Builder<VipAuthInfo>()
.setLayoutManager(GridLayoutManager(this, 3))
.setRecyclerView(binding.recyclerView)
.setEmptyView(
EmptyViewHelper.createEmptyTextView(
context,
getString(R.string.me_no_search_results)
)
)
.setAdapter(authAdapter)
.build()
binding.recyclerView.isNestedScrollingEnabled = false
authAdapter.setOnItemClickListener { _, _, position ->
authAdapter.getItem(position)?.let {
VipAuthDetailsDialog.newInstance(it.descPic, it.authName, it.authIntro).show(this)
}
}
vipViewModel.getVipPageInfo()
vipViewModel.loadingLiveData.observe(this) {
if (it == true) {
dialogManager.showProgressDialog(this)
} else {
dialogManager.dismissDialog()
}
}
vipViewModel.authInfosLiveData.observe(this) {
authAdapter.setNewData(it)
}
vipViewModel.vipInfosLiveData.observe(this) {
it?.let {
initTitleTab(it)
}
}
vipViewModel.myVipInfoLiveData.observe(this) {
it?.let {
binding.layoutLevelInfo.isVisible = true
binding.layoutLevelProgress.isVisible = true
binding.tvNotOpen.text =
"${getString(R.string.me_current_power_value)}${it.currScore}"
binding.tvCurrValue.text = "${getString(R.string.me_current)}${it.currScore}"
binding.tvCurrLevelName.text = it.vipName
binding.tvKeepValue.text = "${getString(R.string.me_grading)}${it.levelKeepScore}"
if (it.isMaxLevel) {
binding.llNextLevelDesc.isVisible = false
binding.tvMaxLevelHint.isVisible = true
binding.tvUpValue.isVisible = false
} else {
binding.llNextLevelDesc.isVisible = true
binding.tvMaxLevelHint.isVisible = false
binding.tvUpValue.isVisible = true
binding.tvNextLevelName.text = it.nextVipName
binding.tvUpValue.text = "${getString(R.string.me_upgrade)}${it.levelUpScore}"
binding.tvUpgradeValue.text = "${it.levelUpScore - it.currScore}"
}
binding.tvResidueTime.text = TimeUtil.getElapseTimeForVip(it.remainSeconds)
binding.seekBar.max = it.levelUpScore
binding.seekBar.progress = Math.min(it.currScore, it.levelUpScore)
val currValueParams =
binding.tvCurrValue.layoutParams as ConstraintLayout.LayoutParams
currValueParams.horizontalBias =
Math.min(it.currScore.toFloat() / it.levelUpScore, 1f)
binding.tvCurrValue.layoutParams = currValueParams
val keepParams =
binding.ivKeepIndicator.layoutParams as ConstraintLayout.LayoutParams
keepParams.horizontalBias = it.levelKeepScore.toFloat() / it.levelUpScore
binding.ivKeepIndicator.layoutParams = keepParams
if (it.ownAuthTypes?.contains(13) == true && mTitleBar.actionCount == 1) {
mTitleBar.addAction(object : TitleBar.ImageAction(R.drawable.ic_vip_setting) {
override fun performAction(view: View) {
VipSettingActivity.start(this@VipMainActivity)
}
}, 0)
}
} ?: run {
binding.layoutLevelInfo.isVisible = false
binding.layoutLevelProgress.isVisible = false
binding.slAuth.isVisible = true
binding.tvNotOpen.text = getString(R.string.me_no_aristocracy_yet)
}
}
vipViewModel.currVipInfoLiveData.observe(this) {
it?.let {
if (it.comingSoon == 2) {
binding.llNotOpen.isVisible = true
binding.slAuth.isVisible = false
binding.layoutBottomPanel.isVisible = false
loadSVGA(binding.ivNotOpenIcon, it.vipLogo)
} else {
binding.slAuth.isVisible = true
binding.llNotOpen.isVisible = false
binding.layoutBottomPanel.isVisible = true
val myVipInfo = vipViewModel.myVipInfoLiveData.value
binding.ivMyLevel.isInvisible = it.vipLevel != myVipInfo?.vipLevel
binding.tvNotOpen.isInvisible =
!(it.vipLevel == myVipInfo?.vipLevel || myVipInfo == null)
loadSVGA(binding.ivVipIcon, it.vipLogo)
binding.tvAuthNum.text =
"${it.ownAuthTypes?.size ?: 0}/${vipViewModel.authInfosLiveData.value?.size ?: 0}"
authAdapter.setVipInfo(it)
authAdapter.notifyDataSetChanged()
loadRebateData(it)
refreshOpenVipState()
}
} ?: run {
getString(R.string.me_failed_to_get_aristocrat_data).toast()
binding.llNotOpen.isVisible = false
binding.slAuth.isVisible = false
}
}
vipViewModel.pageLiveData.observe(this) {
it?.let {
binding.magicIndicator.onPageSelected(it)
}
}
binding.layoutOpenVip.setOnClickListener {
checkBuyVip {
buyVip()
}
}
requestChargeList{
loadChargeList(it)
}
initBilling()
}
private fun initBilling() {
billingManager = IGoogleService.newBillingService(this,this)
}
override fun initWhiteTitleBar(title: String?) {
mTitleBar = findViewById(R.id.title_bar)
if (mTitleBar != null) {
mTitleBar.setTitle(title)
mTitleBar.setImmersive(false)
mTitleBar.setTitleColor(resources.getColor(R.color.white))
mTitleBar.setLeftImageResource(R.drawable.arrow_left_white)
mTitleBar.setBackgroundResource(R.color.transparent)
mTitleBar.setLeftClickListener { onLeftClickListener() }
}
}
/**
* 初始化推荐和派对tab
*/
private fun initTitleTab(vipInfos: List<VipInfo>) {
val commonNavigator = CommonNavigator(context)
commonNavigator.isEnablePivotScroll = true
commonNavigator.isFollowTouch = false
val magicIndicatorAdapter =
VipMagicIndicatorAdapter(
context,
vipInfos
)
magicIndicatorAdapter.setOnItemSelectListener(this)
commonNavigator.adapter = magicIndicatorAdapter
binding.magicIndicator.navigator = commonNavigator
commonNavigator.titleContainer.showDividers = LinearLayout.SHOW_DIVIDER_MIDDLE
}
private fun loadSVGA(svgaImageView: SVGAImageView, svgaUrl: String) {
try {
SVGAParser.shareParser()
.decodeFromURL(URL(svgaUrl), object : SVGAParser.ParseCompletion {
override fun onComplete(videoItem: SVGAVideoEntity) {
val drawable = SVGADrawable(videoItem)
svgaImageView.setImageDrawable(drawable)
svgaImageView.startAnimation()
}
override fun onError() {
}
})
} catch (e: MalformedURLException) {
}
}
@SuppressLint("SetTextI18n")
override fun onItemSelect(position: Int, view: TextView?) {
vipViewModel.onItemSelect(position)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onVipOpenEvent(vipOpenEvent: VipOpenEvent) {
getString(R.string.me_opening_of_the_aristocracy_successful).toast()
vipViewModel.getVipPageInfo()
}
override fun needSteepStateBar() = true
override fun setStatusBar() {
super.setStatusBar()
StatusBarUtil.transparencyBar(this)
}
/*客户端设置成功回调*/
@SuppressLint("CheckResult", "SetTextI18n")
override fun onBillingClientSetupFinished() {
Log.i(TAG, "onBillingClientSetupFinished")
val call: ((List<ChargeBean>) -> Unit) = { list ->
loadChargeList(list)
val productKeys = ArrayList<String>()
list.forEach {
productKeys.add(it.getChargeProdId())
}
billingManager?.querySkuDetailsAsync(productKeys,
object : IBillingService.ProductDetailsResponseListener {
override fun onProductDetailsResponse(
billingResult: IBillingResult,
productDetails: List<IProductDetails>
) {
if (!billingResult.isResponseOk()) {
Log.w(
TAG,
"Unsuccessful query for Error code: " + billingResult.getResponseCode()
)
} else if (productDetails.isNotEmpty()) {
for (item in list) {
for (skuDetails in productDetails) {
if (skuDetails.getProductId() == item.getChargeProdId()) {
item.productDetails = skuDetails
break
}
}
}
loadChargeList(list)
}
}
})
}
val list = chargeList
if (list.isNullOrEmpty()) {
requestChargeList{
call.invoke(it)
}
} else {
call.invoke(list)
}
}
@SuppressLint("CheckResult")
private fun requestChargeList(call: (List<ChargeBean>) -> Unit) {
PayModel.get().vipList
.compose(bindToLifecycle())
.subscribe(
{
call.invoke(it)
}, {
it.printStackTrace()
}
)
}
/*商品更新回调*/
@SuppressLint("CheckResult")
override fun onPurchasesUpdated(purchases: List<IPurchase>) {
for (purchase in purchases) {
if (purchase.isPurchasedState() &&
purchase.getAccountIdentifiers() != null
) {
PayModel.get().verifyOrder(
purchase.getAccountIdentifiers()!!.getObfuscatedAccountId(),
purchase.getProducts().firstOrNull(),
purchase.getPackageName(),
purchase.getPurchaseToken()
)
.compose(bindToLifecycle())
.subscribe(
{ token: String ->
//L.i("token=" + token);
billingManager?.consumeAsync(token)
// var skuDetails: IProductDetails? = null
// if (googleChargeBean?.getChargeProdId() == purchase.getProducts()
// .firstOrNull()
// ) {
// skuDetails = googleChargeBean?.productDetails
// }
// if (skuDetails != null) {
// val eventValue: MutableMap<String, Any> =
// HashMap()
// eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
// eventValue[AFInAppEventParameterName.QUANTITY] = 1
// eventValue[AFInAppEventParameterName.CONTENT_ID] =
// purchase.getOrderId()!!
// if (skuDetails.getOneTimePurchaseOfferDetails() != null) {
// eventValue[AFInAppEventParameterName.REVENUE] =
// skuDetails.getOneTimePurchaseOfferDetails()
// ?.getPriceAmountMicros()!! / 1000000f
// eventValue["Price"] =
// skuDetails.getOneTimePurchaseOfferDetails()
// ?.getFormattedPrice()!!
// eventValue[AFInAppEventParameterName.CURRENCY] =
// skuDetails.getOneTimePurchaseOfferDetails()
// ?.getPriceCurrencyCode()!!
// }
// AppsFlyerLib.getInstance().logEvent(
// applicationContext,
// AFInAppEventType.PURCHASE,
// eventValue
// )
// }
}
) { throwable: Throwable ->
if (throwable !is IgnoreException) {
SingleToastUtil.showToast(throwable.message)
}
}
}
}
Log.i(TAG, "onPurchasesUpdated")
}
override fun onConsumeFinished(token: String?, result: Int) {
}
override fun onFailedHandle(result: Int) {
}
/*购买商品*/
@SuppressLint("CheckResult")
fun buyProduct(productDetails: IProductDetails?) {
if (productDetails != null) {
Log.d(TAG, "BuyProduct:" + productDetails.getProductId())
PayModel.get().placeOrder(productDetails.getProductId())
.compose(bindToLifecycle())
.subscribe(
{ recordId: PayRecordId ->
billingManager?.initiatePurchaseFlow(
productDetails,
recordId.recordId
)
}
) { throwable: Throwable ->
SingleToastUtil.showToast(
throwable.message
)
}
} else {
Log.w(TAG, "skuDetails ==null")
}
}
override fun onResume() {
super.onResume()
if (billingManager?.isServiceConnected() == true) {
billingManager?.onQueryPurchases()
}
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
billingManager?.destroy()
currentChargeInfo = null
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
dialogManager.dismissDialog()
if (resultCode != RESULT_OK) {
return
}
if (requestCode == BIND_CODE_GOLD) {
ModifyPwdActivity.start(this, ModifyPwdActivity.FOGERT_PAY_PWD)
}
}
private fun initView() {
binding.tvTabPrivilege.setOnClickListener {
showPrivilegeTab()
}
binding.tvTabRebate.setOnClickListener {
showRebateTab()
}
rebateAdapter.onGetListener = {
vipViewModel.getVipRebate(it)
}
binding.rvRebate.isNestedScrollingEnabled = false
binding.rvRebate.adapter = rebateAdapter
}
private fun initObserve(){
lifecycleScope.launch(Dispatchers.Main) {
vipViewModel.getVipRebateSuccessFlow.collect {
rebateAdapter.notifyItemRangeChanged(0, rebateAdapter.itemCount, true)
}
}
}
private fun showPrivilegeTab() {
binding.layoutRebate.isInvisible = true
binding.groupPrivilege.isInvisible = false
binding.tvTabPrivilege.setBackgroundResource(R.drawable.vip_bg_tab_selected)
binding.tvTabRebate.setBackgroundResource(R.drawable.vip_bg_tab_unselected)
}
private fun showRebateTab() {
binding.groupPrivilege.isInvisible = true
binding.layoutRebate.isInvisible = false
binding.tvTabPrivilege.setBackgroundResource(R.drawable.vip_bg_tab_unselected)
binding.tvTabRebate.setBackgroundResource(R.drawable.vip_bg_tab_selected)
}
private fun loadChargeList(list: List<ChargeBean>) {
this.chargeList = list
refreshOpenVipState()
}
private fun loadRebateData(info: VipInfo) {
binding.tvTableLevelName.text = info.vipName
binding.tvRebateTips1.text =
context.getString(R.string.vip_buy_tips_format).format(info.vipName)
rebateAdapter.setNewData(info.returnProfits)
val isNormalStatus = info.isRebate()
binding.layoutRebate.children.forEach {
if(it == binding.tvRebateDisableStatus){
it.isVisible = !isNormalStatus
}else{
it.isVisible = isNormalStatus
}
}
}
private fun refreshOpenVipState() {
val currentVipInfo = vipViewModel.currVipInfoLiveData.value
val myVipInfo = vipViewModel.myVipInfoLiveData.value
if (currentVipInfo != null) {
currentChargeInfo = chargeList?.firstOrNull {
it.prodDesc?.toIntOrNull() == currentVipInfo.vipLevel
}
if (currentChargeInfo != null && (myVipInfo == null || myVipInfo.vipLevel < currentVipInfo.vipLevel)) {
binding.tvOpenVip.text =
"${currentChargeInfo?.getMoney()} ${
getString(R.string.vip_buy_format).format(
currentVipInfo.vipName
)
}"
binding.layoutOpenVip.isVisible = true
} else {
binding.layoutOpenVip.isVisible = false
}
} else {
currentChargeInfo = null
binding.layoutOpenVip.isVisible = false
}
if (binding.layoutOpenVip.isVisible && binding.layoutLevelProgress.isVisible) {
binding.layoutBottomPanel.setBackgroundDrawable(binding.layoutLevelProgress.background)
} else {
binding.layoutBottomPanel.setBackgroundDrawable(null)
}
}
private fun checkBuyVip(block: () -> Unit) {
val myVipInfo = vipViewModel.myVipInfoLiveData.value
val currentVipInfo = vipViewModel.currVipInfoLiveData.value
if (currentVipInfo != null && myVipInfo != null && currentVipInfo.vipLevel > myVipInfo.vipLevel) {
val message = context.getString(R.string.vip_buy_tips).format(
myVipInfo.vipName,currentVipInfo.vipName
)
dialogManager.showOkCancelDialog(message,
context.getString(R.string.miniworld_activity_mwteamroommessageact_07),
context.getString(R.string.miniworld_activity_mwteamroommessageact_08),
true
) { block.invoke() }
} else {
block.invoke()
}
}
private fun buyVip() {
val googleUnavailable = ((currentChargeInfo?.productDetails?.getOneTimePurchaseOfferDetails()
?.getPriceAmountMicros()
?: "0") == "0")
var text =
currentChargeInfo?.productDetails?.getOneTimePurchaseOfferDetails()?.getFormattedPrice()
if (text.isNullOrEmpty()) {
text = ((currentChargeInfo?.money ?: 0.0) * 1000).toInt().toString()
}
SelectPayTypeDialog.newInstance(
text,
!googleUnavailable,
currentChargeInfo?.getMoney() ?: 0.0
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond(
currentChargeInfo?.getProdDesc()?.toIntOrNull() ?: -1
)
}
setOnGoogleChargeClick {
if (googleUnavailable) {
toast(getString(R.string.Recharge_failure))
return@setOnGoogleChargeClick
}
currentChargeInfo?.let { charge ->
buyProduct(charge.productDetails)
}
}
setOnChargeClick {
ChargeActivity.start(this@VipMainActivity)
}
}
.show(context)
}
}

View File

@@ -61,28 +61,20 @@ class VipViewModel : BaseViewModel() {
vipPageInfo?.let {
_authInfosLiveData.value = it.vipAuthInfos
_vipInfosLiveData.value = it.vipInfos
if (it.currLevel == 0) {
_myVipInfoLiveData.value = null
onItemSelect(0)
} else {
var position = 0
_myVipInfoLiveData.value =
it.vipInfos?.find { vipInfo -> it.currLevel == vipInfo.vipLevel }
?.copy()
?.apply {
position = it.vipInfos?.indexOf(this) ?: -1
val nextVipInfo =
it.vipInfos?.getOrNull(position + 1)
nextVipName =
if (nextVipInfo?.vipName == vipName) null else nextVipInfo?.vipName
remainSeconds = it.remainSeconds
currLevel = it.currLevel
currScore = it.currScore
isMaxLevel = it.isMaxLevel
}
onItemSelect(if (position < 0) 0 else position)
}
var position = 0
_myVipInfoLiveData.value = it.vipInfos?.findLast { vipInfo ->
vipInfo.remainSeconds > 0
}?.copy()
?.apply {
position = it.vipInfos?.indexOf(this) ?: -1
val nextVipInfo = it.vipInfos?.getOrNull(position + 1)
nextVipName = if (nextVipInfo?.vipName == vipName) null else nextVipInfo?.vipName
// remainSeconds = it.remainSeconds
currLevel = it.currLevel
currScore = it.currScore
isMaxLevel = it.isMaxLevel
}
onItemSelect(if (position < 0) 0 else position)
}
}

View File

@@ -22,6 +22,6 @@ class VipAuthAdapter :
helper.setText(R.id.tv_auth_name, item.authName)
helper.getView<ImageView>(R.id.iv_auth_icon).load(item.authIcon)
helper.itemView.alpha =
if (vipInfo?.ownAuthTypes?.contains(item.authType) == true) 1f else 0.5f
if (vipInfo?.ownAuthTypes?.contains(item.authType) == true) 1f else 0.7f
}
}

View File

@@ -0,0 +1,165 @@
package com.chwl.app.vip.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.core.vip.bean.VipInfo
import com.chwl.library.download.DownloadException
import com.chwl.library.download.DownloadManager.download
import com.chwl.library.download.DownloadRequest.Companion.build
import com.chwl.library.download.DownloadTask
import com.chwl.library.download.FileDownloadListener
import com.chwl.library.utils.PathHelper.generateResourcesFilePath
import com.chwl.library.utils.ResUtil.getString
import com.tencent.qgame.animplayer.AnimConfig
import com.tencent.qgame.animplayer.AnimView
import com.tencent.qgame.animplayer.inter.IAnimListener
import com.tencent.qgame.animplayer.util.ScaleType
import com.youth.banner.adapter.BannerAdapter
import java.io.File
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
class VipCenterBannerAdapter(
private val context: Context,
private val vipInfos: List<VipInfo>,
private val myVipInfo: VipInfo?
) : BannerAdapter<VipInfo, VipCenterBannerAdapter.BannerViewHolder>(vipInfos) {
private val DOWNLOAD_TAG = "gift_effect_download"
override fun onCreateHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
val view = LayoutInflater.from(context).inflate(
R.layout.banner_vip_center_custom,
parent,
false)
return BannerViewHolder(view)
}
override fun onBindView(holder: BannerViewHolder, data: VipInfo, position: Int, size: Int) {
//todo do 旧bug 买完VIP不刷新item
holder.dueText.visibility = View.GONE
if (myVipInfo != null) {
myVipInfo.let {
if (it.vipLevel >= data.vipLevel) {
var result = getString(R.string.vip_center_8)
if (data.remainSeconds>0){
val calendar = Calendar.getInstance()
calendar.add(Calendar.SECOND, data.remainSeconds)
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
val formattedDate = dateFormat.format(calendar.time)
result = "${getString(R.string.vip_center_2)}$formattedDate"
}
holder.dueText.text = result
holder.dueText.visibility = View.VISIBLE
} else if (it.vipLevel < data.vipLevel) {
holder.dueText.text = getString(R.string.vip_center_8)
holder.dueText.visibility = View.VISIBLE
} else {
holder.dueText.visibility = View.GONE
}
}
}else{
holder.dueText.text = getString(R.string.vip_center_8)
holder.dueText.visibility = View.VISIBLE
}
when(position) {
0-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_3A4D14))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_1)
}
1-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_4D143A))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_2)
}
2-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_4D2C14))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_3)
}
3-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_44144D))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_4)
}
4-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_1C344D))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_5)
}
5-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_1C4D35))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_6)
}
6-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_44144D))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_7)
}
7-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_4D371C))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_8)
}
8-> {
holder.dueText.setTextColor(context.resources.getColor(R.color.color_4D1C1C))
holder.imgBackground.setImageResource(R.drawable.vip_center_level_9)
}
}
holder.vapAnimView.setScaleType(ScaleType.FIT_XY)
holder.vapAnimView.setLoop(Int.MAX_VALUE)
holder.vapAnimView.setAnimListener(object : IAnimListener {
override fun onFailed(errorType: Int, errorMsg: String?) {
println(errorMsg)
}
override fun onVideoComplete() {
println("complete")
}
override fun onVideoDestroy() {
println("destory")
}
override fun onVideoRender(frameIndex: Int, config: AnimConfig?) {
println("rendering")
}
override fun onVideoStart() {
println("start")
}
})
val filePath = generateResourcesFilePath(data.vipLogo)
val request = build(data.vipLogo, filePath, DOWNLOAD_TAG, null, 60000L)
download(request, object : FileDownloadListener() {
override fun onDownloadCompleted(task: DownloadTask) {
val path = task.getRequest().getPath()
holder.vapAnimView.startPlay(File(path))
}
override fun onDownloadError(exception: DownloadException) {
exception.printStackTrace()
}
})
}
inner class BannerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val imgBackground: ImageView = view.findViewById(R.id.img_background)
// val svgaImage: SVGAImageView = view.findViewById(R.id.iv_vip_icon)
val vapAnimView: AnimView = view.findViewById(R.id.vap_anim_view)
val dueText: TextView = view.findViewById(R.id.due_date_textview)
}
fun millis2String(millis: Long, format: DateFormat): String {
return format.format(Date(millis))
}
}

View File

@@ -0,0 +1,156 @@
package com.chwl.app.vip.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.core.vip.bean.VipAuthInfo
import com.chwl.core.vip.bean.VipInfo
interface OnItemClickListener {
fun onItemClick(position: Int)
}
class VipCenterIdentificationsAdapter(
private val context: Context,
private val items: List<VipAuthInfo>,
private val listener: OnItemClickListener
) : RecyclerView.Adapter<VipCenterIdentificationsAdapter.ItemViewHolder>() {
private var vipInfo: VipInfo? = null
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): VipCenterIdentificationsAdapter.ItemViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.vip_center_idnetifications_layout, parent, false)
return ItemViewHolder(view)
}
override fun onBindViewHolder(
holder: VipCenterIdentificationsAdapter.ItemViewHolder,
position: Int
) {
val filteredList = items.filter {
it.authType == 1 || it.authType == 5 || it.authType == 8 || it.authType ==
11 || it.authType == 12
}
val item = filteredList[position]
vipInfo?.let {
holder.titleTextView.text = item.authName
// val lv = it.vipLevel
// var resourceName = "null"
when (position) {
0 -> {
when (it.vipLevel) {
1 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv1)
2 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv2)
3 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv3)
4 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv4)
5 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv5)
6 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv6)
7 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv7)
8 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv8)
9 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_vipidentity_lv9)
}
// resourceName = "vip_center_identification_vipidentity_lv$lv"
}
1 -> {
// resourceName = "vip_center_identification_roomcard_lv$lv"
when (it.vipLevel) {
1 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv1)
2 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv2)
3 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv3)
4 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv4)
5 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv5)
6 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv6)
7 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv7)
8 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv8)
9 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_roomcard_lv9)
}
}
2 -> {
// resourceName = "vip_center_identification_mic_lv$lv"
when (it.vipLevel) {
3 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv3)
4 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv4)
5 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv5)
6 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv6)
7 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv7)
8 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv8)
9 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_mic_lv9)
}
}
3 -> {
// resourceName = "vip_center_identification_bubble_lv$lv"
when (it.vipLevel) {
4 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv4)
5 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv5)
6 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv6)
7 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv7)
8 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv8)
9 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_bubble_lv9)
}
}
4 -> {
// resourceName = "vip_center_identification_entry_lv$lv"
when (it.vipLevel) {
4 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv4)
5 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv5)
6 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv6)
7 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv7)
8 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv8)
9 -> holder.contentImageView.setImageResource(R.drawable.vip_center_identification_entry_lv9)
}
}
}
// val resourceId = context.resources
// .getIdentifier(resourceName, "drawable", context.packageName)
// holder.contentImageView.setImageResource(resourceId)
}
val screenWidth = context.resources.displayMetrics.widthPixels
val itemWidth = (screenWidth * 160)/375
val layoutParams = holder.itemView.layoutParams
layoutParams.width = itemWidth
holder.itemView.layoutParams = layoutParams
// holder.itemView.setOnClickListener {
// listener.onItemClick(position)
// }
}
override fun getItemCount(): Int {
return vipInfo?.let {
when (it.vipLevel) {
1, 2 -> 2
3 -> 3
else -> 5
}
} ?: 0 // items.size
}
@SuppressLint("NotifyDataSetChanged")
fun setVipInfo(vipInfo: VipInfo?) {
this.vipInfo = vipInfo
this.notifyDataSetChanged()
}
inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val contentImageView: ImageView = view.findViewById(R.id.item_image)
val titleTextView: TextView = view.findViewById(R.id.item_title)
}
}

View File

@@ -51,9 +51,9 @@ class SelectPayTypeDialog : BaseDialogFragment<DialogSelectPayTypeBinding>() {
fun newInstance(
descText: String,
showGoogleCharge: Boolean = false,
money: Double = 0.0
money: Int = 0
): SelectPayTypeDialog {
return newInstance(descText, (money * 1000).toLong(), showGoogleCharge)
return newInstance(descText, money.toLong(), showGoogleCharge)
}

View File

@@ -12,6 +12,14 @@ import com.chwl.app.base.BaseDialogFragment
import com.chwl.app.databinding.DialogVipUpgradeBinding
import com.chwl.app.vip.VipViewModel
import com.chwl.core.vip.bean.VipInfo
import com.chwl.library.download.DownloadException
import com.chwl.library.download.DownloadManager.download
import com.chwl.library.download.DownloadRequest
import com.chwl.library.download.DownloadRequest.Companion
import com.chwl.library.download.DownloadTask
import com.chwl.library.download.FileDownloadListener
import com.chwl.library.utils.PathHelper.generateResourcesFilePath
import java.io.File
import java.net.MalformedURLException
import java.net.URL
@@ -53,23 +61,38 @@ class VipUpgradeDialog : BaseDialogFragment<DialogVipUpgradeBinding>() {
}
binding?.tvVipUplevel?.setOnClickListener { dismissAllowingStateLoss() }
binding?.tvVipOrigin?.setOnClickListener { vm.saveOriginDisguise() }
try {
SVGAParser.shareParser()
.decodeFromURL(URL(vipInfo.vipLogo), object : SVGAParser.ParseCompletion {
override fun onComplete(videoItem: SVGAVideoEntity) {
val drawable = SVGADrawable(videoItem)
if (isViewLoaded) {
_binding?.ivVipIcon?.setImageDrawable(drawable)
_binding?.ivVipIcon?.startAnimation()
}
}
binding?.ivVipIconMp4?.setLoop(Int.MAX_VALUE)
override fun onError() {
}
})
} catch (e: MalformedURLException) {
val filePath = generateResourcesFilePath(vipInfo.vipLogo)
val request = DownloadRequest.build(vipInfo.vipLogo, filePath, "gift_effect_download", null, 60000L)
download(request, object : FileDownloadListener() {
override fun onDownloadCompleted(task: DownloadTask) {
val path = task.getRequest().getPath()
binding?.ivVipIconMp4?.startPlay(File(path))
}
}
override fun onDownloadError(exception: DownloadException) {
exception.printStackTrace()
}
})
// try {
// SVGAParser.shareParser()
// .decodeFromURL(URL(vipInfo.vipLogo), object : SVGAParser.ParseCompletion {
// override fun onComplete(videoItem: SVGAVideoEntity) {
// val drawable = SVGADrawable(videoItem)
// if (isViewLoaded) {
// _binding?.ivVipIcon?.setImageDrawable(drawable)
// _binding?.ivVipIcon?.startAnimation()
// }
// }
//
// override fun onError() {
// }
// })
// } catch (e: MalformedURLException) {
//
// }
binding?.tvLevelDesc?.text = getString(R.string.level_up_wear_dress_tips_format).format(vipInfo.vipName)
}
}

View File

@@ -2,7 +2,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:duration="500"
android:duration="200"
android:fromAlpha="1.0"
android:toAlpha="0" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="100"
android:fromXDelta="-100%p"
android:toXDelta="0"/>
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="100"
android:fromXDelta="100%p"
android:toXDelta="0"/>
</set>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="500"
android:fromXScale="1.3"
android:fromYScale="1.3"
android:toXScale="1"
android:toYScale="1"/>
</set>

Some files were not shown because too many files have changed in this diff Show More