遮罩层 + 历史frag UI

This commit is contained in:
renhaoting 2025-12-05 11:53:16 +08:00
parent fb1c6011e0
commit fedae8b98f
17 changed files with 787 additions and 208 deletions

View File

@ -0,0 +1,15 @@
package com.gamedog.vididin.beans
data class Transaction(
val id: Long,
val dateTime: String,
val status: TransactionStatus,
val statusText: String,
val description: String,
val amount: String,
val amountColor: Int
)
enum class TransactionStatus {
SUCCESS, FAILED, PROCESSING, REDEEM
}

View File

@ -0,0 +1,51 @@
package com.gamedog.vididin.features.withdrawrecord
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.gamedog.vididin.beans.Transaction
import com.gamedog.vididin.beans.TransactionStatus
import com.gamedog.vididin.databinding.FragmentWithdrawRecordGoldItemBinding
class TransactionAdapter : ListAdapter<Transaction, TransactionAdapter.ViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = FragmentWithdrawRecordGoldItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position))
}
inner class ViewHolder(private val binding: FragmentWithdrawRecordGoldItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(transaction: Transaction) {
binding.tvDate.text = transaction.dateTime
binding.tvStatus.text = transaction.statusText
binding.tvDescription.text = transaction.description
binding.tvAmount.text = transaction.amount
binding.tvAmount.setTextColor(ContextCompat.getColor(binding.root.context, transaction.amountColor))
// 设置状态图标
binding.tvStatusIcon.text = when (transaction.status) {
TransactionStatus.SUCCESS -> ""
TransactionStatus.FAILED -> "!"
TransactionStatus.PROCESSING -> ""
TransactionStatus.REDEEM -> ""
}
}
}
class DiffCallback : DiffUtil.ItemCallback<Transaction>() {
override fun areItemsTheSame(oldItem: Transaction, newItem: Transaction): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Transaction, newItem: Transaction): Boolean {
return oldItem == newItem
}
}
}

View File

@ -0,0 +1,19 @@
package com.gamedog.vididin.features.withdrawrecord
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.gamedog.vididin.features.withdrawrecord.fragments.DinheiroFragment
class ViewPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> DinheiroFragment()
1 -> DinheiroFragment() // 创建类似的Fragment
else -> throw IllegalArgumentException("Invalid position: $position")
}
}
}

View File

@ -10,6 +10,7 @@ import androidx.core.view.updatePadding
import com.ama.core.architecture.appBase.AppViewsActivity import com.ama.core.architecture.appBase.AppViewsActivity
import com.gamedog.vididin.R import com.gamedog.vididin.R
import com.gamedog.vididin.main.interfaces.OnTabStyleListener import com.gamedog.vididin.main.interfaces.OnTabStyleListener
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlin.getValue import kotlin.getValue
import com.gamedog.vididin.databinding.ActivityWithdrawRecordBinding as ViewBinding import com.gamedog.vididin.databinding.ActivityWithdrawRecordBinding as ViewBinding
@ -26,8 +27,7 @@ class WithdrawRecordActivity : AppViewsActivity<ViewBinding, UiState, ViewModel>
override fun ViewBinding.initViews() { override fun ViewBinding.initViews() {
with(binding) { with(binding) {
titlebar.setBackIconColor(R.color.black) setupViewPager()
titlebar.setTitleText(R.string.title_cash_record, R.color.black)
} }
} }
@ -58,6 +58,20 @@ class WithdrawRecordActivity : AppViewsActivity<ViewBinding, UiState, ViewModel>
} }
private fun setupViewPager() {
val adapter = ViewPagerAdapter(this)
binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) {
0 -> "Dinheiro"
1 -> "Moedas"
else -> null
}
}.attach()
}
companion object { companion object {
internal fun startActivity(activity: Activity) { internal fun startActivity(activity: Activity) {
activity.startActivity(Intent(activity.applicationContext, WithdrawRecordActivity::class.java)) activity.startActivity(Intent(activity.applicationContext, WithdrawRecordActivity::class.java))
@ -65,3 +79,6 @@ class WithdrawRecordActivity : AppViewsActivity<ViewBinding, UiState, ViewModel>
} }
} }

