Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
A
appzxhy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhouzhi
appzxhy
Commits
f43b9a38
Commit
f43b9a38
authored
Mar 19, 2025
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
4f5c6253
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
703 additions
and
826 deletions
+703
-826
build.gradle.kts
Drouter/build.gradle.kts
+4
-0
AppService.kt
Drouter/src/main/java/com/koko/drouter/app/AppService.kt
+9
-2
BaseActivity.kt
Drouter/src/main/java/com/koko/drouter/base/BaseActivity.kt
+14
-55
AdCountDownDialog.kt
app/src/main/java/com/base/appzxhy/ads/AdCountDownDialog.kt
+67
-0
AdEvent.kt
app/src/main/java/com/base/appzxhy/ads/AdEvent.kt
+4
-4
AdsMgr.kt
app/src/main/java/com/base/appzxhy/ads/AdsMgr.kt
+20
-24
AdsShowCallBack.kt
app/src/main/java/com/base/appzxhy/ads/AdsShowCallBack.kt
+1
-1
LimitUtils.kt
app/src/main/java/com/base/appzxhy/ads/LimitUtils.kt
+7
-2
NativeParentView.kt
app/src/main/java/com/base/appzxhy/ads/NativeParentView.kt
+0
-110
AdInterMgr.kt
app/src/main/java/com/base/appzxhy/ads/admob/AdInterMgr.kt
+34
-55
AdNativeMgr.kt
app/src/main/java/com/base/appzxhy/ads/admob/AdNativeMgr.kt
+44
-53
AdOpenMgr.kt
app/src/main/java/com/base/appzxhy/ads/admob/AdOpenMgr.kt
+36
-52
AdmobAdState.kt
app/src/main/java/com/base/appzxhy/ads/admob/AdmobAdState.kt
+63
-0
AdmobEvent.kt
app/src/main/java/com/base/appzxhy/ads/admob/AdmobEvent.kt
+5
-5
AdMaxEvent.kt
...src/main/java/com/base/appzxhy/ads/applovin/AdMaxEvent.kt
+0
-1
MaxAdState.kt
...src/main/java/com/base/appzxhy/ads/applovin/MaxAdState.kt
+59
-0
MaxInsertMgr.kt
...c/main/java/com/base/appzxhy/ads/applovin/MaxInsertMgr.kt
+57
-78
MaxNativeMgr.kt
...c/main/java/com/base/appzxhy/ads/applovin/MaxNativeMgr.kt
+36
-5
MaxOpenMgr.kt
...src/main/java/com/base/appzxhy/ads/applovin/MaxOpenMgr.kt
+63
-94
BaseActivity.kt
app/src/main/java/com/base/appzxhy/base/BaseActivity.kt
+0
-199
BaseFragment.kt
app/src/main/java/com/base/appzxhy/base/BaseFragment.kt
+0
-73
HomeFragment.kt
app/src/main/java/com/base/appzxhy/ui/main/HomeFragment.kt
+1
-1
MainActivity.kt
app/src/main/java/com/base/appzxhy/ui/main/MainActivity.kt
+52
-7
StartActivity.kt
app/src/main/java/com/base/appzxhy/ui/start/StartActivity.kt
+16
-1
StartViewModel.kt
...src/main/java/com/base/appzxhy/ui/start/StartViewModel.kt
+42
-0
bg_ffffff_15.xml
app/src/main/res/drawable/bg_ffffff_15.xml
+8
-0
activity_main.xml
app/src/main/res/layout/activity_main.xml
+3
-4
dialog_ad_countdown.xml
app/src/main/res/layout/dialog_ad_countdown.xml
+54
-0
zhuanquan.png
app/src/main/res/mipmap-xxhdpi/zhuanquan.png
+0
-0
dimens.xml
app/src/main/res/values/dimens.xml
+4
-0
No files found.
Drouter/build.gradle.kts
View file @
f43b9a38
...
...
@@ -46,4 +46,8 @@ dependencies {
api
(
libs
.
drouter
.
api
)
api
(
libs
.
drouter
.
api
.
page
)
api
(
libs
.
drouter
.
api
.
process
)
// 语种切换框架:https://github.com/getActivity/MultiLanguages
api
(
"com.github.getActivity:MultiLanguages:9.3"
)
}
\ No newline at end of file
Drouter/src/main/java/com/koko/drouter/app/AppService.kt
View file @
f43b9a38
...
...
@@ -2,7 +2,7 @@ package com.koko.drouter.app
import
android.app.Activity
import
com.didi.drouter.api.DRouter
import
com.koko.drouter.ad.NativeAdServic
e
import
java.util.Local
e
val
appService
by
lazy
{
...
...
@@ -11,7 +11,14 @@ val appService by lazy {
interface
AppService
{
fun
eventActivity
()
=
Unit
fun
getCurrentSpLocal
():
Locale
fun
changeActivityLanguage
(
activity
:
Activity
,
currentLocale
:
Locale
,
changeAction
:
()
->
Unit
):
Boolean
fun
finishToMain
()
=
Unit
...
...
Drouter/src/main/java/com/koko/drouter/base/BaseActivity.kt
View file @
f43b9a38
package
com.koko.drouter.base
import
android.content.Context
import
android.graphics.Color
import
android.os.Bundle
import
android.view.LayoutInflater
...
...
@@ -10,7 +11,9 @@ import androidx.core.view.ViewCompat
import
androidx.core.view.WindowInsetsCompat
import
androidx.viewbinding.ViewBinding
import
com.didi.drouter.api.DRouter
import
com.hjq.language.MultiLanguages
import
com.koko.drouter.app.AppService
import
com.koko.drouter.app.appService
import
com.koko.drouter.event.EventService
import
java.util.Locale
import
java.util.concurrent.atomic.AtomicBoolean
...
...
@@ -27,7 +30,8 @@ abstract class BaseActivity<VB : ViewBinding>(
}
lateinit
var
launcher
:
ActivityLauncher
private
var
currentLocale
:
Locale
?
=
null
private
var
currentLocale
:
Locale
=
appService
.
getCurrentSpLocal
()
private
var
isLanguageRecreate
:
Boolean
=
false
//判断当前activity有没有因为切换语言重新创建
private
val
eventService
by
lazy
{
DRouter
.
build
(
EventService
::
class
.
java
).
getService
()
...
...
@@ -42,14 +46,19 @@ abstract class BaseActivity<VB : ViewBinding>(
// LogEx.logDebug(TAG, "lifecycle $tagNo onCreate ${javaClass.simpleName} $onCreateI")
launcher
=
ActivityLauncher
(
this
)
setContentView
(
binding
.
root
)
eventActivity
()
// currentLocale = Locale(appLanguageSp, appLanguageCountrySp
)
changeLanguage
(
)
initView
()
initListener
()
initData
()
}
private
fun
changeLanguage
()
{
isLanguageRecreate
=
appService
.
changeActivityLanguage
(
this
,
currentLocale
)
{
currentLocale
=
appService
.
getCurrentSpLocal
()
}
}
open
fun
initData
()
{}
open
fun
useDefaultImmersive
()
{
...
...
@@ -62,7 +71,6 @@ abstract class BaseActivity<VB : ViewBinding>(
}
private
fun
eventActivity
()
{
val
eventService
=
DRouter
.
build
(
EventService
::
class
.
java
).
getService
()
eventService
.
eventActivity
(
this
)
}
...
...
@@ -81,57 +89,8 @@ abstract class BaseActivity<VB : ViewBinding>(
super
.
onDestroy
()
}
// override fun attachBaseContext(newBase: Context?) {
// super.attachBaseContext(MultiLanguages.attach(newBase))
// }
// fun changeLanguage(currentActivity: Activity, bundle: Bundle = Bundle()): Boolean {
// val spLanguage = Locale(appLanguageSp, appLanguageCountrySp)
// val flag = currentLocale != spLanguage
// val restart = MultiLanguages.setAppLanguage(this, spLanguage)
// LogEx.logDebug(
// TAG, "changeLanguage " +
// "flag=$flag restart=$restart currentLocale=$currentLocale spLanguage=$spLanguage"
// )
// if (restart) {
// currentLocale = Locale(appLanguageSp, appLanguageCountrySp)
// }
//
// if (flag || restart) {
// // 1.使用 recreate 来重启 Activity,效果差,有闪屏的缺陷
//// recreate();
//
// // 2.使用常规 startActivity 来重启 Activity,有从左向右的切换动画
// // 稍微比 recreate 的效果好一点,但是这种并不是最佳的效果
// // startActivity(new Intent(this, LanguageActivity.class));
// // finish();
//
// // 3.我们可以充分运用 Activity 跳转动画,在跳转的时候设置一个渐变的效果,相比前面的两种带来的体验是最佳的
// //需要设置启动模式,避免AndroidManifest.xml设置singleTop启动模式导致重复启动不生效
// //这种方式如果设置了singleTop或者singleTask的,再次回到该activity无法改变于语言,因为还在堆栈里没有重新创建
// needRecreate()
// if (needRecreate()) {
// LogEx.logDebug(TAG, "changeLanguage recreate")
// recreate()
// } else {
// startActivity(Intent(this, currentActivity::class.java).apply {
// putExtras(bundle)
// })
// overridePendingTransition(R.anim.activity_alpha_in, R.anim.activity_alpha_out)
// finish()
// }
// return true
// }
// return false
// }
/**
* 判断是否需要重新创建对SingleTop启动模式的有效
*/
fun
needRecreate
():
Boolean
{
return
TAG
.
contains
(
"MainActivity"
)
override
fun
attachBaseContext
(
newBase
:
Context
?)
{
super
.
attachBaseContext
(
MultiLanguages
.
attach
(
newBase
))
}
...
...
app/src/main/java/com/base/appzxhy/ads/AdDialog.kt
→
app/src/main/java/com/base/appzxhy/ads/Ad
CountDown
Dialog.kt
View file @
f43b9a38
...
...
@@ -2,21 +2,24 @@ package com.base.appzxhy.ads
import
android.animation.ObjectAnimator
import
android.animation.ValueAnimator.INFINITE
import
android.annotation.SuppressLint
import
android.app.AlertDialog
import
android.app.Dialog
import
android.content.Context
import
android.os.CountDownTimer
import
android.view.LayoutInflater
import
android.view.animation.LinearInterpolator
import
com.base.appzxhy.databinding.DialogAdPreparingBinding
import
com.base.appzxhy.
utils.DensityUtils
import
com.base.appzxhy.
utils.LogEx
import
android.widget.TextView
import
com.base.appzxhy.
R
import
com.base.appzxhy.
databinding.DialogAdCountdownBinding
object
AdDialog
{
object
Ad
CountDown
Dialog
{
private
val
TAG
=
"
com.base.appzxhy.ads.Ad
Dialog"
fun
Context
.
showAdPreparingDialog
(
where
:
Int
=
0
):
AlertDialog
{
LogEx
.
logDebug
(
TAG
,
"where=$where"
)
val
binding
=
DialogAd
Preparing
Binding
.
inflate
(
LayoutInflater
.
from
(
this
))
private
val
TAG
=
"
AdCountDown
Dialog"
fun
Context
.
showAdCountDownDialog
():
AlertDialog
{
val
binding
=
DialogAd
Countdown
Binding
.
inflate
(
LayoutInflater
.
from
(
this
))
val
dialog
=
AlertDialog
.
Builder
(
this
).
create
()
dialog
.
setView
(
binding
.
root
)
dialog
.
setCancelable
(
false
)
...
...
@@ -24,13 +27,14 @@ object AdDialog {
dialog
.
show
()
val
params
=
dialog
.
window
?.
attributes
params
?.
width
=
DensityUtils
.
dip2px
(
200f
)
params
?.
height
=
DensityUtils
.
dip2px
(
146f
)
// params?.width = LinearLayout.LayoutParams.WRAP_CONTENT
params
?.
width
=
resources
.
getDimensionPixelSize
(
R
.
dimen
.
dp_300
)
// params?.height = LinearLayout.LayoutParams.WRAP_CONTENT
dialog
.
window
?.
attributes
=
params
dialog
.
window
?.
setBackgroundDrawableResource
(
android
.
R
.
color
.
transparent
)
// 创建一个旋转动画
val
rotateAnimator
=
ObjectAnimator
.
ofFloat
(
binding
.
iv
,
"rotation"
,
0f
,
-
360f
)
val
rotateAnimator
=
ObjectAnimator
.
ofFloat
(
binding
.
iv
Yuan
,
"rotation"
,
0f
,
-
360f
)
rotateAnimator
.
setDuration
(
1000
)
// 设置动画持续时间为1000毫秒
rotateAnimator
.
repeatCount
=
INFINITE
rotateAnimator
.
interpolator
=
LinearInterpolator
()
// 设置插值器为线性插值
...
...
@@ -38,4 +42,26 @@ object AdDialog {
return
dialog
}
fun
createUICountdownTimer
(
dialog
:
Dialog
?,
onFinish
:
()
->
Unit
)
{
val
tvCountdown
=
dialog
?.
findViewById
<
TextView
>(
R
.
id
.
tvCountdown
)
val
countDownTimer
=
object
:
CountDownTimer
(
4000
,
1000
)
{
@SuppressLint
(
"SetTextI18n"
)
override
fun
onTick
(
millisUntilFinished
:
Long
)
{
val
s
=
millisUntilFinished
/
1000
tvCountdown
?.
text
=
"Ads are about to be shown(${s}s)"
}
override
fun
onFinish
()
{
kotlin
.
runCatching
{
dialog
?.
dismiss
()
}
onFinish
.
invoke
()
}
}
countDownTimer
.
start
()
}
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ads/AdEvent.kt
View file @
f43b9a38
...
...
@@ -30,7 +30,7 @@ abstract class AdEvent {
obj1
.
put
(
"req_id"
,
reqId
)
obj1
.
put
(
"from"
,
from
)
EventUtils
.
event
(
"ad_prepare_show"
,
ext
=
obj1
)
LogEx
.
logDebug
(
TAG
,
"ad_prepare_show $obj1"
)
LogEx
.
logDebug
(
TAG
,
"ad_prepare_show
_$adUnit
$obj1"
)
}
fun
adPulStart
()
{
...
...
@@ -40,7 +40,7 @@ abstract class AdEvent {
obj
.
put
(
"ad_type"
,
adUnit
)
obj
.
put
(
"from"
,
from
)
EventUtils
.
event
(
"ad_pull_start"
,
ext
=
obj
)
LogEx
.
logDebug
(
TAG
,
"ad_pull_start $obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_pull_start
_$adUnit
$obj"
)
}
fun
adShowError
(
reason
:
Any
)
{
...
...
@@ -50,7 +50,7 @@ abstract class AdEvent {
obj
.
put
(
"from"
,
from
)
obj
.
put
(
"reason"
,
reason
.
toString
())
EventUtils
.
event
(
"ad_show_error"
,
ext
=
obj
)
LogEx
.
logDebug
(
TAG
,
"ad_show_error $obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_show_error
_$adUnit
$obj"
)
}
fun
adLimited
(
value
:
String
)
{
...
...
@@ -59,7 +59,7 @@ abstract class AdEvent {
obj
.
put
(
"req_id"
,
reqId
)
obj
.
put
(
"from"
,
from
)
EventUtils
.
event
(
"ad_limit"
,
value
,
obj
)
LogEx
.
logDebug
(
TAG
,
"ad_limit $obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_limit
_$adUnit
$obj"
)
}
...
...
app/src/main/java/com/base/appzxhy/ads/AdsMgr.kt
View file @
f43b9a38
...
...
@@ -2,9 +2,9 @@ package com.base.appzxhy.ads
import
android.app.Activity
import
android.content.Context
import
android.view.LayoutInflater
import
android.view.ViewGroup
import
android.widget.FrameLayout
import
android.widget.Toast
import
androidx.annotation.LayoutRes
import
com.applovin.sdk.AppLovinMediationProvider
import
com.applovin.sdk.AppLovinSdk
...
...
@@ -29,7 +29,6 @@ import com.base.appzxhy.utils.ToastUtils.toast
import
com.google.android.gms.ads.MobileAds
import
com.google.android.gms.ads.identifier.AdvertisingIdClient
import
com.google.android.gms.ads.initialization.AdapterStatus
import
com.google.android.gms.ads.nativead.NativeAdView
import
java.util.Collections
import
java.util.concurrent.Executors
...
...
@@ -88,8 +87,11 @@ object AdsMgr {
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
initAdmob
(
context
)
initMax
(
context
)
if
(
adsConfigBean
.
adSwitch
)
{
initAdmob
(
context
)
}
else
{
initMax
(
context
)
}
}
...
...
@@ -105,8 +107,8 @@ object AdsMgr {
if
(
adsConfigBean
.
adSwitch
)
{
admobInitCallBack
?.
invoke
()
admobInitCallBack
=
null
adOpenMgr
.
loadAd
(
context
,
false
,
AdmobEvent
(
"openAd"
,
context
::
class
.
java
.
simpleName
))
adInsertMgr
.
loadAd
(
context
,
false
,
AdmobEvent
(
"interAd"
,
context
::
class
.
java
.
simpleName
))
adOpenMgr
.
loadAd
(
context
,
AdmobEvent
(
"openAd"
,
context
::
class
.
java
.
simpleName
))
adInsertMgr
.
loadAd
(
context
,
AdmobEvent
(
"interAd"
,
context
::
class
.
java
.
simpleName
))
}
}
...
...
@@ -133,7 +135,7 @@ object AdsMgr {
isMaxInit
=
true
// maxOpenMgr.loadAd(context)
if
(!
adsConfigBean
.
adSwitch
)
{
maxInsertMgr
.
loadAd
(
context
,
false
,
AdMaxEvent
(
"interAd"
,
context
::
class
.
java
.
simpleName
))
maxInsertMgr
.
loadAd
(
AdMaxEvent
(
"interAd"
,
context
::
class
.
java
.
simpleName
))
context
.
toast
(
"max init"
)
maxInitCallBack
?.
invoke
()
maxInitCallBack
=
null
...
...
@@ -158,7 +160,6 @@ object AdsMgr {
*/
fun
showOpen
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
false
,
showCallBack
:
AdsShowCallBack
?
=
null
,
)
{
if
(
configBean
.
isInBlackList
)
{
...
...
@@ -169,18 +170,18 @@ object AdsMgr {
val
from
=
activity
::
class
.
java
.
simpleName
if
(
adsConfigBean
.
adSwitch
)
{
if
(
isAdmobInit
)
{
adOpenMgr
.
show
(
activity
,
isUnLimit
,
AdmobEvent
(
"openAd"
,
from
),
showCallBack
)
adOpenMgr
.
show
(
activity
,
AdmobEvent
(
"openAd"
,
from
),
showCallBack
)
}
else
{
admobInitCallBack
=
{
}
adOpenMgr
.
show
(
activity
,
isUnLimit
,
AdmobEvent
(
"openAd"
,
from
),
showCallBack
)
adOpenMgr
.
show
(
activity
,
AdmobEvent
(
"openAd"
,
from
),
showCallBack
)
}
}
else
{
if
(
isMaxInit
)
{
maxOpenMgr
.
show
(
activity
,
isUnLimit
,
AdMaxEvent
(
"openAd"
,
from
),
showCallBack
)
maxOpenMgr
.
show
(
activity
,
AdMaxEvent
(
"openAd"
,
from
),
showCallBack
)
}
else
{
maxInitCallBack
=
{
maxOpenMgr
.
show
(
activity
,
isUnLimit
,
AdMaxEvent
(
"openAd"
,
from
),
showCallBack
)
maxOpenMgr
.
show
(
activity
,
AdMaxEvent
(
"openAd"
,
from
),
showCallBack
)
}
}
}
...
...
@@ -196,7 +197,6 @@ object AdsMgr {
*/
fun
showInsert
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
false
,
showCallBack
:
AdsShowCallBack
?
=
null
,
)
{
if
(
configBean
.
isInBlackList
)
{
...
...
@@ -206,9 +206,9 @@ object AdsMgr {
LogEx
.
logDebug
(
"showAd"
,
"adSwitch=${adsConfigBean.adSwitch}"
)
val
from
=
activity
::
class
.
java
.
simpleName
if
(
adsConfigBean
.
adSwitch
)
{
adInsertMgr
.
show
(
activity
,
isUnLimit
,
AdmobEvent
(
"interAd"
,
from
),
showCallBack
)
adInsertMgr
.
show
(
activity
,
AdmobEvent
(
"interAd"
,
from
),
showCallBack
)
}
else
{
maxInsertMgr
.
show
(
activity
,
isUnLimit
,
AdMaxEvent
(
"interAd"
,
from
),
showCallBack
)
maxInsertMgr
.
show
(
activity
,
AdMaxEvent
(
"interAd"
,
from
),
showCallBack
)
}
}
...
...
@@ -221,29 +221,25 @@ object AdsMgr {
fun
showNative
(
activity
:
Activity
,
parent
:
FrameLayout
,
@LayoutRes
layout
:
Int
,
@LayoutRes
admobLayout
:
Int
,
@LayoutRes
maxLayout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
if
(
configBean
.
isInBlackList
)
{
LogEx
.
logDebug
(
"showNative"
,
"isInBlackList"
)
EventUtils
.
event
(
"isInBlackList"
,
configBean
.
isInBlackList
.
toString
())
return
}
if
(!
isAdmobInit
)
return
val
from
=
activity
::
class
.
java
.
simpleName
if
(
adsConfigBean
.
adSwitch
)
{
val
nativeView
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
layout
,
parent
,
false
)
as
NativeAdView
adNativeMgr
.
show
(
AdmobEvent
(
"nativeAd"
,
from
),
parent
,
nativeView
,
nativeCallBack
)
adNativeMgr
.
show
(
AdmobEvent
(
"nativeAd"
,
from
),
parent
,
admobLayout
,
nativeCallBack
)
}
else
{
// maxNativeMgr.show(AdMaxEvent("nativeAd", "nativeAd"), nativeParent, l
ayout, nativeCallBack)
maxNativeMgr
.
show
(
AdMaxEvent
(
"nativeAd"
,
from
),
parent
,
maxL
ayout
,
nativeCallBack
)
}
}
fun
isNativeShow
()
=
(
isAdmobInit
&&
!
configBean
.
isInBlackList
)
&&
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
,
null
)
/**
* 展示banner广告
...
...
app/src/main/java/com/base/appzxhy/ads/AdsShowCallBack.kt
View file @
f43b9a38
...
...
@@ -4,5 +4,5 @@ abstract class AdsShowCallBack {
open
fun
show
()
{}
abstract
fun
close
(
where
:
Int
=
0
)
abstract
fun
failed
(
where
:
Int
=
0
)
abstract
fun
google
Failed
(
where
:
Int
=
0
)
abstract
fun
ad
Failed
(
where
:
Int
=
0
)
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ads/LimitUtils.kt
View file @
f43b9a38
package
com.base.appzxhy.ads
import
com.base.appzxhy.BuildConfig
import
com.base.appzxhy.bean.config.AdConfigBean
import
com.base.appzxhy.utils.AppPreferences
import
com.base.appzxhy.utils.KotlinExt.toFormatTime4
...
...
@@ -16,7 +17,7 @@ object LimitUtils {
const
val
NUM_CLICK
=
"local_numClickLimit"
const
val
SAVE_DATE
=
"local_
SAVE_DATE
"
const
val
SAVE_DATE
=
"local_
saveDate
"
/**
* 保存的时间,用来判断是否是当天,不是当天要重置计数次数
...
...
@@ -34,7 +35,6 @@ object LimitUtils {
}
/**
* 广告请求是否到达限制
*/
...
...
@@ -81,6 +81,11 @@ object LimitUtils {
* @return true or false
*/
fun
isAdShow
(
adsType
:
AdsType
,
adEvent
:
AdEvent
?):
Boolean
{
if
(
BuildConfig
.
DEBUG
)
{
return
true
}
val
currentDate
=
System
.
currentTimeMillis
().
toFormatTime4
()
if
(
saveDate
!=
currentDate
)
{
//如果已经不是今天了,就重置个数
...
...
app/src/main/java/com/base/appzxhy/ads/NativeParentView.kt
deleted
100644 → 0
View file @
4f5c6253
package
com.base.appzxhy.ads
import
android.annotation.SuppressLint
import
android.content.Context
import
android.util.AttributeSet
import
android.view.LayoutInflater
import
android.view.View
import
android.widget.Button
import
android.widget.FrameLayout
import
android.widget.ImageView
import
android.widget.TextView
import
androidx.annotation.LayoutRes
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.nativeAds.MaxNativeAdLoader
import
com.applovin.mediation.nativeAds.MaxNativeAdView
import
com.applovin.mediation.nativeAds.MaxNativeAdViewBinder
import
com.base.appzxhy.R
import
com.google.android.gms.ads.nativead.NativeAd
import
com.google.android.gms.ads.nativead.NativeAdView
@SuppressLint
(
"ViewConstructor"
)
class
NativeParentView
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
)
:
FrameLayout
(
context
,
attrs
)
{
private
val
TAG
=
"NativeParentView"
private
var
removeAll
=
true
init
{
// 获取XML属性
val
a
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
NativeParentView
,
0
,
0
)
// 从XML中读取属性值
// 例如,如果你的XML中有自定义属性 `app:customAttribute="value"`
removeAll
=
a
.
getBoolean
(
R
.
styleable
.
NativeParentView_removeAll
,
true
)
// 回收TypedArray
a
.
recycle
()
}
fun
setNativeAd
(
nativeAd
:
NativeAd
,
@LayoutRes
resource
:
Int
?
=
null
)
{
val
layout
=
resource
?:
R
.
layout
.
layout_admob_native_custom
val
adView
=
layout
.
let
{
LayoutInflater
.
from
(
context
).
inflate
(
it
,
null
)
}
as
NativeAdView
adView
.
mediaView
=
adView
.
findViewById
(
R
.
id
.
ad_media
)
adView
.
headlineView
=
adView
.
findViewById
(
R
.
id
.
ad_headline
)
adView
.
bodyView
=
adView
.
findViewById
(
R
.
id
.
ad_body
)
adView
.
callToActionView
=
adView
.
findViewById
(
R
.
id
.
ad_call_to_action
)
adView
.
iconView
=
adView
.
findViewById
(
R
.
id
.
ad_app_icon
)
(
adView
.
headlineView
as
TextView
?)
?.
text
=
nativeAd
.
headline
adView
.
mediaView
?.
mediaContent
=
nativeAd
.
mediaContent
if
(
nativeAd
.
body
==
null
)
{
adView
.
bodyView
?.
visibility
=
View
.
INVISIBLE
}
else
{
adView
.
bodyView
?.
visibility
=
View
.
VISIBLE
(
adView
.
bodyView
as
TextView
?)
?.
text
=
nativeAd
.
body
}
if
(
nativeAd
.
callToAction
==
null
)
{
adView
.
callToActionView
?.
visibility
=
View
.
INVISIBLE
}
else
{
adView
.
callToActionView
?.
visibility
=
View
.
VISIBLE
(
adView
.
callToActionView
as
Button
?)
?.
text
=
nativeAd
.
callToAction
}
if
(
nativeAd
.
icon
==
null
)
{
adView
.
iconView
?.
visibility
=
View
.
GONE
}
else
{
(
adView
.
iconView
as
ImageView
?)
?.
setImageDrawable
(
nativeAd
.
icon
?.
drawable
)
adView
.
iconView
?.
visibility
=
View
.
VISIBLE
}
adView
.
setNativeAd
(
nativeAd
)
setBackgroundResource
(
0
)
if
(
removeAll
)
{
removeAllViews
()
}
addView
(
adView
)
}
fun
setNativeAd
(
nativeAdLoader
:
MaxNativeAdLoader
,
nativeAd
:
MaxAd
,
@LayoutRes
resource
:
Int
?
=
null
)
{
val
layout
=
resource
?:
R
.
layout
.
layout_max_native_custom
val
binder
:
MaxNativeAdViewBinder
=
MaxNativeAdViewBinder
.
Builder
(
layout
)
.
setTitleTextViewId
(
R
.
id
.
title_text_view
)
.
setBodyTextViewId
(
R
.
id
.
body_text_view
)
.
setAdvertiserTextViewId
(
R
.
id
.
advertiser_text_view
)
.
setIconImageViewId
(
R
.
id
.
icon_image_view
)
.
setMediaContentViewGroupId
(
R
.
id
.
media_view_container
)
.
setOptionsContentViewGroupId
(
R
.
id
.
options_view
)
.
setStarRatingContentViewGroupId
(
R
.
id
.
star_rating_view
)
.
setCallToActionButtonId
(
R
.
id
.
cta_button
)
.
build
()
val
adView
=
MaxNativeAdView
(
binder
,
context
)
nativeAdLoader
.
render
(
adView
,
nativeAd
)
setBackgroundResource
(
0
)
removeAllViews
()
addView
(
adView
)
}
}
app/src/main/java/com/base/appzxhy/ads/admob/AdInterMgr.kt
View file @
f43b9a38
...
...
@@ -3,75 +3,64 @@ package com.base.appzxhy.ads.admob
import
android.app.Activity
import
android.content.Context
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.ads.AdDialog.showAdPreparingDialog
import
com.base.appzxhy.ads.AdCountDownDialog.createUICountdownTimer
import
com.base.appzxhy.ads.AdCountDownDialog.showAdCountDownDialog
import
com.base.appzxhy.ads.AdEvent
import
com.base.appzxhy.ads.AdsShowCallBack
import
com.base.appzxhy.ads.AdsType
import
com.base.appzxhy.ads.LimitUtils
import
com.base.appzxhy.ads.adState
import
com.google.android.gms.ads.AdError
import
com.google.android.gms.ads.AdRequest
import
com.google.android.gms.ads.FullScreenContentCallback
import
com.google.android.gms.ads.LoadAdError
import
com.google.android.gms.ads.interstitial.InterstitialAd
import
com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import
java.lang.ref.WeakReference
/**
*插屏广告加载显示管理类
*/
class
AdInterMgr
{
private
var
adState
=
adState
<
InterstitialAd
>
()
private
var
showCallBack
:
AdsShowCallBack
?
=
null
private
var
adState
=
AdmobAdState
()
fun
show
(
activity
:
Activity
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
fun
show
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
if
(
activity
.
isFinishing
||
activity
.
isDestroyed
)
{
showCallBack
?.
failed
(
0
)
return
}
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
showCallBack
?.
failed
(
2
)
return
}
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
(
3
)
return
}
}
if
(
adState
.
showingAd
)
{
if
(
!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
)
)
{
showCallBack
?.
failed
(
1
)
adEvent
.
adShowError
(
"showingAd"
)
adState
.
showingAd
=
false
return
}
if
(
showCallBack
!=
null
)
{
this
.
showCallBack
=
showCallBack
adState
.
activityRef
=
WeakReference
(
activity
)
if
(
adState
.
adDialog
==
null
)
{
adState
.
adDialog
=
activity
.
showAdPreparingDialog
(
1
)
}
adEvent
.
adPrepareShow
()
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
(
2
)
return
}
if
(!
adState
.
loadingAd
)
{
if
(
adState
.
currentAd
==
null
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
val
loadingDialog
=
activity
.
showAdCountDownDialog
()
if
(
adState
.
currentAd
==
null
||
!
adAvailable
())
{
loadAd
(
activity
,
adEvent
)
{
if
(
adState
.
currentAd
!=
null
)
{
createUICountdownTimer
(
loadingDialog
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
}
if
(!
adAvailable
())
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
}
else
{
createUICountdownTimer
(
loadingDialog
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
showReadyAd
(
adEvent
,
activity
)
}
}
private
fun
showReadyAd
(
adEvent
:
AdEvent
,
activity
:
Activity
)
{
adState
.
currentAd
?.
run
{
private
fun
showReadyAd
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
val
ad
=
adState
.
currentAd
as
InterstitialAd
?
ad
?.
run
{
fullScreenContentCallback
=
object
:
FullScreenContentCallback
()
{
override
fun
onAdShowedFullScreenContent
()
{
super
.
onAdShowedFullScreenContent
()
...
...
@@ -85,9 +74,7 @@ class AdInterMgr {
super
.
onAdFailedToShowFullScreenContent
(
adError
)
adState
.
onAdDisplayFailed
()
showCallBack
?.
googleFailed
()
showCallBack
=
null
showCallBack
?.
adFailed
()
adEvent
.
adShowError
(
adError
)
}
...
...
@@ -97,8 +84,7 @@ class AdInterMgr {
adState
.
onAdHidden
()
showCallBack
?.
close
()
showCallBack
=
null
loadAd
(
activity
.
applicationContext
,
false
,
AdmobEvent
(
"interAd"
,
"preload"
))
loadAd
(
activity
.
applicationContext
,
AdmobEvent
(
"interAd"
,
"preload"
))
}
override
fun
onAdClicked
()
{
...
...
@@ -112,15 +98,12 @@ class AdInterMgr {
}
}
fun
loadAd
(
context
:
Context
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
)
{
fun
loadAd
(
context
:
Context
,
adEvent
:
AdEvent
,
loadCallBack
:
(()
->
Unit
)?
=
null
)
{
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
this
.
showCallBack
?.
close
(
4
)
this
.
showCallBack
=
null
adState
.
onAdLoadFailed
()
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
loadCallBack
?.
invoke
()
adState
.
onAdLoadFailed
()
return
}
if
(!
adState
.
loadingAd
)
{
...
...
@@ -132,10 +115,7 @@ class AdInterMgr {
object
:
InterstitialAdLoadCallback
()
{
override
fun
onAdLoaded
(
ad
:
InterstitialAd
)
{
adState
.
onAdLoaded
(
ad
)
val
ac
=
adState
.
activityRef
?.
get
()
if
(
ac
!=
null
)
{
show
(
ac
,
isUnLimit
,
adEvent
,
null
)
}
loadCallBack
?.
invoke
()
(
adEvent
as
AdmobEvent
).
pullAd
(
ad
.
responseInfo
)
LimitUtils
.
addRequestNum
()
ad
.
onPaidEventListener
=
AdmobEvent
.
EventOnPaidEventListener
(
ad
)
...
...
@@ -144,8 +124,7 @@ class AdInterMgr {
override
fun
onAdFailedToLoad
(
loadAdError
:
LoadAdError
)
{
adState
.
onAdLoadFailed
()
(
adEvent
as
AdmobEvent
).
pullAd
(
loadAdError
.
responseInfo
,
loadAdError
)
showCallBack
?.
googleFailed
()
showCallBack
=
null
loadCallBack
?.
invoke
()
}
}
)
...
...
app/src/main/java/com/base/appzxhy/ads/admob/AdNativeMgr.kt
View file @
f43b9a38
package
com.base.appzxhy.ads.admob
import
android.content.Context
import
android.view.LayoutInflater
import
android.view.View
import
android.widget.Button
import
android.widget.FrameLayout
import
android.widget.ImageView
import
android.widget.TextView
import
androidx.core.view.isVisible
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.R
import
com.base.appzxhy.ads.AdsType
...
...
@@ -15,48 +15,40 @@ import com.google.android.gms.ads.AdListener
import
com.google.android.gms.ads.AdLoader
import
com.google.android.gms.ads.AdRequest
import
com.google.android.gms.ads.LoadAdError
import
com.google.android.gms.ads.nativead.MediaView
import
com.google.android.gms.ads.nativead.NativeAd
import
com.google.android.gms.ads.nativead.NativeAdOptions
import
com.google.android.gms.ads.nativead.NativeAdView
import
java.util.concurrent.ConcurrentLinkedDeque
/**
*原生广告加载显示管理类
*/
class
AdNativeMgr
{
/**
* 上一次的缓存成功时间
*/
private
val
TAG
=
this
::
class
.
java
.
simpleName
protected
var
lastTime
:
Long
=
0
/**
* 原生广告缓存队列
*/
private
val
cacheItems
=
ConcurrentLinkedDeque
<
NativeAd
>()
private
var
currentAd
:
NativeAd
?
=
null
private
fun
loadAd
(
admobEvent
:
AdmobEvent
,
parent
:
FrameLayou
t
,
nativeAdView
:
NativeAdView
context
:
Contex
t
,
callback
:
((
nativeAd
:
NativeAd
)
->
Unit
)?
=
null
)
{
admobEvent
.
adPulStart
()
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
,
admobEvent
))
return
admobEvent
.
adPulStart
()
var
currentNativeAd
:
NativeAd
?
=
null
val
adLoader
=
AdLoader
.
Builder
(
parent
.
context
,
context
,
GlobalConfig
.
ID_ADMOB_NATIVE
).
forNativeAd
{
nativeAd
->
currentNativeAd
=
nativeAd
cacheItems
.
offer
(
nativeAd
)
lastTime
=
System
.
currentTimeMillis
()
nativeAd
.
setOnPaidEventListener
(
AdmobEvent
.
EventOnPaidEventListener
(
nativeAd
))
admobEvent
.
pullAd
(
nativeAd
.
responseInfo
)
show
(
admobEvent
,
parent
,
nativeAdView
)
callback
?.
invoke
(
nativeAd
)
}.
withAdListener
(
object
:
AdListener
()
{
override
fun
onAdFailedToLoad
(
error
:
LoadAdError
)
{
...
...
@@ -80,69 +72,68 @@ class AdNativeMgr {
fun
show
(
admobEvent
:
AdmobEvent
,
nativeP
arent
:
FrameLayout
,
nativeAdView
:
NativeAdView
,
p
arent
:
FrameLayout
,
layout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
admobEvent
.
adPrepareShow
()
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
NATIVE
,
admobEvent
))
{
cacheItems
.
clear
()
return
}
val
nativeAd
=
cacheItems
.
peek
()
if
(
nativeAd
==
null
||
!
adAvailable
())
{
//缓存过期了就清空
cacheItems
.
clear
()
loadAd
(
admobEvent
,
nativeParent
,
nativeAdView
)
return
}
nativeCallBack
?.
invoke
(
nativeAd
)
//添加原生到父布局
nativeParent
.
removeAllViews
()
nativeAdView
.
bindNativeAd
(
nativeAd
)
nativeParent
.
addView
(
nativeAdView
)
nativeParent
.
isVisible
=
true
admobEvent
.
adPrepareShow
()
admobEvent
.
showAd
(
nativeAd
.
responseInfo
)
if
(
currentAd
==
null
||
!
adAvailable
())
{
loadAd
(
admobEvent
,
parent
.
context
)
{
nativeAd
:
NativeAd
->
setNative
(
parent
,
layout
,
nativeAd
)
admobEvent
.
showAd
(
nativeAd
.
responseInfo
)
nativeCallBack
?.
invoke
(
nativeAd
)
}
}
else
{
currentAd
?.
let
{
setNative
(
parent
,
layout
,
it
)
admobEvent
.
showAd
(
it
.
responseInfo
)
nativeCallBack
?.
invoke
(
it
)
}
}
}
private
fun
NativeAdView
.
bindNativeAd
(
nativeAd
:
NativeAd
?)
{
nativeAd
?:
return
private
fun
setNative
(
parent
:
FrameLayout
,
layout
:
Int
,
nativeAd
:
NativeAd
)
=
runCatching
{
mediaView
=
findViewById
(
R
.
id
.
ad_media
)
headlineView
=
findViewById
(
R
.
id
.
ad_headline
)
bodyView
=
findViewById
(
R
.
id
.
ad_body
)
callToActionView
=
findViewById
(
R
.
id
.
ad_call_to_action
)
iconView
=
findViewById
(
R
.
id
.
ad_app_icon
)
currentAd
=
null
(
headlineView
as
TextView
?)
?.
text
=
nativeAd
.
headline
val
nativeView
=
LayoutInflater
.
from
(
parent
.
context
).
inflate
(
layout
,
parent
,
false
)
as
NativeAdView
val
mediaView
=
nativeView
.
findViewById
<
MediaView
?>(
R
.
id
.
ad_media
)
mediaView
?.
mediaContent
=
nativeAd
.
mediaContent
val
headlineView
=
nativeView
.
findViewById
<
TextView
?>(
R
.
id
.
ad_headline
)
headlineView
?.
text
=
nativeAd
.
headline
val
bodyView
=
nativeView
.
findViewById
<
TextView
?>(
R
.
id
.
ad_body
)
if
(
nativeAd
.
body
==
null
)
{
bodyView
?.
visibility
=
View
.
INVISIBLE
}
else
{
bodyView
?.
visibility
=
View
.
VISIBLE
(
bodyView
as
TextView
?)
?.
text
=
nativeAd
.
body
bodyView
?.
text
=
nativeAd
.
body
}
val
callToActionView
=
nativeView
.
findViewById
<
Button
?>(
R
.
id
.
ad_call_to_action
)
if
(
nativeAd
.
callToAction
==
null
)
{
callToActionView
?.
visibility
=
View
.
INVISIBLE
}
else
{
callToActionView
?.
visibility
=
View
.
VISIBLE
(
callToActionView
as
Button
?)
?.
text
=
nativeAd
.
callToAction
callToActionView
?.
text
=
nativeAd
.
callToAction
}
val
iconView
=
nativeView
.
findViewById
<
ImageView
?>(
R
.
id
.
ad_app_icon
)
if
(
nativeAd
.
icon
==
null
)
{
iconView
?.
visibility
=
View
.
GONE
}
else
{
(
iconView
as
ImageView
?)
?.
setImageDrawable
(
nativeAd
.
icon
?.
drawable
)
iconView
?.
setImageDrawable
(
nativeAd
.
icon
?.
drawable
)
iconView
?.
visibility
=
View
.
VISIBLE
}
setNativeAd
(
nativeAd
)
parent
.
removeAllViews
()
parent
.
addView
(
nativeView
)
}
private
fun
adAvailable
():
Boolean
{
...
...
app/src/main/java/com/base/appzxhy/ads/admob/AdOpenMgr.kt
View file @
f43b9a38
...
...
@@ -3,66 +3,62 @@ package com.base.appzxhy.ads.admob
import
android.app.Activity
import
android.content.Context
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.ads.AdCountDownDialog.createUICountdownTimer
import
com.base.appzxhy.ads.AdsType
import
com.base.appzxhy.ads.AdEvent
import
com.base.appzxhy.ads.AdsShowCallBack
import
com.base.appzxhy.ads.LimitUtils
import
com.base.appzxhy.ads.adState
import
com.google.android.gms.ads.AdError
import
com.google.android.gms.ads.AdRequest
import
com.google.android.gms.ads.FullScreenContentCallback
import
com.google.android.gms.ads.LoadAdError
import
com.google.android.gms.ads.appopen.AppOpenAd
import
java.lang.ref.WeakReference
/**
* 开屏广告加载显示管理类
*/
class
AdOpenMgr
{
private
val
adState
=
adState
<
AppOpenAd
>()
private
var
showCallBack
:
AdsShowCallBack
?
=
null
private
val
adState
=
AdmobAdState
()
fun
show
(
activity
:
Activity
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
fun
show
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
if
(
activity
.
isFinishing
||
activity
.
isDestroyed
)
{
return
}
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
showCallBack
?.
failed
()
return
}
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
()
return
}
}
if
(
adState
.
showingAd
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
showCallBack
?.
failed
()
adEvent
.
adShowError
(
"showingAd"
)
adState
.
showingAd
=
false
return
}
if
(
showCallBack
!=
null
)
{
this
.
showCallBack
=
showCallBack
adState
.
activityRef
=
WeakReference
(
activity
)
adEvent
.
adPrepareShow
()
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
()
return
}
adEvent
.
adPrepareShow
()
if
(!
adState
.
loadingAd
)
{
if
(!
adAvailable
()
||
adState
.
currentAd
==
null
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
if
(
adState
.
currentAd
==
null
||
!
adAvailable
())
{
loadAd
(
activity
,
adEvent
)
{
if
(
adState
.
currentAd
!=
null
)
{
createUICountdownTimer
(
null
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
else
{
showCallBack
?.
failed
()
}
}
showReadyAd
(
adEvent
,
activity
)
}
}
else
{
createUICountdownTimer
(
null
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
}
private
fun
showReadyAd
(
adEvent
:
AdEvent
,
activity
:
Activity
)
{
adState
.
currentAd
?.
run
{
private
fun
showReadyAd
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
val
ad
=
adState
.
currentAd
as
AppOpenAd
?
ad
?.
run
{
fullScreenContentCallback
=
object
:
FullScreenContentCallback
()
{
override
fun
onAdShowedFullScreenContent
()
{
...
...
@@ -77,8 +73,7 @@ class AdOpenMgr {
override
fun
onAdFailedToShowFullScreenContent
(
adError
:
AdError
)
{
super
.
onAdFailedToShowFullScreenContent
(
adError
)
showCallBack
?.
googleFailed
()
showCallBack
=
null
showCallBack
?.
adFailed
()
adState
.
onAdDisplayFailed
()
(
adEvent
as
AdmobEvent
).
adShowError
(
adError
)
...
...
@@ -87,13 +82,9 @@ class AdOpenMgr {
override
fun
onAdDismissedFullScreenContent
()
{
super
.
onAdDismissedFullScreenContent
()
showCallBack
?.
close
()
showCallBack
=
null
adState
.
onAdHidden
()
loadAd
(
activity
.
applicationContext
,
false
,
AdmobEvent
(
"openAd"
,
"preload"
))
loadAd
(
activity
.
applicationContext
,
AdmobEvent
(
"openAd"
,
"preload"
))
}
override
fun
onAdClicked
()
{
...
...
@@ -106,15 +97,12 @@ class AdOpenMgr {
}
}
fun
loadAd
(
context
:
Context
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
)
{
fun
loadAd
(
context
:
Context
,
adEvent
:
AdEvent
,
loadCallBack
:
(()
->
Unit
)?
=
null
)
{
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
this
.
showCallBack
?.
close
()
this
.
showCallBack
=
null
adState
.
onAdLoadFailed
()
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
loadCallBack
?.
invoke
()
adState
.
onAdLoadFailed
()
return
}
if
(!
adState
.
loadingAd
)
{
...
...
@@ -128,19 +116,15 @@ class AdOpenMgr {
object
:
AppOpenAd
.
AppOpenAdLoadCallback
()
{
override
fun
onAdLoaded
(
appOpenAd
:
AppOpenAd
)
{
adState
.
onAdLoaded
(
appOpenAd
)
val
ac
=
adState
.
activityRef
?.
get
()
if
(
ac
!=
null
)
{
show
(
ac
,
isUnLimit
,
adEvent
,
null
)
}
loadCallBack
?.
invoke
()
(
adEvent
as
AdmobEvent
).
pullAd
(
appOpenAd
.
responseInfo
)
appOpenAd
.
onPaidEventListener
=
AdmobEvent
.
EventOnPaidEventListener
(
appOpenAd
)
LimitUtils
.
addRequestNum
()
}
override
fun
onAdFailedToLoad
(
loadAdError
:
LoadAdError
)
{
showCallBack
?.
googleFailed
()
showCallBack
=
null
adState
.
onAdLoadFailed
()
loadCallBack
?.
invoke
()
(
adEvent
as
AdmobEvent
).
pullAd
(
loadAdError
.
responseInfo
,
loadAdError
)
}
}
...
...
app/src/main/java/com/base/appzxhy/ads/
BaseAdMgr
.kt
→
app/src/main/java/com/base/appzxhy/ads/
admob/AdmobAdState
.kt
View file @
f43b9a38
package
com.base.appzxhy.ads
package
com.base.appzxhy.ads
.admob
import
android.app.Activity
import
android.app.Dialog
import
android.content.Context
import
java.lang.ref.WeakReference
class
adState
<
T
>()
{
var
adDialog
:
Dialog
?
=
null
class
AdmobAdState
{
/**
* 当前缓存的广告
*/
var
currentAd
:
T
?
=
null
var
currentAd
:
Any
?
=
null
/**
* 是否正在缓存加载广告
...
...
@@ -22,11 +15,6 @@ class adState<T>() {
var
loadingAd
:
Boolean
=
false
/**
* 是否正在显示广告
*/
var
showingAd
:
Boolean
=
false
/**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕)
*/
...
...
@@ -43,10 +31,6 @@ class adState<T>() {
var
lastShowTime
:
Long
=
0
fun
onAdDisplayed
()
{
showingAd
=
true
adDialog
?.
dismiss
()
adDialog
=
null
lastShowTime
=
System
.
currentTimeMillis
()
...
...
@@ -56,19 +40,15 @@ class adState<T>() {
fun
onAdHidden
()
{
// 广告关闭,清空缓存数据,重新加载
showingAd
=
false
}
fun
onAdDisplayFailed
()
{
adDialog
?.
dismiss
()
adDialog
=
null
showingAd
=
false
currentAd
=
null
activityRef
=
null
}
fun
onAdLoaded
(
ad
:
T
?)
{
fun
onAdLoaded
(
ad
:
Any
?)
{
//这里可能提前设置,所有可以不设置,max回调的类型可能不同
if
(
ad
!=
null
)
{
currentAd
=
ad
...
...
@@ -78,70 +58,6 @@ class adState<T>() {
}
fun
onAdLoadFailed
()
{
adDialog
?.
dismiss
()
adDialog
=
null
loadingAd
=
false
}
}
/**
* 特定广告管理基类
* @param T 缓存广告的类
*/
abstract
class
BaseAdMgr
<
T
>
{
/**
* 广告展示回调
*/
protected
var
showCallBack
:
AdsShowCallBack
?
=
null
/**
* 当前缓存的广告
*/
protected
var
currentAd
:
T
?
=
null
/**
* 是否正在缓存加载广告
*/
protected
var
loadingAd
:
Boolean
=
false
/**
* 是否正在显示广告
*/
protected
var
showingAd
:
Boolean
=
false
/**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕)
*/
protected
var
activityRef
:
WeakReference
<
Activity
>?
=
null
/**
* 上一次的缓存成功时间
*/
protected
var
lastLoadTime
:
Long
=
0
/**
* 预加载广告
*
* @param context 加载所用的上下文,一般使用appContext
*/
abstract
fun
loadAd
(
context
:
Context
,
isUnLimit
:
Boolean
=
true
,
adEvent
:
AdEvent
)
/**
* 广告显示
*
* @param activity 当前页面
*/
abstract
fun
show
(
activity
:
Activity
,
isUnLimit
:
Boolean
=
true
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?
=
null
)
/**
* 预加载的缓存超时判断
*
* @return true:没有超时 false:超时需要重新加载
*/
abstract
fun
adAvailable
():
Boolean
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ads/admob/AdmobEvent.kt
View file @
f43b9a38
...
...
@@ -67,7 +67,7 @@ class AdmobEvent : AdEvent {
obj
.
put
(
"status"
,
"2"
)
}
EventUtils
.
event
(
"ad_pull"
,
ext
=
obj
)
LogEx
.
logDebug
(
TAG
,
"ad_pull obj=$obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_pull
_$adUnit
obj=$obj"
)
}
...
...
@@ -89,9 +89,9 @@ class AdmobEvent : AdEvent {
obj
.
put
(
"from"
,
from
)
obj
.
put
(
"networkname"
,
responseInfo
?.
mediationAdapterClassName
)
if
(
adUnit
!=
"nativeAd"
)
{
EventUtils
.
event
(
"ad_click"
,
ext
=
obj
)
EventUtils
.
event
(
"ad_click
_$adUnit
"
,
ext
=
obj
)
}
else
{
EventUtils
.
event
(
"ad_click"
,
ext
=
obj
)
EventUtils
.
event
(
"ad_click
_$adUnit
"
,
ext
=
obj
)
}
}
...
...
@@ -115,7 +115,7 @@ class AdmobEvent : AdEvent {
}
else
{
EventUtils
.
event
(
"ad_show"
,
ext
=
obj
)
}
LogEx
.
logDebug
(
TAG
,
"ad_show $obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_show
_$adUnit
$obj"
)
}
class
EventOnPaidEventListener
(
private
val
ad
:
Any
?)
:
OnPaidEventListener
{
...
...
@@ -303,7 +303,7 @@ class AdmobEvent : AdEvent {
obj
.
put
(
"from"
,
from
)
obj
.
put
(
"ad_unit"
,
"openAd"
)
EventUtils
.
event
(
"ad_show_error"
,
ext
=
obj
)
LogEx
.
logDebug
(
TAG
,
"ad_show_error $obj"
)
LogEx
.
logDebug
(
TAG
,
"ad_show_error
_$adUnit
$obj"
)
}
}
...
...
app/src/main/java/com/base/appzxhy/ads/applovin/AdMaxEvent.kt
View file @
f43b9a38
...
...
@@ -10,7 +10,6 @@ import com.base.appzxhy.ads.AdEvent
import
com.base.appzxhy.ads.taichiPref
import
com.base.appzxhy.ads.taichiSharedPreferencesEditor
import
com.base.appzxhy.helper.EventUtils
import
com.base.appzxhy.utils.LogEx
import
com.base.appzxhy.utils.LogEx.logDebug
import
com.facebook.appevents.AppEventsConstants
import
com.facebook.appevents.AppEventsLogger
...
...
app/src/main/java/com/base/appzxhy/ads/applovin/MaxAdState.kt
0 → 100644
View file @
f43b9a38
package
com.base.appzxhy.ads.applovin
import
android.app.Activity
import
java.lang.ref.WeakReference
class
MaxAdState
{
/**
* 当前缓存的广告
*/
var
currentAd
:
Any
?
=
null
/**
* 是否正在缓存加载广告
*/
var
loadingAd
:
Boolean
=
false
/**
* 用于保存引用现有页面,在此页面显示广告(因为要等待广告加载完毕)
*/
var
activityRef
:
WeakReference
<
Activity
>?
=
null
/**
* 上一次的缓存成功时间
*/
var
lastLoadTime
:
Long
=
0
/**
* 上次展示时间
*/
var
lastShowTime
:
Long
=
0
fun
onAdDisplayed
()
{
lastShowTime
=
System
.
currentTimeMillis
()
activityRef
=
null
}
fun
onAdHidden
()
{
// 广告关闭,清空缓存数据,重新加载
}
fun
onAdDisplayFailed
()
{
activityRef
=
null
}
fun
onAdLoaded
()
{
loadingAd
=
false
lastLoadTime
=
System
.
currentTimeMillis
()
}
fun
onAdLoadFailed
()
{
loadingAd
=
false
}
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ads/applovin/MaxInsertMgr.kt
View file @
f43b9a38
package
com.base.appzxhy.ads.applovin
import
android.app.Activity
import
android.content.Context
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.MaxAdListener
import
com.applovin.mediation.MaxError
import
com.applovin.mediation.ads.MaxInterstitialAd
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.MyApplication
import
com.base.appzxhy.ads.AdCountDownDialog.createUICountdownTimer
import
com.base.appzxhy.ads.AdCountDownDialog.showAdCountDownDialog
import
com.base.appzxhy.ads.AdsType
import
com.base.appzxhy.ads.AdDialog.showAdPreparingDialog
import
com.base.appzxhy.ads.AdEvent
import
com.base.appzxhy.ads.AdsShowCallBack
import
com.base.appzxhy.ads.LimitUtils
import
com.base.appzxhy.ads.adState
import
java.lang.ref.WeakReference
/**
*插屏广告加载显示管理类
*/
class
MaxInsertMgr
{
private
var
adState
=
adState
<
MaxInterstitialAd
>()
private
var
showCallBack
:
AdsShowCallBack
?
=
null
private
var
adState
=
MaxAdState
().
apply
{
currentAd
=
MaxInterstitialAd
(
GlobalConfig
.
ID_MAX_INTER
,
MyApplication
.
appContext
)
}
fun
show
(
activity
:
Activity
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?
)
{
if
(
activity
.
isFinishing
||
activity
.
isDestroyed
)
{
showCallBack
?.
failed
(
0
)
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
showCallBack
?.
failed
(
1
)
return
}
if
(
adState
.
showingAd
)
{
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
)
)
{
showCallBack
?.
failed
(
2
)
return
}
if
(
showCallBack
!=
null
)
{
adState
.
activityRef
=
WeakReference
(
activity
)
this
.
showCallBack
=
showCallBack
if
(
adState
.
adDialog
==
null
)
{
adState
.
adDialog
=
activity
.
showAdPreparingDialog
(
2
)
}
adEvent
.
adPrepareShow
()
}
if
(!
adState
.
loadingAd
)
{
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
showCallBack
?.
failed
(
3
)
return
}
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
(
4
)
return
}
}
adEvent
.
adPrepareShow
()
if
(!
adAvailable
()
||
adState
.
currentAd
==
null
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
}
val
loadingDialog
=
activity
.
showAdCountDownDialog
()
if
(
adState
.
currentAd
?.
isReady
==
false
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
if
(
adState
.
currentAd
==
null
||
!
adAvailable
())
{
loadAd
(
adEvent
)
{
flag
:
Boolean
->
if
(
flag
)
{
createUICountdownTimer
(
loadingDialog
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
else
{
showCallBack
?.
failed
()
}
}
showReadyAd
(
adEvent
)
}
else
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
private
fun
showReadyAd
(
adEvent
:
AdEvent
)
{
adState
.
currentAd
?.
run
{
private
fun
showReadyAd
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
val
ad
=
adState
.
currentAd
as
MaxInterstitialAd
?
ad
?.
run
{
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdLoadFailed
(
p0
:
String
,
p1
:
MaxError
)
=
Unit
...
...
@@ -93,8 +83,7 @@ class MaxInsertMgr {
override
fun
onAdDisplayFailed
(
ad
:
MaxAd
,
error
:
MaxError
)
{
adState
.
onAdDisplayFailed
()
showCallBack
?.
googleFailed
()
showCallBack
=
null
showCallBack
?.
adFailed
()
(
adEvent
as
AdMaxEvent
).
adShowError
(
error
)
}
...
...
@@ -104,7 +93,7 @@ class MaxInsertMgr {
adState
.
onAdHidden
()
showCallBack
?.
close
()
loadAd
(
activity
.
applicationContext
,
false
,
AdMaxEvent
(
"interAd"
,
"preload"
))
loadAd
(
AdMaxEvent
(
"interAd"
,
"preload"
))
}
override
fun
onAdClicked
(
ad
:
MaxAd
)
{
...
...
@@ -123,53 +112,43 @@ class MaxInsertMgr {
fun
loadAd
(
context
:
Context
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
,
loadCallBack
:
((
flag
:
Boolean
)
->
Unit
)?
=
null
)
{
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
this
.
showCallBack
?.
close
(
4
)
this
.
showCallBack
=
null
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
loadCallBack
?.
invoke
(
false
)
return
}
if
(!
adState
.
loadingAd
)
{
adState
.
loadingAd
=
true
adEvent
.
adPulStart
()
adState
.
currentAd
=
MaxInterstitialAd
(
GlobalConfig
.
ID_MAX_INTER
,
context
)
adState
.
currentAd
?.
setListener
(
object
:
MaxAdListener
{
val
ad
=
adState
.
currentAd
as
MaxInterstitialAd
?
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdHidden
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdClicked
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
p1
:
MaxError
)
=
Unit
ad
?.
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
adState
.
onAdLoaded
(
null
)
val
ac
=
adState
.
activityRef
?.
get
()
if
(
ac
!=
null
)
{
show
(
ac
,
isUnLimit
,
adEvent
,
null
)
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdHidden
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdClicked
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
p1
:
MaxError
)
=
Unit
(
adEvent
as
AdMaxEvent
).
pullAd
(
ad
)
LimitUtils
.
addRequestNum
()
}
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
loadCallBack
?.
invoke
(
true
)
adState
.
onAdLoaded
()
(
adEvent
as
AdMaxEvent
).
pullAd
(
ad
)
LimitUtils
.
addRequestNum
()
}
override
fun
onAdLoadFailed
(
ad
:
String
,
error
:
MaxError
)
{
adState
.
onAdLoadFailed
()
override
fun
onAdLoadFailed
(
ad
:
String
,
error
:
MaxError
)
{
loadCallBack
?.
invoke
(
false
)
adState
.
onAdLoadFailed
()
(
adEvent
as
AdMaxEvent
).
pullAd
(
null
,
error
)
(
adEvent
as
AdMaxEvent
).
pullAd
(
null
,
error
)
}
showCallBack
?.
googleFailed
(
5
)
showCallBack
=
null
}
})
})
adState
.
currentAd
?.
loadAd
()
if
(!
adState
.
loadingAd
)
{
adState
.
loadingAd
=
true
adEvent
.
adPulStart
()
ad
?.
loadAd
()
}
}
...
...
app/src/main/java/com/base/appzxhy/ads/applovin/MaxNativeMgr.kt
View file @
f43b9a38
package
com.base.appzxhy.ads.applovin
import
android.widget.FrameLayout
import
androidx.annotation.LayoutRes
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.MaxError
import
com.applovin.mediation.nativeAds.MaxNativeAdListener
import
com.applovin.mediation.nativeAds.MaxNativeAdLoader
import
com.applovin.mediation.nativeAds.MaxNativeAdView
import
com.applovin.mediation.nativeAds.MaxNativeAdViewBinder
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.R
import
com.base.appzxhy.ads.AdsType
import
com.base.appzxhy.ads.LimitUtils
import
com.base.appzxhy.ads.NativeParentView
import
com.base.appzxhy.helper.EventUtils
import
org.json.JSONObject
import
java.util.UUID
...
...
@@ -30,10 +32,9 @@ class MaxNativeMgr {
private
var
currentAd
:
MaxAd
?
=
null
private
var
currentLoader
:
MaxNativeAdLoader
?
=
null
private
fun
loadAd
(
adMaxEvent
:
AdMaxEvent
,
parent
:
NativeParentView
,
parent
:
FrameLayout
,
@LayoutRes
layout
:
Int
)
{
...
...
@@ -71,7 +72,7 @@ class MaxNativeMgr {
fun
show
(
adMaxEvent
:
AdMaxEvent
,
parent
:
NativeParentView
,
parent
:
FrameLayout
,
@LayoutRes
layout
:
Int
,
nativeCallBack
:
((
Any
?)
->
Unit
)?
=
null
)
{
...
...
@@ -105,11 +106,41 @@ class MaxNativeMgr {
val
obj
=
JSONObject
()
obj
.
put
(
"ad_unit"
,
"nativeAd"
)
EventUtils
.
event
(
"ad_prepare_show"
,
ext
=
obj
)
parent
.
setNativeAd
(
nativeLoader
!!
,
nativeAd
!!
,
layout
)
setMaxNativeAd
(
parent
,
layout
)
nativeCallBack
?.
invoke
(
nativeAd
)
}
private
fun
adAvailable
():
Boolean
{
return
((
System
.
currentTimeMillis
()
-
lastTime
)
/
1000
/
60
).
toInt
()
<
30
}
private
fun
setMaxNativeAd
(
parent
:
FrameLayout
,
layout
:
Int
)
{
// val binder: MaxNativeAdViewBinder = MaxNativeAdViewBinder.Builder(R.layout.layout_max_native_custom)
// .setTitleTextViewId(R.id.title_text_view)
// .setBodyTextViewId(R.id.body_text_view)
// .setAdvertiserTextViewId(R.id.advertiser_text_view)
// .setIconImageViewId(R.id.icon_image_view)
// .setMediaContentViewGroupId(R.id.media_view_container)
// .setOptionsContentViewGroupId(R.id.options_view)
// .setStarRatingContentViewGroupId(R.id.star_rating_view)
// .setCallToActionButtonId(R.id.cta_button)
// .build()
// return MaxNativeAdView(binder, context)
val
binder
:
MaxNativeAdViewBinder
=
MaxNativeAdViewBinder
.
Builder
(
layout
)
.
setTitleTextViewId
(
R
.
id
.
ad_headline
)
.
setBodyTextViewId
(
R
.
id
.
ad_body
)
// .setAdvertiserTextViewId(R.id.advertiser_text_view)
.
setIconImageViewId
(
R
.
id
.
ad_app_icon
)
.
setMediaContentViewGroupId
(
R
.
id
.
ad_media
)
// .setOptionsContentViewGroupId(R.id.options_view)
// .setStarRatingContentViewGroupId(R.id.star_rating_view)
.
setCallToActionButtonId
(
R
.
id
.
ad_call_to_action
)
.
build
()
val
maxNativeAdView
=
MaxNativeAdView
(
binder
,
parent
.
context
)
parent
.
removeAllViews
()
parent
.
addView
(
maxNativeAdView
)
}
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ads/applovin/MaxOpenMgr.kt
View file @
f43b9a38
package
com.base.appzxhy.ads.applovin
import
android.app.Activity
import
android.content.Context
import
com.applovin.mediation.MaxAd
import
com.applovin.mediation.MaxAdListener
import
com.applovin.mediation.MaxError
import
com.applovin.mediation.ads.MaxAppOpenAd
import
com.base.appzxhy.GlobalConfig
import
com.base.appzxhy.MyApplication
import
com.base.appzxhy.ads.AdCountDownDialog.createUICountdownTimer
import
com.base.appzxhy.ads.AdCountDownDialog.showAdCountDownDialog
import
com.base.appzxhy.ads.AdsType
import
com.base.appzxhy.ads.AdEvent
import
com.base.appzxhy.ads.AdsShowCallBack
import
com.base.appzxhy.ads.LimitUtils
import
com.base.appzxhy.ads.adState
import
java.lang.ref.WeakReference
/**
* 开屏广告加载显示管理类
*/
class
MaxOpenMgr
{
private
val
adState
=
adState
<
MaxAppOpenAd
>()
private
var
showCallBack
:
AdsShowCallBack
?
=
null
private
val
adState
=
MaxAdState
().
apply
{
currentAd
=
MaxAppOpenAd
(
GlobalConfig
.
ID_MAX_OPEN
,
MyApplication
.
appContext
)
}
fun
show
(
activity
:
Activity
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
fun
show
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
if
(
activity
.
isFinishing
||
activity
.
isDestroyed
)
{
showCallBack
?.
failed
(
0
)
return
}
if
(
adState
.
showingAd
)
{
showCallBack
?.
failed
()
adEvent
.
adShowError
(
"showingAd"
)
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
INSERT
,
adEvent
))
{
showCallBack
?.
failed
(
1
)
return
}
if
(
showCallBack
!=
null
)
{
this
.
showCallBack
=
showCallBack
adState
.
activityRef
=
WeakReference
(
activity
)
adEvent
.
adPrepareShow
()
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
(
2
)
return
}
if
(!
adState
.
loadingAd
)
{
adEvent
.
adPrepareShow
()
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
showCallBack
?.
failed
()
return
}
if
(
LimitUtils
.
isIntervalLimited
(
adState
.
lastShowTime
,
adEvent
))
{
showCallBack
?.
failed
()
return
}
}
if
(!
adAvailable
()
||
adState
.
currentAd
==
null
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
}
val
loadingDialog
=
activity
.
showAdCountDownDialog
()
if
(
adState
.
currentAd
?.
isReady
!=
true
)
{
loadAd
(
activity
,
isUnLimit
,
adEvent
)
return
if
(!
adAvailable
())
{
loadAd
(
adEvent
)
{
flag
:
Boolean
->
if
(
flag
)
{
createUICountdownTimer
(
loadingDialog
)
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
else
{
showCallBack
?.
failed
()
}
}
showReadyAd
(
activity
,
adEvent
)
}
else
{
showReadyAd
(
activity
,
adEvent
,
showCallBack
)
}
}
private
fun
showReadyAd
(
activity
:
Activity
,
adEvent
:
AdEvent
)
{
adState
.
currentAd
?.
run
{
private
fun
showReadyAd
(
activity
:
Activity
,
adEvent
:
AdEvent
,
showCallBack
:
AdsShowCallBack
?)
{
val
ad
=
adState
.
currentAd
as
MaxAppOpenAd
?
ad
?.
run
{
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
p0
:
MaxAd
)
{
}
override
fun
onAdLoaded
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdLoadFailed
(
p0
:
String
,
p1
:
MaxError
)
=
Unit
override
fun
onAdDisplayed
(
ad
:
MaxAd
)
{
adState
.
onAdDisplayed
()
showCallBack
?.
show
()
LimitUtils
.
addDisplayNum
()
(
adEvent
as
AdMaxEvent
).
showAd
(
ad
,
activity
::
class
.
simpleName
)
}
...
...
@@ -86,9 +78,7 @@ class MaxOpenMgr {
override
fun
onAdHidden
(
p0
:
MaxAd
)
{
adState
.
onAdHidden
()
showCallBack
?.
close
()
showCallBack
=
null
loadAd
(
activity
.
applicationContext
,
false
,
AdMaxEvent
(
"openAd"
,
"preload"
))
loadAd
(
AdMaxEvent
(
"openAd"
,
"preload"
))
}
override
fun
onAdClicked
(
ad
:
MaxAd
)
{
...
...
@@ -97,14 +87,10 @@ class MaxOpenMgr {
LimitUtils
.
addClickNum
()
}
override
fun
onAdLoadFailed
(
p0
:
String
,
p1
:
MaxError
)
{
}
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
error
:
MaxError
)
{
adState
.
onAdDisplayFailed
()
showCallBack
?.
googleFailed
()
showCallBack
=
null
showCallBack
?.
adFailed
()
adEvent
.
adShowError
(
error
)
}
...
...
@@ -114,60 +100,43 @@ class MaxOpenMgr {
}
}
fun
loadAd
(
context
:
Context
,
isUnLimit
:
Boolean
,
adEvent
:
AdEvent
)
{
fun
loadAd
(
adEvent
:
AdEvent
,
loadCallBack
:
((
flag
:
Boolean
)
->
Unit
)?
=
null
)
{
if
(!
isUnLimit
)
{
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
this
.
showCallBack
?.
close
()
this
.
showCallBack
=
null
return
}
if
(!
LimitUtils
.
isAdShow
(
AdsType
.
OPEN
,
adEvent
))
{
loadCallBack
?.
invoke
(
false
)
return
}
val
ad
=
adState
.
currentAd
as
MaxAppOpenAd
?
ad
?.
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
adState
.
onAdLoaded
()
loadCallBack
?.
invoke
(
true
)
(
adEvent
as
AdMaxEvent
).
pullAd
(
ad
)
LimitUtils
.
addRequestNum
()
}
override
fun
onAdLoadFailed
(
p0
:
String
,
error
:
MaxError
)
{
adState
.
onAdLoadFailed
()
(
adEvent
as
AdMaxEvent
).
pullAd
(
null
,
error
)
loadCallBack
?.
invoke
(
false
)
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdHidden
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdClicked
(
p0
:
MaxAd
)
=
Unit
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
p1
:
MaxError
)
=
Unit
})
if
(!
adState
.
loadingAd
)
{
adState
.
loadingAd
=
true
adEvent
.
adPulStart
()
adState
.
currentAd
=
MaxAppOpenAd
(
GlobalConfig
.
ID_MAX_OPEN
,
context
)
adState
.
currentAd
?.
setListener
(
object
:
MaxAdListener
{
override
fun
onAdLoaded
(
ad
:
MaxAd
)
{
adState
.
onAdLoaded
(
null
)
val
ac
=
adState
.
activityRef
?.
get
()
if
(
ac
!=
null
)
{
show
(
ac
,
isUnLimit
,
adEvent
,
null
)
}
(
adEvent
as
AdMaxEvent
).
pullAd
(
ad
)
LimitUtils
.
addRequestNum
()
}
override
fun
onAdDisplayed
(
p0
:
MaxAd
)
{
}
override
fun
onAdHidden
(
p0
:
MaxAd
)
{
}
override
fun
onAdClicked
(
p0
:
MaxAd
)
{
}
override
fun
onAdLoadFailed
(
p0
:
String
,
error
:
MaxError
)
{
adState
.
onAdLoadFailed
()
showCallBack
?.
googleFailed
()
showCallBack
=
null
(
adEvent
as
AdMaxEvent
).
pullAd
(
null
,
error
)
}
override
fun
onAdDisplayFailed
(
p0
:
MaxAd
,
p1
:
MaxError
)
{
}
})
adState
.
currentAd
?.
loadAd
()
ad
?.
loadAd
()
}
}
fun
adAvailable
()
=
((
System
.
currentTimeMillis
()
-
adState
.
lastLoadTime
)
/
1000
/
60
).
toInt
()
<
30
private
fun
adAvailable
()
=
((
System
.
currentTimeMillis
()
-
adState
.
lastLoadTime
)
/
1000
/
60
).
toInt
()
<
30
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/base/BaseActivity.kt
deleted
100644 → 0
View file @
4f5c6253
package
com.base.appzxhy.base
import
android.app.Activity
import
android.app.Dialog
import
android.content.Context
import
android.content.Intent
import
android.os.Bundle
import
android.view.LayoutInflater
import
androidx.appcompat.app.AppCompatActivity
import
androidx.lifecycle.lifecycleScope
import
androidx.viewbinding.ViewBinding
import
com.base.appzxhy.ui.main.MainActivity
import
com.base.appzxhy.R
import
com.base.appzxhy.bean.ConstObject.appLanguageCountrySp
import
com.base.appzxhy.bean.ConstObject.appLanguageSp
import
com.base.appzxhy.helper.EventUtils
import
com.base.appzxhy.utils.ActivityLauncher
import
com.base.appzxhy.utils.ActivityManagerUtils
import
com.base.appzxhy.utils.LogEx
import
com.gyf.immersionbar.ktx.immersionBar
import
com.hjq.language.MultiLanguages
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.delay
import
kotlinx.coroutines.launch
import
java.util.Locale
import
java.util.concurrent.atomic.AtomicBoolean
import
kotlin.random.Random
abstract
class
BaseActivity
<
VB
:
ViewBinding
>(
bindingInflater
:
(
LayoutInflater
)
->
VB
)
:
AppCompatActivity
()
{
open
val
TAG
=
javaClass
.
simpleName
private
val
tagNo
=
Random
.
nextInt
(
500
)
val
binding
by
lazy
(
LazyThreadSafetyMode
.
NONE
)
{
bindingInflater
(
layoutInflater
)
}
lateinit
var
launcher
:
ActivityLauncher
private
var
currentLocale
:
Locale
?
=
null
var
onCreateI
=
0
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
configSystemBar
()
onCreateI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onCreate ${javaClass.simpleName} $onCreateI"
)
launcher
=
ActivityLauncher
(
this
)
setContentView
(
binding
.
root
)
EventUtils
.
event
(
"page_${javaClass.simpleName}"
)
currentLocale
=
Locale
(
appLanguageSp
,
appLanguageCountrySp
)
initView
()
initListener
()
}
protected
open
fun
initView
()
{}
protected
open
fun
initListener
()
{}
fun
finishToMain
(
delay
:
Long
=
0
)
{
val
flag
=
this
!
is
MainActivity
&&
!
ActivityManagerUtils
.
getInstance
().
isActivityInStack
(
MainActivity
::
class
.
java
)
if
(
flag
)
{
startActivity
(
Intent
(
this
,
MainActivity
::
class
.
java
).
apply
{
putExtra
(
"where"
,
"finishToMain"
)
})
}
lifecycleScope
.
launch
(
Dispatchers
.
Main
)
{
delay
(
delay
)
finish
()
}
}
fun
finishToMainTop
()
{
val
intent
=
Intent
(
this
,
MainActivity
::
class
.
java
)
intent
.
putExtra
(
"where"
,
"finishToMainTop"
)
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_REORDER_TO_FRONT
)
startActivity
(
intent
)
}
var
dialog
:
Dialog
?
=
null
override
fun
onDestroy
()
{
super
.
onDestroy
()
ActivityManagerUtils
.
getInstance
().
removeActivity
(
this
)
if
(
dialog
!=
null
)
{
dialog
?.
dismiss
()
dialog
=
null
}
}
override
fun
attachBaseContext
(
newBase
:
Context
?)
{
super
.
attachBaseContext
(
MultiLanguages
.
attach
(
newBase
))
}
fun
changeLanguage
(
currentActivity
:
Activity
,
bundle
:
Bundle
=
Bundle
()):
Boolean
{
val
spLanguage
=
Locale
(
appLanguageSp
,
appLanguageCountrySp
)
val
flag
=
currentLocale
!=
spLanguage
val
restart
=
MultiLanguages
.
setAppLanguage
(
this
,
spLanguage
)
LogEx
.
logDebug
(
TAG
,
"changeLanguage "
+
"flag=$flag restart=$restart currentLocale=$currentLocale spLanguage=$spLanguage"
)
if
(
restart
)
{
currentLocale
=
Locale
(
appLanguageSp
,
appLanguageCountrySp
)
}
if
(
flag
||
restart
)
{
// 1.使用 recreate 来重启 Activity,效果差,有闪屏的缺陷
// recreate();
// 2.使用常规 startActivity 来重启 Activity,有从左向右的切换动画
// 稍微比 recreate 的效果好一点,但是这种并不是最佳的效果
// startActivity(new Intent(this, LanguageActivity.class));
// finish();
// 3.我们可以充分运用 Activity 跳转动画,在跳转的时候设置一个渐变的效果,相比前面的两种带来的体验是最佳的
//需要设置启动模式,避免AndroidManifest.xml设置singleTop启动模式导致重复启动不生效
//这种方式如果设置了singleTop或者singleTask的,再次回到该activity无法改变于语言,因为还在堆栈里没有重新创建
needRecreate
()
if
(
needRecreate
())
{
LogEx
.
logDebug
(
TAG
,
"changeLanguage recreate"
)
recreate
()
}
else
{
startActivity
(
Intent
(
this
,
currentActivity
::
class
.
java
).
apply
{
putExtras
(
bundle
)
})
overridePendingTransition
(
R
.
anim
.
activity_alpha_in
,
R
.
anim
.
activity_alpha_out
)
finish
()
}
return
true
}
return
false
}
/**
* 判断是否需要重新创建对SingleTop启动模式的有效
*/
fun
needRecreate
():
Boolean
{
return
TAG
.
contains
(
"MainActivity"
)
}
/**
* 避免在onResume--onPause周期内,多次调用
* 在onStop中重置标志
*/
private
val
onResumeCalled
=
AtomicBoolean
(
false
)
private
var
onResumeOneShootI
=
0
open
fun
onResumeOneShoot
()
{
onResumeOneShootI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onResumeOneShoot ${javaClass.simpleName} $onResumeOneShootI"
)
}
private
var
onResumeI
=
0
override
fun
onResume
()
{
super
.
onResume
()
onResumeI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onResume ${javaClass.simpleName} $onResumeI"
)
if
(!
onResumeCalled
.
get
())
{
onResumeCalled
.
set
(
true
)
onResumeOneShoot
()
}
}
private
var
onStartI
=
0
override
fun
onStart
()
{
super
.
onStart
()
onStartI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onStart ${javaClass.simpleName} $onStartI"
)
}
private
var
onStopI
=
0
override
fun
onStop
()
{
super
.
onStop
()
onStopI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onStop ${javaClass.simpleName} $onStopI"
)
onResumeCalled
.
set
(
false
)
}
private
var
onPauseI
=
0
override
fun
onPause
()
{
super
.
onPause
()
onPauseI
++
LogEx
.
logDebug
(
TAG
,
"lifecycle $tagNo onPause ${javaClass.simpleName} $onPauseI"
)
}
open
fun
configSystemBar
()
{
immersionBar
{
statusBarColor
(
"#FFFFFFFF"
)
navigationBarColor
(
"#FFFFFFFF"
)
statusBarDarkFont
(
true
)
navigationBarDarkIcon
(
true
)
fitsSystemWindows
(
true
)
}
}
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/base/BaseFragment.kt
deleted
100644 → 0
View file @
4f5c6253
@file
:
Suppress
(
"unused"
)
package
com.base.appzxhy.base
import
android.app.Activity
import
android.content.Intent
import
android.os.Bundle
import
android.view.LayoutInflater
import
android.view.View
import
android.view.ViewGroup
import
androidx.fragment.app.Fragment
import
androidx.viewbinding.ViewBinding
/**
*
* @param VB : ViewBinding
* 基本的fragment绑定数据
*/
abstract
class
BaseFragment
<
VB
:
ViewBinding
>(
private
val
bindingInflater
:
(
LayoutInflater
,
ViewGroup
?,
Boolean
)
->
VB
)
:
Fragment
()
{
private
var
_binding
:
VB
?
=
null
private
var
fragmentInit
=
false
open
val
TAG
=
javaClass
.
simpleName
//重写binding get()方法不直接暴露真实的可空_binding数据
@Suppress
(
"MemberVisibilityCanBePrivate"
)
val
binding
:
VB
get
()
=
_binding
!!
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?
):
View
{
_binding
=
bindingInflater
.
invoke
(
inflater
,
container
,
false
)
return
binding
.
root
}
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
initView
()
initListener
()
}
protected
open
fun
initView
()
{}
protected
open
fun
initListener
()
{}
open
fun
onResumeOneShoot
()
=
Unit
override
fun
onResume
()
{
if
(!
fragmentInit
)
{
onResumeOneShoot
()
fragmentInit
=
true
}
super
.
onResume
()
}
override
fun
onDestroyView
()
{
super
.
onDestroyView
()
//要手动置null防止内存泄漏
_binding
=
null
}
}
inline
fun
<
VB
:
ViewBinding
>
BaseFragment
<
VB
>.
viewBind
(
block
:
VB
.()
->
Unit
)
{
binding
.
apply
(
block
)
}
inline
fun
Fragment
.
goToAc
(
clazz
:
Class
<
out
Activity
>,
block
:
(
Intent
.()
->
Unit
)
=
{})
{
context
?.
startActivity
(
Intent
(
context
,
clazz
).
apply
(
block
))
}
app/src/main/java/com/base/appzxhy/ui/main/HomeFragment.kt
View file @
f43b9a38
package
com.base.appzxhy.ui.main
import
com.base.appzxhy.base.BaseFragment
import
com.base.appzxhy.databinding.FragmentHomeBinding
import
com.koko.drouter.base.BaseFragment
class
HomeFragment
:
BaseFragment
<
FragmentHomeBinding
>(
FragmentHomeBinding
::
inflate
)
{
...
...
app/src/main/java/com/base/appzxhy/ui/main/MainActivity.kt
View file @
f43b9a38
...
...
@@ -3,17 +3,18 @@ package com.base.appzxhy.ui.main
import
android.graphics.Color
import
android.view.LayoutInflater
import
android.widget.TextView
import
androidx.fragment.app.Fragment
import
androidx.lifecycle.ViewModelProvider
import
androidx.
navigation.NavControll
er
import
androidx.
navigation.fragment.NavHostFragment
import
androidx.
viewpager2.adapter.FragmentStateAdapt
er
import
androidx.
viewpager2.widget.ViewPager2
import
com.base.appzxhy.R
import
com.base.appzxhy.base.BaseActivity
import
com.base.appzxhy.bean.HomeTabUIBean
import
com.base.appzxhy.databinding.ActivityMainBinding
import
com.base.appzxhy.databinding.ItemHomeTabBinding
import
com.base.appzxhy.utils.LogEx
import
com.google.android.material.tabs.TabLayout
import
com.google.android.material.tabs.TabLayout.OnTabSelectedListener
import
com.koko.drouter.base.BaseActivity
class
MainActivity
:
BaseActivity
<
ActivityMainBinding
>(
ActivityMainBinding
::
inflate
)
{
...
...
@@ -21,18 +22,58 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
ViewModelProvider
(
this
)[
MainViewModel
::
class
.
java
]
}
private
lateinit
var
navController
:
NavController
private
val
homeTabs
by
lazy
{
arrayOf
(
HomeTabUIBean
(
R
.
drawable
.
bg_selector_home
,
getString
(
R
.
string
.
home
)),
)
}
private
val
homeFragment
by
lazy
(
LazyThreadSafetyMode
.
NONE
)
{
HomeFragment
()
}
private
val
fragments
=
arrayOf
(
homeFragment
)
private
var
pageAdapter
:
FragmentStateAdapter
?
=
null
override
fun
initView
()
{
super
.
initView
()
navController
=
(
supportFragmentManager
.
findFragmentById
(
R
.
id
.
fragment_container
)
as
NavHostFragment
).
navController
initViewPager2
()
initTab
()
}
private
fun
initViewPager2
()
{
pageAdapter
=
object
:
FragmentStateAdapter
(
this
)
{
override
fun
getItemCount
():
Int
{
return
fragments
.
size
}
override
fun
createFragment
(
position
:
Int
):
Fragment
{
return
fragments
[
position
]
}
}
binding
.
viewPager2
.
run
{
isUserInputEnabled
=
false
//https://www.jianshu.com/p/f69bd30cf5b0
//FragmentStateAdapter 这里必须传人fragment
adapter
=
pageAdapter
offscreenPageLimit
=
3
}
binding
.
viewPager2
.
registerOnPageChangeCallback
(
object
:
ViewPager2
.
OnPageChangeCallback
()
{
override
fun
onPageScrolled
(
position
:
Int
,
positionOffset
:
Float
,
positionOffsetPixels
:
Int
)
{
super
.
onPageScrolled
(
position
,
positionOffset
,
positionOffsetPixels
)
}
override
fun
onPageSelected
(
position
:
Int
)
{
val
defaultTab
=
binding
.
tabLayout
.
getTabAt
(
position
)
defaultTab
?.
select
()
defaultTab
?.
setSelected
()
}
})
}
private
fun
initTab
()
{
homeTabs
.
forEachIndexed
{
index
,
homeTab
->
val
tab
=
binding
.
tabLayout
.
newTab
()
...
...
@@ -47,7 +88,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
binding
.
tabLayout
.
addOnTabSelectedListener
(
object
:
OnTabSelectedListener
{
override
fun
onTabSelected
(
tab
:
TabLayout
.
Tab
?)
{
tab
?.
setSelected
()
tab
?.
let
{
it
.
setSelected
()
naviFragment
(
tab
.
id
)
}
}
override
fun
onTabUnselected
(
tab
:
TabLayout
.
Tab
?)
{
...
...
@@ -65,6 +109,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
private
fun
naviFragment
(
id
:
Int
)
{
if
(
binding
.
viewPager2
.
currentItem
==
id
)
return
binding
.
viewPager2
.
setCurrentItem
(
id
,
false
)
when
(
id
)
{
0
->
{
}
...
...
@@ -87,7 +133,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
val
textView
=
customView
?.
findViewById
<
TextView
>(
R
.
id
.
tv_tab
)
LogEx
.
logDebug
(
TAG
,
"setSelected ${textView?.text}"
)
textView
?.
setTextColor
(
Color
.
parseColor
(
"#FF0000"
))
naviFragment
(
this
.
id
)
}
}
\ No newline at end of file
app/src/main/java/com/base/appzxhy/ui/start/StartActivity.kt
View file @
f43b9a38
...
...
@@ -2,9 +2,14 @@ package com.base.appzxhy.ui.start
import
android.annotation.SuppressLint
import
android.content.Intent
import
com.base.appzxhy.base.BaseActivity
import
android.graphics.Color
import
androidx.activity.SystemBarStyle
import
androidx.activity.enableEdgeToEdge
import
androidx.core.view.ViewCompat
import
androidx.core.view.WindowInsetsCompat
import
com.base.appzxhy.databinding.ActivityStartBinding
import
com.koko.batteryinfo.BatteryInfoActivity
import
com.koko.drouter.base.BaseActivity
class
StartActivity
:
BaseActivity
<
ActivityStartBinding
>(
ActivityStartBinding
::
inflate
)
{
...
...
@@ -12,6 +17,16 @@ class StartActivity : BaseActivity<ActivityStartBinding>(ActivityStartBinding::i
super
.
initView
()
}
override
fun
useDefaultImmersive
()
{
// enableEdgeToEdge(SystemBarStyle.light(Color.TRANSPARENT, Color.TRANSPARENT))
enableEdgeToEdge
(
SystemBarStyle
.
dark
(
Color
.
TRANSPARENT
))
ViewCompat
.
setOnApplyWindowInsetsListener
(
binding
.
root
)
{
v
,
insets
->
val
systemBars
=
insets
.
getInsets
(
WindowInsetsCompat
.
Type
.
systemBars
())
v
.
setPadding
(
systemBars
.
left
,
0
,
systemBars
.
right
,
systemBars
.
bottom
)
insets
}
}
@SuppressLint
(
"SetTextI18n"
)
override
fun
initListener
()
{
...
...
app/src/main/java/com/base/appzxhy/ui/start/StartViewModel.kt
0 → 100644
View file @
f43b9a38
package
com.base.appzxhy.ui.start
import
android.os.CountDownTimer
import
androidx.lifecycle.ViewModel
import
com.base.appzxhy.bean.config.AdConfigBean
class
StartViewModel
:
ViewModel
()
{
var
jumpNext
:
(()
->
Unit
)?
=
null
var
onTick
:
((
sLong
:
Long
,
total
:
Long
,
percent
:
Int
)
->
Unit
)?
=
null
private
val
openAdLoading
=
AdConfigBean
.
adsConfigBean
.
openAdLoading
*
1000L
private
var
countdownTimer
:
CountDownTimer
?
=
null
fun
startJumpCountdown
()
{
cancelJumpCountDown
()
countdownTimer
=
createNewCountdownTimer
()
countdownTimer
?.
start
()
}
fun
cancelJumpCountDown
()
{
countdownTimer
?.
cancel
()
onTick
?.
invoke
(
0
,
openAdLoading
,
0
)
}
private
fun
createNewCountdownTimer
():
CountDownTimer
{
return
object
:
CountDownTimer
(
openAdLoading
,
1000
)
{
override
fun
onTick
(
millisUntilFinished
:
Long
)
{
val
progress
=
(
openAdLoading
-
millisUntilFinished
)
val
percent
=
(
progress
*
100
/
openAdLoading
).
toInt
()
onTick
?.
invoke
(
progress
,
openAdLoading
,
percent
)
}
override
fun
onFinish
()
{
onTick
?.
invoke
(
openAdLoading
,
openAdLoading
,
100
)
jumpNext
?.
invoke
()
jumpNext
=
null
}
}
}
}
\ No newline at end of file
app/src/main/res/drawable/bg_ffffff_15.xml
0 → 100644
View file @
f43b9a38
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"#ffffff"
/>
<corners
android:radius=
"15dp"
/>
</shape>
\ No newline at end of file
app/src/main/res/layout/activity_main.xml
View file @
f43b9a38
...
...
@@ -6,14 +6,13 @@
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
<androidx.
fragment.app.FragmentContainerView
android:id=
"@+id/
fragment_container
"
<androidx.
viewpager2.widget.ViewPager2
android:id=
"@+id/
viewPager2
"
android:name=
"androidx.navigation.fragment.NavHostFragment"
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
app:layout_constraintBottom_toTopOf=
"@id/fl_tab"
app:layout_constraintTop_toTopOf=
"parent"
app:navGraph=
"@navigation/nav_graph"
/>
app:layout_constraintTop_toTopOf=
"parent"
/>
<FrameLayout
android:id=
"@+id/fl_tab"
...
...
app/src/main/res/layout/dialog_ad_countdown.xml
0 → 100644
View file @
f43b9a38
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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=
"300dp"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:background=
"@drawable/bg_ffffff_15"
android:orientation=
"vertical"
>
<LinearLayout
android:id=
"@+id/ll"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_horizontal"
android:layout_marginTop=
"30dp"
android:orientation=
"horizontal"
>
<ImageView
android:id=
"@+id/ivYuan"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:layout_marginStart=
"20dp"
android:scaleType=
"centerInside"
android:src=
"@mipmap/zhuanquan"
tools:ignore=
"ContentDescription"
/>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_vertical"
android:layout_marginStart=
"10dp"
android:text=
"AD LOADING"
android:textColor=
"#ff111111"
android:textSize=
"20sp"
tools:ignore=
"HardcodedText"
/>
</LinearLayout>
<TextView
android:id=
"@+id/tvCountdown"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center_horizontal"
android:layout_marginTop=
"16dp"
android:layout_marginBottom=
"24dp"
android:text=
"Ads are about to be shown"
android:textColor=
"#666666"
android:textSize=
"13sp"
tools:ignore=
"HardcodedText"
/>
</LinearLayout>
\ No newline at end of file
app/src/main/res/mipmap-xxhdpi/zhuanquan.png
0 → 100644
View file @
f43b9a38
11.2 KB
app/src/main/res/values/dimens.xml
0 → 100644
View file @
f43b9a38
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen
name=
"dp_300"
>
300dp
</dimen>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment