feat: 更新 VIP 页面 UI & 功能
@@ -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()) {
|
||||
|
@@ -734,7 +734,10 @@
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".vip.VipMainActivity"
|
||||
android:screenOrientation="portrait" /> <!-- 隐私设置 -->
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".vip.VipCenterActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".vip.VipSettingActivity"
|
||||
android:screenOrientation="portrait" /> <!-- 通知提醒设置 -->
|
||||
|
@@ -35,6 +35,7 @@ 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.VipCenterActivity
|
||||
import com.chwl.app.vip.VipMainActivity
|
||||
import com.chwl.app.vip.VipViewModel
|
||||
import com.chwl.core.auth.AuthModel
|
||||
@@ -353,7 +354,8 @@ class MeFragment : BaseFragment(), View.OnClickListener {
|
||||
}
|
||||
|
||||
R.id.iv_vip -> {
|
||||
VipMainActivity.start(mContext)
|
||||
// VipMainActivity.start(mContext)
|
||||
VipCenterActivity.start(mContext)
|
||||
//进入贵族中心埋点
|
||||
val goldWalletInfo = PayModel.get().currentWalletInfo
|
||||
val map = HashMap<String, Any>(5)
|
||||
|
403
app/src/main/java/com/chwl/app/vip/VipCenterActivity.kt
Normal file
@@ -0,0 +1,403 @@
|
||||
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.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
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.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.module_base.support.billing.IBillingService
|
||||
import com.example.module_base.support.billing.IProductDetails
|
||||
import com.example.module_base.support.billing.IPurchase
|
||||
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
|
||||
|
||||
|
||||
class VipCenterActivity : BaseViewBindingActivity<ActivityVipCenterBinding>(),
|
||||
VipMagicIndicatorAdapter.OnItemSelectListener, IBillingService.Listener {
|
||||
|
||||
private val authAdapter = VipAuthAdapter() // 用户权限
|
||||
private val vipViewModel: VipViewModel by viewModels()
|
||||
private var chargeList: List<ChargeBean>? = 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
|
||||
|
||||
// protected var banner: Banner? = null
|
||||
|
||||
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)
|
||||
initWhiteTitleBar(getString(R.string.vip_center))
|
||||
|
||||
initView()
|
||||
initObserve()
|
||||
|
||||
handleAuthAdapter()
|
||||
handleViewModel()
|
||||
handleBinding()
|
||||
|
||||
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()
|
||||
|
||||
authAdapter.setOnItemClickListener { _, _, position ->
|
||||
authAdapter.getItem(position)?.let {
|
||||
VipAuthDetailsDialog.newInstance(it.descPic, it.authName, it.authIntro).show(this)
|
||||
}
|
||||
}
|
||||
|
||||
requestChargeList{
|
||||
loadChargeList(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
banner = findViewById(R.id.banner_view)
|
||||
banner.isAutoLoop(false)
|
||||
banner.setBannerGalleryEffect(25, 25,25)
|
||||
|
||||
recyclerView = findViewById(R.id.recycler_view)
|
||||
recyclerView.layoutManager = GridLayoutManager(this, 2)
|
||||
|
||||
// val identificationTitle = findViewById<TextView>(R.id.center_title)
|
||||
// identificationTitle.text = R.string.vip_center_2.toString()
|
||||
//
|
||||
// val exclusivePrivilegesTitle = findViewById<TextView>(R.id.center_title_2)
|
||||
// exclusivePrivilegesTitle.text = R.string.vip_center_4.toString()
|
||||
}
|
||||
|
||||
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.color_FFE3AF))
|
||||
mTitleBar.setLeftImageResource(R.drawable.vip_center_back_button)
|
||||
mTitleBar.setBackgroundResource(R.color.transparent)
|
||||
mTitleBar.setLeftClickListener { onLeftClickListener() }
|
||||
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
|
||||
}
|
||||
|
||||
private fun handleViewModel() {
|
||||
vipViewModel.getVipPageInfo()
|
||||
|
||||
vipViewModel.loadingLiveData.observe(this) {
|
||||
if (it == true) {
|
||||
dialogManager.showProgressDialog(this)
|
||||
} else {
|
||||
dialogManager.dismissDialog()
|
||||
}
|
||||
}
|
||||
|
||||
vipViewModel.authInfosLiveData.observe(this) {
|
||||
// ArrayList[VipAuthInfo] // 全部特权列表
|
||||
authAdapter.setNewData(it)
|
||||
it?.let {
|
||||
vipIdentificationsAdapter = VipCenterIdentificationsAdapter(this, it)
|
||||
recyclerView.adapter = vipIdentificationsAdapter
|
||||
}
|
||||
}
|
||||
|
||||
vipViewModel.pageLiveData.observe(this) {
|
||||
it?.let { // 当前显示的 index
|
||||
// binding.magicIndicator.onPageSelected(it)
|
||||
// TODO 处理轮播组件 index 更新
|
||||
}
|
||||
}
|
||||
|
||||
vipViewModel.vipInfosLiveData.observe(this) {
|
||||
it?.let { // ArrayList[VipInfo] 每个等级的 VIP 内容
|
||||
// initTitleTab(it)
|
||||
// TODO 初始化轮播组件
|
||||
val adapter = VipCenterBannerAdapter(this, it)
|
||||
banner.setAdapter(adapter)
|
||||
|
||||
// banner.setAdapter(object : BannerImageAdapter<VipInfo>(it) {
|
||||
// override fun onBindView(holder: BannerImageHolder, data: VipInfo, position: Int, size: Int) {
|
||||
// //图片加载自己实现
|
||||
// Glide.with(holder.itemView)
|
||||
// .load(data.vipIcon)
|
||||
// .apply(RequestOptions.bitmapTransform(RoundedCorners(30)))
|
||||
// .into(holder.imageView)
|
||||
// }
|
||||
// override fun onCreateHolder(
|
||||
// parent: ViewGroup?,
|
||||
// viewType: Int
|
||||
// ): BannerImageHolder {
|
||||
// return super.onCreateHolder(parent, viewType)
|
||||
// }
|
||||
// }).addBannerLifecycleObserver(this)
|
||||
// .setIndicator(CircleIndicator(this), false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vipViewModel.myVipInfoLiveData.observe(this) {
|
||||
it?.let {
|
||||
//TODO 处理有 VIP 的情况
|
||||
// bannerView.visibility = View.VISIBLE
|
||||
// bannerView.post {
|
||||
// binding.bannerView.setPageMargin(UIUtil.dip2px(mContext, 8.0))
|
||||
// .setScrollDuration(800)
|
||||
// .setOnPageClickListener { _: View?, position: Int ->
|
||||
// }
|
||||
// .create(it)
|
||||
// }
|
||||
} ?: 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
|
||||
// TODO 根据当前显示的 VIP 信息更新 UI
|
||||
} ?: run {
|
||||
getString(R.string.me_failed_to_get_aristocrat_data).toast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
refreshOpenVipState()
|
||||
}
|
||||
|
||||
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@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 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)) {
|
||||
"${currentChargeInfo?.getMoney()} ${
|
||||
getString(R.string.vip_buy_format).format(
|
||||
currentVipInfo.vipName
|
||||
)
|
||||
}".also { binding.tvOpenVip.text = it }
|
||||
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)
|
||||
// }
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
}
|
@@ -546,12 +546,11 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
|
||||
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
|
||||
)
|
||||
}"
|
||||
}".also { binding.tvOpenVip.text = it }
|
||||
binding.layoutOpenVip.isVisible = true
|
||||
} else {
|
||||
binding.layoutOpenVip.isVisible = false
|
||||
|
@@ -0,0 +1,49 @@
|
||||
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 androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.chwl.app.R
|
||||
import com.chwl.core.vip.bean.VipInfo
|
||||
import com.youth.banner.adapter.BannerAdapter
|
||||
|
||||
class VipCenterBannerAdapter(
|
||||
private val context: Context,
|
||||
private val vipInfos: List<VipInfo>
|
||||
) : BannerAdapter<VipInfo, VipCenterBannerAdapter.BannerViewHolder>(vipInfos) {
|
||||
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) {
|
||||
// 加载本地背景图片
|
||||
when(position) {
|
||||
1->holder.imgBackground.setImageResource(R.drawable.vip_center_level_1)
|
||||
2->holder.imgBackground.setImageResource(R.drawable.vip_center_level_2)
|
||||
3->holder.imgBackground.setImageResource(R.drawable.vip_center_level_3)
|
||||
4->holder.imgBackground.setImageResource(R.drawable.vip_center_level_4)
|
||||
5->holder.imgBackground.setImageResource(R.drawable.vip_center_level_5)
|
||||
6->holder.imgBackground.setImageResource(R.drawable.vip_center_level_6)
|
||||
7->holder.imgBackground.setImageResource(R.drawable.vip_center_level_7)
|
||||
8->holder.imgBackground.setImageResource(R.drawable.vip_center_level_8)
|
||||
9->holder.imgBackground.setImageResource(R.drawable.vip_center_level_9)
|
||||
}
|
||||
|
||||
// 加载网络图片
|
||||
Glide.with(context)
|
||||
.load(data.vipIcon) // data 是图片的 URL
|
||||
.into(holder.imgForeground)
|
||||
}
|
||||
|
||||
inner class BannerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val imgBackground: ImageView = view.findViewById(R.id.img_background)
|
||||
val imgForeground: ImageView = view.findViewById(R.id.img_foreground)
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
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.bumptech.glide.Glide
|
||||
import com.chwl.app.R
|
||||
import com.chwl.core.vip.bean.VipAuthInfo
|
||||
|
||||
class VipCenterIdentificationsAdapter(
|
||||
private val context: Context,
|
||||
private val items: List<VipAuthInfo>
|
||||
) : RecyclerView.Adapter<VipCenterIdentificationsAdapter.ItemViewHolder>() {
|
||||
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 item = items[position]
|
||||
|
||||
// 加载内容图片
|
||||
Glide.with(context)
|
||||
.load(item.authIcon)
|
||||
.into(holder.contentImageView)
|
||||
|
||||
// 设置标题
|
||||
holder.titleTextView.text = item.authName
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return items.size
|
||||
}
|
||||
|
||||
inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
// val backgroundImageView: ImageView = view.findViewById(R.id.background_image)
|
||||
val contentImageView: ImageView = view.findViewById(R.id.item_image)
|
||||
val titleTextView: TextView = view.findViewById(R.id.item_title)
|
||||
}
|
||||
}
|
||||
|
BIN
app/src/main/res/drawable-xhdpi/vip_center_back_button.webp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_background.webp
Normal file
After Width: | Height: | Size: 642 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_help_button.webp
Normal file
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 6.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_label_decorate.webp
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_1.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_2.webp
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_3.webp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_4.webp
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_5.webp
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_6.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_7.webp
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_8.webp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_level_9.webp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_purchase_bg.webp
Normal file
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable-xhdpi/vip_center_purchase_coin.webp
Normal file
After Width: | Height: | Size: 7.3 KiB |
255
app/src/main/res/layout/activity_vip_center.xml
Normal file
@@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#150c00"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:id="@+id/view_top"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/vip_center_background"
|
||||
app:layout_constraintDimensionRatio="750:820"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.chwl.app.base.TitleBar
|
||||
android:id="@+id/title_bar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.youth.banner.Banner
|
||||
android:id="@+id/banner_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginTop="20dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_bar"
|
||||
android:visibility="visible"
|
||||
app:bvp_auto_play="false"
|
||||
app:bvp_can_loop="false"
|
||||
app:bvp_indicator_visibility="gone"
|
||||
app:bvp_page_style="multi_page_scale"
|
||||
app:layout_constraintDimensionRatio="351:80"
|
||||
app:layout_goneMarginTop="@dimen/dp_16"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/sl_auth"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="@dimen/dp_80"
|
||||
android:fillViewport="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/banner_view">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center_horizontal">
|
||||
<!-- 这部分是你的标题和左右两侧图片 -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<!-- 左侧图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/left_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="18dp"
|
||||
android:src="@drawable/vip_center_label_decorate"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- 右侧图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/right_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="18dp"
|
||||
android:scaleX="-1"
|
||||
android:src="@drawable/vip_center_label_decorate"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- 中央标题 -->
|
||||
<TextView
|
||||
android:id="@+id/center_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Identification"
|
||||
android:text="@string/vip_center_3"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
app:layout_constraintStart_toEndOf="@id/left_image"
|
||||
app:layout_constraintEnd_toStartOf="@id/right_image"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- 新增的 RecyclerView,用于显示 API 数据 -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical"
|
||||
tools:listitem="@layout/vip_center_idnetifications_layout"
|
||||
tools:itemCount="2" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/vip_center_title_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<!-- 左侧图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/left_image_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="18dp"
|
||||
android:src="@drawable/vip_center_label_decorate"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- 右侧图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/right_image_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="18dp"
|
||||
android:scaleX="-1"
|
||||
android:src="@drawable/vip_center_label_decorate"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- 中央标题 -->
|
||||
<TextView
|
||||
android:id="@+id/center_title_2"
|
||||
android:maxLines="2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Exclusive Privileges\n(3/13)"
|
||||
android:text="@string/vip_center_4"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
app:layout_constraintStart_toEndOf="@id/left_image_2"
|
||||
app:layout_constraintEnd_toStartOf="@id/right_image_2"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view_bottom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginBottom="165dp"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/vip_center_title_2"
|
||||
app:layout_constraintVertical_bias="0" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_bottom_panel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="53dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="26dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/vip_center_purchase_bg"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="16dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
<TextView
|
||||
android:id="@+id/tv_open_vip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="4dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="@color/color_FFE3AF"
|
||||
android:textSize="@dimen/sp_13"
|
||||
android:textStyle="bold"
|
||||
app:drawableLeftCompat="@drawable/vip_center_purchase_coin"
|
||||
tools:text="19.99/30Days"
|
||||
android:text="@string/vip_center_5"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_additional_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="5dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="@color/color_FFE3AF"
|
||||
android:textSize="@dimen/sp_11"
|
||||
tools:text="Date to Expires"
|
||||
android:text="@string/vip_center_6"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 右侧按钮 -->
|
||||
<Button
|
||||
android:id="@+id/layout_open_vip"
|
||||
android:layout_width="147dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:background="@drawable/vip_center_purchase_button_bg"
|
||||
android:textColor="@color/color_633000"
|
||||
android:textSize="@dimen/sp_16"
|
||||
android:text="@string/vip_center_7"
|
||||
tools:text="Renew" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
50
app/src/main/res/layout/banner_vip_center_custom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible">
|
||||
<!-- 本地背景图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/img_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintDimensionRatio="320:136"
|
||||
android:src="@drawable/vip_center_level_1" />
|
||||
<!-- 网络图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/img_foreground"
|
||||
android:layout_width="@dimen/dp_130"
|
||||
android:layout_height="@dimen/dp_130"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_marginEnd="13dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:src="@drawable/vip_center_purchase_button_bg" />
|
||||
</FrameLayout>
|
||||
<TextView
|
||||
android:id="@+id/due_date_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/vip_center_2"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="18dp"
|
||||
android:layout_marginBottom="26dp" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="8dp">
|
||||
|
||||
<!-- 背景图片 -->
|
||||
<ImageView
|
||||
android:id="@+id/item_background"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/vip_center_identification_card"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintDimensionRatio="166:120"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_image"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/item_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="@color/color_FFE3AF"
|
||||
android:textSize="13sp"
|
||||
android:gravity="center"
|
||||
tools:text="1234567"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/item_image" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@@ -5343,4 +5343,11 @@
|
||||
<string name="game_team_18">%s ساعة</string>
|
||||
<string name="game_team_19">تم تقديم الطلب بنجاح</string>
|
||||
|
||||
<string name="vip_center_1">Activate VIP</string>
|
||||
<string name="vip_center_2">Due on:</string>
|
||||
<string name="vip_center_3">Identification</string>
|
||||
<string name="vip_center_4">Exclusive Privileges/n</string>
|
||||
<string name="vip_center_5">Days</string>
|
||||
<string name="vip_center_6"> Expires</string>
|
||||
<string name="vip_center_7">Renew</string>
|
||||
</resources>
|
@@ -5283,4 +5283,13 @@
|
||||
<string name="game_team_17">和我一起玩遊戲吧~</string>
|
||||
<string name="game_team_18">%s小時</string>
|
||||
<string name="game_team_19">下單成功~</string>
|
||||
|
||||
<string name="vip_center_1">Activate VIP</string>
|
||||
<string name="vip_center_2">Due on:</string>
|
||||
<string name="vip_center_3">Identification</string>
|
||||
<string name="vip_center_4">Exclusive Privileges/n</string>
|
||||
<string name="vip_center_5">Days</string>
|
||||
<string name="vip_center_6"> Expires</string>
|
||||
<string name="vip_center_7">Renew</string>
|
||||
|
||||
</resources>
|
@@ -747,4 +747,7 @@
|
||||
<color name="color_002512">#002512</color>
|
||||
<color name="color_3FDDAC">#3FDDAC</color>
|
||||
<color name="color_0FCA81">#0FCA81</color>
|
||||
|
||||
<color name="color_FFE3AF">#FFE3AF</color>
|
||||
<color name="color_633000">#633000</color>
|
||||
</resources>
|
||||
|
@@ -5323,6 +5323,14 @@ You cannot join again within 24 hours after leaving</string>
|
||||
<string name="game_team_18">%s Hour</string>
|
||||
<string name="game_team_19">successfully ordered</string>
|
||||
|
||||
<string name="vip_center_1">Activate VIP</string>
|
||||
<string name="vip_center_2">Due on:</string>
|
||||
<string name="vip_center_3">Identification</string>
|
||||
<string name="vip_center_4">Exclusive Privileges/n</string>
|
||||
<string name="vip_center_5">Days</string>
|
||||
<string name="vip_center_6"> Expires</string>
|
||||
<string name="vip_center_7">Renew</string>
|
||||
|
||||
</resources>
|
||||
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
|