View File

@ -0,0 +1,88 @@
package com.gamedog.vididin.features.withdrawrecord.fragments
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels
import com.ama.core.architecture.appBase.AppViewsFragment
import com.ama.core.architecture.appBase.OnFragmentBackgroundListener
import com.ama.core.architecture.util.setOnClickBatch
import com.ama.core.architecture.util.setStatusBarDarkFont
import com.ama.core.common.util.dp
import com.gamedog.vididin.router.Router
import dagger.hilt.android.AndroidEntryPoint
import kotlin.getValue
import com.gamedog.vididin.databinding.VididinappFeatureMineFragmentMineBinding as ViewBinding
import com.gamedog.vididin.main.fragments.mine.MineUiState as UiState
import com.gamedog.vididin.main.fragments.mine.MineViewModel as ViewModel
@AndroidEntryPoint
class CashRecordFragment : AppViewsFragment<ViewBinding, UiState, ViewModel>(),
OnFragmentBackgroundListener {
override val mViewModel: ViewModel by viewModels()
override var isBackgroundBright: Boolean = true
private var isStatusBarDarkFont = false
override fun inflateViewBinding(
inflater: LayoutInflater,
container: ViewGroup?,
) = ViewBinding.inflate(inflater, container, false)
override fun ViewBinding.initWindowInsets() {
ViewCompat.setOnApplyWindowInsetsListener(topBackground) { v, insets ->
val systemBars =
insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
v.updatePadding(top = systemBars.top + 20.dp)
insets
}
}
override fun ViewBinding.initViews() {
setOnClickBatch(rlPrivacy, rlVersion, rlFeedback) {
when (this) {
rlPrivacy -> {
Router.Privacy.startActivity(requireActivity())
}
rlVersion -> {
Router.Version.startActivity(requireActivity())
}
rlFeedback -> {
Router.Feedback.startActivity(requireActivity())
}
}
}
}
override fun ViewBinding.initListeners() {
nestedScrollView.setOnScrollChangeListener { _, _, scrollY, _, _ ->
isStatusBarDarkFont = scrollY > topBackground.height
setStatusBarDarkFont(isStatusBarDarkFont)
}
}
override fun ViewBinding.initObservers() {
}
override fun ViewBinding.onUiStateCollect(uiState: UiState) {
//dynamicColorsSwitch.isChecked = uiState.useDynamicColor
}
override fun onResume() {
super.onResume()
setStatusBarDarkFont(isDarkFont = isStatusBarDarkFont)
}
companion object {
internal fun newInstance() = CashRecordFragment()
}
}

View File

@ -0,0 +1,77 @@
package com.gamedog.vididin.features.withdrawrecord.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.gamedog.vididin.R
import com.gamedog.vididin.beans.Transaction
import com.gamedog.vididin.beans.TransactionStatus
import com.gamedog.vididin.databinding.FragmentWithdrawRecordCashBinding
import com.gamedog.vididin.features.withdrawrecord.TransactionAdapter
class DinheiroFragment : Fragment() {
private lateinit var binding: FragmentWithdrawRecordCashBinding
private lateinit var adapter: TransactionAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentWithdrawRecordCashBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRecyclerView()
}
private fun setupRecyclerView() {
adapter = TransactionAdapter()
binding.recyclerView.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
// 模拟数据 - 根据您的截图
val transactions = listOf(
Transaction(
id = 1,
dateTime = "2025/10/31 17:30",
status = TransactionStatus.SUCCESS,
statusText = "Sucesso",
description = "Você solicitou o saque com sucesso!",
amount = "-R$ 0,1",
amountColor = R.color.red_11
),
Transaction(
id = 2,
dateTime = "2025/10/31 17:30",
status = TransactionStatus.FAILED,
statusText = "Falhou",
description = "Você solicitou o saque com sucesso!",
amount = "-R$ 0,0",
amountColor = R.color.red_11
),
Transaction(
id = 3,
dateTime = "2025/10/31 17:30",
status = TransactionStatus.PROCESSING,
statusText = "Em processamento...",
description = "Você solicitou o saque com sucesso!",
amount = "-R$ 10,0",
amountColor = R.color.red_11
),
Transaction(
id = 4,
dateTime = "2025/10/31 17:30",
status = TransactionStatus.REDEEM,
statusText = "Resgatar",
description = "Você resgatou 4980 moedas",
amount = "+R$ 10,0",
amountColor = R.color.green_39
)
)
adapter.submitList(transactions)
}
}

