Skip to content

Commit 0c80cc0

Browse files
Improve bottom banner ad layering and loading state
1 parent 9805063 commit 0c80cc0

File tree

3 files changed

+142
-72
lines changed

3 files changed

+142
-72
lines changed

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@
4747
import com.d4rk.androidtutorials.java.utils.ConsentUtils;
4848
import com.d4rk.androidtutorials.java.utils.EdgeToEdgeDelegate;
4949
import com.d4rk.androidtutorials.java.utils.ReviewHelper;
50+
import com.d4rk.androidtutorials.java.ads.views.NativeAdBannerView;
5051
import com.google.android.material.navigation.NavigationBarView;
52+
import com.google.android.material.progressindicator.CircularProgressIndicator;
5153
import com.google.android.material.snackbar.Snackbar;
5254
import com.google.android.play.core.appupdate.AppUpdateInfo;
5355
import com.google.android.play.core.appupdate.AppUpdateManager;
@@ -75,18 +77,7 @@ public class MainActivity extends AppCompatActivity {
7577
@Override
7678
public void onResume(@NonNull LifecycleOwner owner) {
7779
ConsentUtils.applyStoredConsent(MainActivity.this);
78-
ActivityMainBinding binding = mBinding;
79-
if (binding != null) {
80-
View adView = binding.adView;
81-
if (adView != null) {
82-
View adPlaceholder = binding.adPlaceholder;
83-
if (adPlaceholder != null) {
84-
adPlaceholder.setVisibility(View.GONE);
85-
}
86-
adView.setVisibility(View.VISIBLE);
87-
AdUtils.loadBanner(adView);
88-
}
89-
}
80+
updateBottomBannerVisibility(!shouldUseNavigationRail());
9081
}
9182
};
9283
private MainViewModel mainViewModel;
@@ -97,6 +88,7 @@ public void onResume(@NonNull LifecycleOwner owner) {
9788
private AppUpdateManager appUpdateManager;
9889
private InstallStateUpdatedListener installStateUpdatedListener;
9990
private long backPressedTime;
91+
private boolean bottomBannerLoading;
10092

10193
@Override
10294
protected void onCreate(Bundle savedInstanceState) {
@@ -217,24 +209,17 @@ private void observeViewModel() {
217209
navRail.setVisibility(View.VISIBLE);
218210
}
219211
navBarView.setVisibility(View.GONE);
212+
updateBottomBannerVisibility(false);
220213
WindowCompat.enableEdgeToEdge(this.getWindow());
221214
} else {
222215
if (navRail != null) {
223216
navRail.setVisibility(View.GONE);
224217
}
225218
navBarView.setVisibility(View.VISIBLE);
219+
updateBottomBannerVisibility(true);
226220
EdgeToEdgeDelegate.applyBottomBar(this, binding.container, navBarView);
227221

228222
navBarView.setLabelVisibilityMode(uiState.bottomNavVisibility());
229-
View adView = binding.adView;
230-
if (adView != null) {
231-
View adPlaceholder = binding.adPlaceholder;
232-
if (adPlaceholder != null) {
233-
adPlaceholder.setVisibility(View.GONE);
234-
}
235-
adView.setVisibility(View.VISIBLE);
236-
AdUtils.loadBanner(adView);
237-
}
238223
}
239224

240225
NavHostFragment navHostFragment = (NavHostFragment)
@@ -326,12 +311,67 @@ private void observeViewModel() {
326311
mainViewModel.getLoadingState().observe(this, isLoading -> {
327312
ActivityMainBinding binding = mBinding;
328313
if (binding != null) {
329-
assert binding.progressBar != null;
330-
binding.progressBar.setVisibility(Boolean.TRUE.equals(isLoading) ? View.VISIBLE : View.GONE);
314+
CircularProgressIndicator progressIndicator = binding.progressBar;
315+
if (progressIndicator != null) {
316+
if (Boolean.TRUE.equals(isLoading)) {
317+
progressIndicator.show();
318+
} else {
319+
progressIndicator.hide();
320+
}
321+
}
331322
}
332323
});
333324
}
334325

326+
private void updateBottomBannerVisibility(boolean showBanner) {
327+
ActivityMainBinding binding = mBinding;
328+
if (binding == null) {
329+
return;
330+
}
331+
View adContainer = binding.adContainer;
332+
if (adContainer != null) {
333+
adContainer.setVisibility(showBanner ? View.VISIBLE : View.GONE);
334+
}
335+
NativeAdBannerView adView = binding.adView;
336+
View adPlaceholder = binding.adPlaceholder;
337+
if (adView == null) {
338+
if (adPlaceholder != null) {
339+
adPlaceholder.setVisibility(View.GONE);
340+
}
341+
return;
342+
}
343+
if (!showBanner) {
344+
if (adPlaceholder != null) {
345+
adPlaceholder.setVisibility(View.GONE);
346+
}
347+
adView.setVisibility(View.GONE);
348+
adView.removeAllViews();
349+
bottomBannerLoading = false;
350+
return;
351+
}
352+
353+
if (adPlaceholder != null) {
354+
adPlaceholder.setVisibility(View.VISIBLE);
355+
}
356+
if (adView.getVisibility() != View.VISIBLE || adView.getChildCount() > 0) {
357+
bottomBannerLoading = false;
358+
}
359+
360+
adView.setVisibility(View.VISIBLE);
361+
if (adView.getChildCount() > 0) {
362+
if (adPlaceholder != null) {
363+
adPlaceholder.setVisibility(View.GONE);
364+
}
365+
bottomBannerLoading = false;
366+
return;
367+
}
368+
369+
if (!bottomBannerLoading) {
370+
bottomBannerLoading = true;
371+
AdUtils.loadBanner(adView);
372+
}
373+
}
374+
335375

336376
private void navigateToPreferredDestination(int preferredDestination) {
337377
if (navController == null) {

app/src/main/res/layout/activity_main.xml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,22 @@
4141
app:layout_constraintTop_toBottomOf="@id/app_bar_layout"
4242
app:navGraph="@navigation/mobile_navigation" />
4343

44+
<com.google.android.material.bottomnavigation.BottomNavigationView
45+
android:id="@+id/nav_view"
46+
android:layout_width="match_parent"
47+
android:layout_height="wrap_content"
48+
app:labelVisibilityMode="labeled"
49+
app:layout_constraintBottom_toBottomOf="parent"
50+
app:menu="@menu/bottom_nav_menu" />
51+
4452
<FrameLayout
4553
android:id="@+id/ad_container"
4654
android:layout_width="match_parent"
4755
android:layout_height="wrap_content"
56+
android:clipChildren="false"
57+
android:clipToPadding="false"
58+
android:elevation="8dp"
59+
android:visibility="gone"
4860
app:layout_constraintBottom_toTopOf="@+id/nav_view"
4961
app:layout_constraintEnd_toEndOf="parent"
5062
app:layout_constraintStart_toStartOf="parent">
@@ -53,27 +65,24 @@
5365
android:id="@+id/ad_placeholder"
5466
android:layout_width="match_parent"
5567
android:layout_height="match_parent"
56-
android:background="?attr/colorSurfaceContainer" />
68+
android:background="?attr/colorSurfaceContainer"
69+
android:visibility="gone" />
5770

5871
<com.d4rk.androidtutorials.java.ads.views.NativeAdBannerView
5972
android:id="@+id/ad_view"
6073
android:layout_width="match_parent"
6174
android:layout_height="wrap_content"
75+
android:visibility="gone"
6276
app:nativeAdLayout="@layout/ad_bottom_app_bar" />
6377
</FrameLayout>
6478

65-
<com.google.android.material.bottomnavigation.BottomNavigationView
66-
android:id="@+id/nav_view"
67-
android:layout_width="match_parent"
68-
android:layout_height="wrap_content"
69-
app:labelVisibilityMode="labeled"
70-
app:layout_constraintBottom_toBottomOf="parent"
71-
app:menu="@menu/bottom_nav_menu" />
72-
73-
<ProgressBar
79+
<com.google.android.material.progressindicator.CircularProgressIndicator
7480
android:id="@+id/progress_bar"
81+
style="@style/Widget.Material3.CircularProgressIndicator"
7582
android:layout_width="wrap_content"
7683
android:layout_height="wrap_content"
84+
android:indeterminate="true"
85+
android:visibility="gone"
7786
app:layout_constraintBottom_toBottomOf="parent"
7887
app:layout_constraintEnd_toEndOf="parent"
7988
app:layout_constraintStart_toStartOf="parent"
Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,84 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
34
android:layout_width="match_parent"
45
android:layout_height="wrap_content">
56

6-
<androidx.appcompat.widget.LinearLayoutCompat
7+
<com.google.android.material.card.MaterialCardView
8+
android:id="@+id/ad_card"
9+
style="@style/Widget.Material3.CardView.Elevated"
710
android:layout_width="match_parent"
811
android:layout_height="wrap_content"
9-
android:orientation="vertical"
10-
android:background="?attr/colorSurfaceContainer"
11-
android:padding="12dp">
12-
13-
<include layout="@layout/ad_attribution" />
12+
android:layout_marginHorizontal="16dp"
13+
android:layout_marginTop="8dp"
14+
android:layout_marginBottom="12dp"
15+
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.CardViewTopRounded">
1416

1517
<androidx.appcompat.widget.LinearLayoutCompat
1618
android:layout_width="match_parent"
1719
android:layout_height="wrap_content"
18-
android:layout_marginTop="8dp"
19-
android:gravity="center_vertical"
20-
android:orientation="horizontal">
20+
android:orientation="vertical"
21+
android:paddingHorizontal="16dp"
22+
android:paddingTop="12dp"
23+
android:paddingBottom="12dp">
2124

22-
<androidx.appcompat.widget.AppCompatImageView
23-
android:id="@+id/ad_app_icon"
24-
android:layout_width="48dp"
25-
android:layout_height="48dp"
26-
android:layout_marginEnd="12dp"
27-
android:visibility="gone" />
25+
<include layout="@layout/ad_attribution" />
2826

2927
<androidx.appcompat.widget.LinearLayoutCompat
30-
android:layout_width="0dp"
28+
android:layout_width="match_parent"
3129
android:layout_height="wrap_content"
32-
android:layout_weight="1"
33-
android:orientation="vertical">
30+
android:layout_marginTop="8dp"
31+
android:gravity="center_vertical"
32+
android:orientation="horizontal">
3433

35-
<com.google.android.material.textview.MaterialTextView
36-
android:id="@+id/ad_headline"
37-
android:layout_width="wrap_content"
34+
<androidx.appcompat.widget.AppCompatImageView
35+
android:id="@+id/ad_app_icon"
36+
android:layout_width="40dp"
37+
android:layout_height="40dp"
38+
android:layout_marginEnd="12dp"
39+
android:contentDescription="@null"
40+
android:visibility="gone" />
41+
42+
<androidx.appcompat.widget.LinearLayoutCompat
43+
android:layout_width="0dp"
3844
android:layout_height="wrap_content"
39-
android:ellipsize="end"
40-
android:maxLines="1"
41-
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
45+
android:layout_weight="1"
46+
android:orientation="vertical">
47+
48+
<com.google.android.material.textview.MaterialTextView
49+
android:id="@+id/ad_headline"
50+
android:layout_width="wrap_content"
51+
android:layout_height="wrap_content"
52+
android:ellipsize="end"
53+
android:maxLines="1"
54+
android:textAppearance="@style/TextAppearance.Material3.BodyLarge" />
55+
56+
<com.google.android.material.textview.MaterialTextView
57+
android:id="@+id/ad_body"
58+
android:layout_width="wrap_content"
59+
android:layout_height="wrap_content"
60+
android:layout_marginTop="2dp"
61+
android:ellipsize="end"
62+
android:maxLines="2"
63+
android:textAppearance="@style/TextAppearance.Material3.BodySmall" />
64+
</androidx.appcompat.widget.LinearLayoutCompat>
4265

43-
<com.google.android.material.textview.MaterialTextView
44-
android:id="@+id/ad_body"
66+
<com.google.android.material.button.MaterialButton
67+
android:id="@+id/ad_call_to_action"
68+
style="@style/Widget.Material3.Button.TextButton"
4569
android:layout_width="wrap_content"
4670
android:layout_height="wrap_content"
47-
android:ellipsize="end"
48-
android:maxLines="1"
49-
android:textAppearance="@style/TextAppearance.Material3.BodySmall" />
71+
android:minHeight="40dp"
72+
android:minWidth="88dp" />
5073
</androidx.appcompat.widget.LinearLayoutCompat>
51-
52-
<com.google.android.material.button.MaterialButton
53-
android:id="@+id/ad_call_to_action"
54-
style="@style/Widget.Material3.Button.TextButton"
55-
android:layout_width="wrap_content"
56-
android:layout_height="wrap_content"
57-
android:layout_marginStart="8dp"
58-
android:minWidth="88dp"
59-
android:minHeight="40dp" />
6074
</androidx.appcompat.widget.LinearLayoutCompat>
61-
</androidx.appcompat.widget.LinearLayoutCompat>
75+
</com.google.android.material.card.MaterialCardView>
76+
77+
<com.google.android.gms.ads.nativead.AdChoicesView
78+
android:id="@+id/ad_choices"
79+
android:layout_width="wrap_content"
80+
android:layout_height="wrap_content"
81+
android:layout_gravity="end|top"
82+
android:layout_margin="16dp" />
6283
</com.google.android.gms.ads.nativead.NativeAdView>
6384

0 commit comments

Comments
 (0)