app 層級 build.gradle
android {
compileSdk {
version = release(36)
}
...
...
buildFeatures {
viewBinding = true
}
defaultConfig {
...
...
minSdk = 26
targetSdk = 36
}
}
...
...
dependencies {
...
...
// adMob
implementation("com.google.android.gms:play-services-ads:25.1.0")
}
strings.xml
<resources>
<string name="dialog_title">確定要離開?</string>
<string name="dialog_message">您確定要關閉應用程式嗎?</string>
<string name="btn_cancel">取消</string>
<string name="btn_exit">離開</string>
...
...
<!-- adMob app id 測試 -->
<string name="admob_app_id">ca-app-pub-3940256099942544~3347511713</string>
<!-- 橫幅 測試 -->
<string name="banner_ad_unit_id">ca-app-pub-3940256099942544/6300978111</string>
</resources>
AndroidManifest.xml
<manifest
<!-- 存取網路連線 -->
<uses-permission android:name="android.permission.INTERNET" />
...
...
<application ... >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id" />
...
...
<!-- AdMob 的 AdActivity -->
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
...
...
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
自定義對話框 dialog_exit.xml,因為版面很單純,所以採用 LinearLayout。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:id="@+id/tv_dialog_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_title"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="?attr/colorOnSurface"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="end"
android:orientation="horizontal">
<Button
android:id="@+id/btn_cancel"
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_cancel" />
<Button
android:id="@+id/btn_exit"
style="?attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/btn_exit"
android:textColor="?attr/colorError"/>
</LinearLayout>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ads:adSize="MEDIUM_RECTANGLE"
ads:adUnitId="@string/banner_ad_unit_id" />
</LinearLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
// 設定返回鍵攔截(支援新舊所有 Android 版本)
setupBackPressedListener()
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
private fun setupBackPressedListener() {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// 當使用者按下返回鍵(或手勢返回)時,顯示對話框
showExitCustomDialog()
}
}
// 將 callback 加到 Dispatcher 中,它會自動處理生命週期
onBackPressedDispatcher.addCallback(this, callback)
}
private fun showExitCustomDialog() {
// 初始化 Dialog 的 View Binding
val dialogBinding = DialogExitBinding.inflate(layoutInflater)
val dialog = MaterialAlertDialogBuilder(this)
.setView(dialogBinding.root)
.setCancelable(true)
.create()
// AdMob 初始化
MobileAds.initialize(this)
dialogBinding.adView.loadAd(AdRequest.Builder().build())
dialogBinding.btnCancel.setOnClickListener {
dialog.dismiss()
}
dialogBinding.btnExit.setOnClickListener {
dialog.dismiss()
finish()
}
dialog.show()
}
}
實際的對話框效果

沒有留言:
張貼留言