View File

@ -0,0 +1,88 @@
package com.gamedog.vididin.features.withdrawrecord.fragments
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.viewModels
import com.ama.core.architecture.appBase.AppViewsFragment
import com.ama.core.architecture.appBase.OnFragmentBackgroundListener
import com.ama.core.architecture.util.setOnClickBatch
import com.ama.core.architecture.util.setStatusBarDarkFont
import com.ama.core.common.util.dp
import com.gamedog.vididin.router.Router
import dagger.hilt.android.AndroidEntryPoint
import kotlin.getValue
import com.gamedog.vididin.databinding.VididinappFeatureMineFragmentMineBinding as ViewBinding
import com.gamedog.vididin.main.fragments.mine.MineUiState as UiState
import com.gamedog.vididin.main.fragments.mine.MineViewModel as ViewModel
@AndroidEntryPoint
class GoldRecordFragment : AppViewsFragment<ViewBinding, UiState, ViewModel>(),
OnFragmentBackgroundListener {
override val mViewModel: ViewModel by viewModels()
override var isBackgroundBright: Boolean = true
private var isStatusBarDarkFont = false
override fun inflateViewBinding(
inflater: LayoutInflater,
container: ViewGroup?,
) = ViewBinding.inflate(inflater, container, false)
override fun ViewBinding.initWindowInsets() {
ViewCompat.setOnApplyWindowInsetsListener(topBackground) { v, insets ->
val systemBars =
insets.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
v.updatePadding(top = systemBars.top + 20.dp)
insets
}
}
override fun ViewBinding.initViews() {
setOnClickBatch(rlPrivacy, rlVersion, rlFeedback) {
when (this) {
rlPrivacy -> {
Router.Privacy.startActivity(requireActivity())
}
rlVersion -> {
Router.Version.startActivity(requireActivity())
}
rlFeedback -> {
Router.Feedback.startActivity(requireActivity())
}
}
}
}
override fun ViewBinding.initListeners() {
nestedScrollView.setOnScrollChangeListener { _, _, scrollY, _, _ ->
isStatusBarDarkFont = scrollY > topBackground.height
setStatusBarDarkFont(isStatusBarDarkFont)
}
}
override fun ViewBinding.initObservers() {
}
override fun ViewBinding.onUiStateCollect(uiState: UiState) {
//dynamicColorsSwitch.isChecked = uiState.useDynamicColor
}
override fun onResume() {
super.onResume()
setStatusBarDarkFont(isDarkFont = isStatusBarDarkFont)
}
companion object {
internal fun newInstance() = GoldRecordFragment()
}
}

View File

@ -16,6 +16,7 @@ import com.ama.core.architecture.appBase.OnFragmentBackgroundListener
import com.ama.core.architecture.util.setStatusBarDarkFont import com.ama.core.architecture.util.setStatusBarDarkFont
import com.ama.core.common.util.asSafe import com.ama.core.common.util.asSafe
import com.gamedog.vididin.VididinEvents import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.YoutubeVideo
import com.gamedog.vididin.core.login.login.AccountManager import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.main.fragments.home.HomeFragmentStateAdapter import com.gamedog.vididin.main.fragments.home.HomeFragmentStateAdapter
import com.gamedog.vididin.main.fragments.home.fragment.HomeItemFragment import com.gamedog.vididin.main.fragments.home.fragment.HomeItemFragment
@ -116,6 +117,82 @@ class HomeFragment : AppViewsFragment<ViewBinding, UiState, ViewModel>(), OnSwit
} }
override fun ViewBinding.onUiStateCollect(uiState: UiState) { override fun ViewBinding.onUiStateCollect(uiState: UiState) {
val videoList = mutableListOf<YoutubeVideo>()
if (uiState.playLists == null) {
videoList.add(YoutubeVideo("TegalxCm1LA", "111", "bbbbb"))
videoList.add(YoutubeVideo("KA54UCs3E_4", "222", "bbbbb"))
videoList.add(YoutubeVideo("_bAxHM7O_9k", "333", "bbbbb"))
videoList.add(YoutubeVideo("6vAYPVTGs90", "444", "bbbbb"))
videoList.add(YoutubeVideo("bLAfi6cWcoI", "555", "bbbbb"))
videoList.add(YoutubeVideo("WX1MvqCzQ2k", "666", "bbbbb"))
videoList.add(YoutubeVideo("nkRPma2F4s4", "777", "bbbbb"))
videoList.add(YoutubeVideo("ssosMzYpQgc", "888", "bbbbb"))
videoList.add(YoutubeVideo("1sXHOCQcbwc", "999", "bbbbb"))
/*Iy3ml-iFkNk
TegalxCm1LA
KA54UCs3E_4
_bAxHM7O_9k
6vAYPVTGs90
bLAfi6cWcoI
WX1MvqCzQ2k
nkRPma2F4s4
PCB6ln-OS80
ssosMzYpQgc
HOnF5B0DgB4
1sXHOCQcbwc
UtyiXRHCbz0
Li4pxNp0_DU
BrB22pz87sE
u1ZV1r6kDb4
cr5YGtHdXnU
1HcDvPWd3f0
2s5iT-mFObY
a9rlrDayhPw
FC0rQTxiVZM
6Zh7iunptJ8
rIxsZXKb_0s
4dG5xqnWR3c
Kz9-4Xm66hA
3Vsu2fN31Dg
BMLVqUGtDJo
T5T0a7qMOrk
qozqA9Or8fo
3Zxt_Bx5DaU
kOrFO6uqdUA
MtPTSMddLys
a5I0y9vEIXc
wXzLu9L7ycQ
bupCgnL4TKg
7jLDu14kG84
DTrpyWQ-nAg
NK8ieGKZh7U
2owFE-4erL0
ikhXaNg_WDw
XeEknMVly-0
L3zrvfJrTkE
568jYv6tgmI
PgPIEeCOCmQ
AY5FyQSXYYc
I41E7SYNBx4
xL5Amu_srLM
upE5i_hXs7E
gR-RYjzm2UY
ISizhaStk5U
Iy3ml-iFkNk
TegalxCm1LA
KA54UCs3E_4
_bAxHM7O_9k
6vAYPVTGs90
bLAfi6cWcoI
WX1MvqCzQ2k
nkRPma2F4s4
PCB6ln-OS80
ssosMzYpQgc*/
mViewPagerAdapter.submitList(videoList)
return
}
mViewPagerAdapter.submitList(uiState.playLists) mViewPagerAdapter.submitList(uiState.playLists)
} }

View File

@ -1,7 +1,9 @@
package com.gamedog.vididin.main.fragments.home.fragment package com.gamedog.vididin.main.fragments.home.fragment
import android.graphics.Bitmap
import android.os.Bundle import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -9,6 +11,7 @@ import android.view.animation.AlphaAnimation
import android.view.animation.Animation import android.view.animation.Animation
import android.view.animation.AnimationSet import android.view.animation.AnimationSet
import android.view.animation.ScaleAnimation import android.view.animation.ScaleAnimation
import android.widget.FrameLayout
import androidx.annotation.NonNull import androidx.annotation.NonNull
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelFragment import com.ama.core.architecture.appBase.AppViewsEmptyViewModelFragment
@ -32,8 +35,8 @@ import com.gamedog.vididin.databinding.VididinappFeatureHomeItemLayoutBinding as
class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() { class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
private var mMaskBitmap: Bitmap? = null
private var mPlayerView: YouTubePlayerView? = null private var mPlayerView: YouTubePlayerView? = null
private var mIsStared = false
private var mPlayer: YouTubePlayer? = null private var mPlayer: YouTubePlayer? = null
private var mVideoData: YoutubeVideo? = null private var mVideoData: YoutubeVideo? = null
private var mIsPlaying: Boolean = false private var mIsPlaying: Boolean = false
@ -75,9 +78,9 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
} }
)) ))
setOnClickBatch(ivIntroExpand, maskView) { setOnClickBatch(ivIntroExpand, clickMaskView) {
when (this) { when (this) {
maskView -> { clickMaskView -> {
if (mIsPlaying) mPlayer?.pause() else mPlayer?.play() if (mIsPlaying) mPlayer?.pause() else mPlayer?.play()
} }
@ -100,13 +103,35 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
} }
override fun onDestroy() {
super.onDestroy()
mMaskBitmap?.recycle()
}
private fun playVideo() {
if (mPlayer != null && mVideoData != null && !mVideoData?.id.isNullOrEmpty()) {
mPlayer?.loadOrCueVideo(
lifecycle,
mVideoData!!.id,
0f
)
/*mPlayerView?.isVisible?.let {
if (!it) {
mPlayer?.pause()
}
}*/
}
}
fun loadVideo() { fun loadVideo() {
if (null == mPlayerView) { if (null == mPlayerView) {
mPlayerView = YouTubePlayerView(requireContext()) mPlayerView = YouTubePlayerView(requireContext())
binding!!.playerContainer.addView(mPlayerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) val layoutParam = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
layoutParam.gravity = Gravity.CENTER
binding!!.playerContainer.addView(mPlayerView, layoutParam)
lifecycle.addObserver(mPlayerView!!) lifecycle.addObserver(mPlayerView!!)
mPlayerView?.enableAutomaticInitialization = true mPlayerView?.enableAutomaticInitialization = true
} }
@ -120,17 +145,7 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
val playerUiController = MyPlayerControlView(playerView, youTubePlayer) val playerUiController = MyPlayerControlView(playerView, youTubePlayer)
playerView.setCustomPlayerUi(playerUiController.rootView) playerView.setCustomPlayerUi(playerUiController.rootView)
if (mVideoData != null && !mVideoData?.id.isNullOrEmpty()) { playVideo()
youTubePlayer.loadOrCueVideo(
lifecycle,
mVideoData!!.id,
0f
)
if (!playerView.isVisible) {
youTubePlayer.pause()
}
}
} }
override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) { override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) {
@ -164,9 +179,10 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
} }
PlayerConstants.PlayerState.ENDED -> { PlayerConstants.PlayerState.ENDED -> {
togglePlayingState(false) togglePlayingState(false)
playVideo()
} }
PlayerConstants.PlayerState.BUFFERING -> { PlayerConstants.PlayerState.BUFFERING -> {
togglePlayingState(false) //togglePlayingState(false)
} }
PlayerConstants.PlayerState.VIDEO_CUED -> { PlayerConstants.PlayerState.VIDEO_CUED -> {
togglePlayingState(false) togglePlayingState(false)
@ -176,10 +192,28 @@ class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
}) })
} }
private fun generateThumbAndSet() {
// capturePlayerView And Show as thumb
mPlayerView?.let {
mMaskBitmap?.recycle()
mMaskBitmap = AndroidUtil.getThumbOfView(it)
mMaskBitmap?.let {
binding?.ivMask?.setImageBitmap(mMaskBitmap)
}
}
}
private fun togglePlayingState(isPlaying: Boolean) { private fun togglePlayingState(isPlaying: Boolean) {
if (mIsPlaying != isPlaying) { if (mIsPlaying != isPlaying) {
mIsPlaying = isPlaying mIsPlaying = isPlaying
binding?.ivMask?.isVisible = !mIsPlaying if (!mIsPlaying) {
generateThumbAndSet()
}
binding?.ivMask?.isVisible = false/*!mIsPlaying*/
binding?.playerContainer?.isVisible = isPlaying
if (mIsPlaying) { if (mIsPlaying) {
hidePlayIconAnim() hidePlayIconAnim()

View File

@ -2,210 +2,63 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/content_root"> android:id="@+id/content_root">
<com.ama.core.architecture.widget.CustomTitleBar
android:id="@+id/titlebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<LinearLayout <LinearLayout
android:id="@+id/ll_left_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="44dp"
android:layout_marginHorizontal="15dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_date_win"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textSize="12sp"
android:textColor="@color/gray6"
android:text="2025/10/31"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/bg_records_win"
android:layout_marginTop="5dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingVertical="5dp" android:orientation="horizontal">
>
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_left_win" android:id="@+id/iv_back"
android:layout_width="45dp" android:layout_width="wrap_content"
android:layout_height="45dp" android:paddingLeft="16dp"
android:src="@mipmap/record_win" android:layout_height="match_parent"
android:layout_centerVertical="true" android:src="@mipmap/icon_back"
android:layout_marginLeft="15dp" android:tint="@color/black"
/> />
<LinearLayout <com.google.android.material.tabs.TabLayout
android:layout_width="wrap_content" android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:layout_weight="1"
android:layout_marginHorizontal="10dp" android:layout_marginStart="20dp"
android:layout_toRightOf="@+id/iv_left_win" app:tabTextColor="@color/black"
android:layout_toLeftOf="@+id/ll_right_win" app:tabSelectedTextColor="@color/green_39"
android:layout_centerVertical="true" app:tabIndicatorColor="@color/transparent"
app:tabIndicator="@null"
app:tabIndicatorHeight="0dp"
app:tabBackground="@color/transparent"
app:tabRippleColor="@null"
app:tabMode="fixed"
> >
<androidx.appcompat.widget.AppCompatTextView <com.google.android.material.tabs.TabItem
android:id="@+id/tv_title_win"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="15sp" android:text="Dinheiro" />
android:textColor="@color/white"
android:text="@string/record_win_item_title"
/>
<androidx.appcompat.widget.AppCompatTextView <com.google.android.material.tabs.TabItem
android:id="@+id/tv_desc_win"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:text="Moedas" />
android:textSize="14sp" </com.google.android.material.tabs.TabLayout>
android:textColor="@color/white_alpha_99"
android:text="@string/record_win_item_desc"
/>
</LinearLayout> </LinearLayout>
<LinearLayout <androidx.viewpager2.widget.ViewPager2
android:id="@+id/ll_right_win" android:id="@+id/viewPager"
android:layout_width="75dp"
android:layout_height="75dp"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@mipmap/bg_record_win_rgiht"
android:paddingHorizontal="6dp"
android:gravity="center_horizontal"
>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_win_right_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:textSize="15sp"
android:textColor="@color/yellow_00"
android:text="Ganhar"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_win_right_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="11dp"
android:textSize="10sp"
android:textColor="@color/green_54"
android:text="Ver detalhes"
/>
</LinearLayout>
</RelativeLayout>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_date_lost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:textSize="12sp"
android:textColor="@color/gray6"
android:text="2025/10/31"
/>
<RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:orientation="horizontal" android:layout_weight="1" />
android:background="@drawable/bg_records_lost"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:paddingVertical="5dp"
>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_left_lost"
android:layout_width="45dp"
android:layout_height="45dp"
android:src="@mipmap/record_lost"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginHorizontal="10dp"
android:layout_toRightOf="@+id/iv_left_lost"
android:layout_toLeftOf="@+id/ll_right_lost"
android:layout_centerVertical="true"
>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_title_lost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="@color/white"
android:text="@string/record_lost_item_title"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_desc_lost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="14sp"
android:textColor="@color/white_alpha_99"
android:text="@string/record_lost_item_desc"
/>
</LinearLayout>
<FrameLayout
android:id="@+id/ll_right_lost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="5dp"
android:background="@mipmap/bg_record_lost_rgiht"
android:paddingHorizontal="6dp"
android:gravity="center"
>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_lost_right_top"
android:layout_width="75dp"
android:layout_height="75dp"
android:textStyle="bold"
android:gravity="center"
android:layout_gravity="center"
android:textSize="15sp"
android:textColor="@color/gray9"
android:text="@string/not_win"
/>
</FrameLayout>
</RelativeLayout>
</LinearLayout> </LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Total sacado até o momento: R$ 0,1"
android:textSize="16sp"
android:textColor="@color/black"
android:layout_marginBottom="16dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/tvDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2025/10/31 17:30"
android:textSize="12sp"
android:textColor="@color/gray6" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp">
<TextView
android:id="@+id/tvStatusIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="✔"
android:textSize="14sp"
android:textColor="@color/green_39"
android:layout_marginEnd="8dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sucesso"
android:textSize="14sp"
android:textColor="@color/black" />
<TextView
android:id="@+id/tvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Você solicitou o saque com sucesso!"
android:textSize="12sp"
android:textColor="@color/gray6" />
</LinearLayout>
<TextView
android:id="@+id/tvAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-R$ 0,1"
android:textSize="14sp"
android:textColor="@color/red_5c" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Total sacado até o momento: R$ 0,1"
android:textSize="16sp"
android:textColor="@color/black"
android:layout_marginBottom="16dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/tvDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="2025/10/31 17:30"
android:textSize="12sp"
android:textColor="@color/gray6" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="4dp">
<TextView
android:id="@+id/tvStatusIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="✔"
android:textSize="14sp"
android:textColor="@color/green_39"
android:layout_marginEnd="8dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tvStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sucesso"
android:textSize="14sp"
android:textColor="@color/black" />
<TextView
android:id="@+id/tvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Você solicitou o saque com sucesso!"
android:textSize="12sp"
android:textColor="@color/gray6" />
</LinearLayout>
<TextView
android:id="@+id/tvAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-R$ 0,1"
android:textSize="14sp"
android:textColor="@color/red_5c" />
</LinearLayout>
</LinearLayout>

View File

@ -15,13 +15,15 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/black" android:background="@color/black"
android:clickable="false"
android:layout_gravity="center"/> android:layout_gravity="center"/>
<View <View
android:id="@+id/mask_view" android:id="@+id/click_mask_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true" android:clickable="true"
android:layout_marginBottom="30dp"
/> />

View File

@ -4,14 +4,18 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import com.ama.core.architecture.BaseApp import com.ama.core.architecture.BaseApp
import kotlin.random.Random import kotlin.random.Random
import androidx.core.graphics.createBitmap
class AndroidUtil private constructor() { class AndroidUtil private constructor() {
@ -92,6 +96,31 @@ class AndroidUtil private constructor() {
} }
fun getThumbOfView(targetView: View): Bitmap? {
targetView.isDrawingCacheEnabled = true
targetView.buildDrawingCache()
val bitmap = Bitmap.createBitmap(targetView.drawingCache)
targetView.isDrawingCacheEnabled = false
return bitmap
}
fun getThumbOfView2(targetView: View): Bitmap {
if (targetView.width <= 0 || targetView.height <= 0) {
val widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
val heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
targetView.measure(widthSpec, heightSpec)
targetView.layout(0, 0, targetView.measuredWidth, targetView.measuredHeight)
}
val bitmap = createBitmap(targetView.measuredWidth, targetView.measuredHeight)
val canvas = Canvas(bitmap)
targetView.draw(canvas)
return bitmap
}
} }
} }

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View import android.view.View
import androidx.core.graphics.withSave import androidx.core.graphics.withSave
import com.ama.core.architecture.R import com.ama.core.architecture.R
@ -57,4 +58,60 @@ class CustomProgressBar(context: Context, attrs: AttributeSet) : View(context, a
mForColor = ResUtil.getColor(forColor) mForColor = ResUtil.getColor(forColor)
invalidate() invalidate()
} }
//--------------------------- New added ----------------------------
private var onProgressChangeListener: OnProgressChangeListener? = null
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
parent.requestDisallowInterceptTouchEvent(true)
updateProgressFromTouch(event.x)
return true
} }
MotionEvent.ACTION_MOVE -> {
updateProgressFromTouch(event.x)
return true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
parent.requestDisallowInterceptTouchEvent(false)
updateProgressFromTouch(event.x, true)
return true
}
}
return super.onTouchEvent(event)
}
private fun updateProgressFromTouch(touchX: Float, notifyNewProgress: Boolean = false) {
val width = width.toFloat()
if (width > 0) {
var newProgress = (touchX / width * max).toInt()
newProgress = newProgress.coerceIn(0, max)
if (newProgress != progress) {
setProgress(newProgress)
if (notifyNewProgress) {
onProgressChangeListener?.onProgressChanged(newProgress)
}
}
}
}
fun setOnProgressChangeListener(listener: OnProgressChangeListener) {
this.onProgressChangeListener = listener
}
interface OnProgressChangeListener {
fun onProgressChanged(progress: Int)
}
}