1
1
package com .d4rk .androidtutorials .java .ads .managers ;
2
2
3
3
import android .content .Context ;
4
- import android .content .res .Resources ;
5
4
import android .text .TextUtils ;
6
5
import android .util .Log ;
7
6
import android .view .LayoutInflater ;
13
12
14
13
import androidx .annotation .LayoutRes ;
15
14
import androidx .annotation .NonNull ;
16
- import androidx .viewbinding .ViewBinding ;
17
15
18
16
import com .d4rk .androidtutorials .java .R ;
19
17
import com .google .android .gms .ads .AdListener ;
25
23
import com .google .android .gms .ads .nativead .NativeAd ;
26
24
import com .google .android .gms .ads .nativead .NativeAdView ;
27
25
28
- import java .lang .reflect .Field ;
29
- import java .lang .reflect .InvocationTargetException ;
30
- import java .lang .reflect .Method ;
31
-
32
26
/**
33
27
* Helper class to load AdMob native ads into a container.
34
28
*/
35
29
public class NativeAdLoader {
36
30
37
31
private static final String TAG = "NativeAdLoader" ;
38
32
39
- public static void load (@ NonNull Context context , @ NonNull ViewGroup container ) {
40
- load (context , container , R .layout .ad_home_banner_large , null , new AdRequest .Builder ().build (), null );
41
- }
42
-
43
- public static void load (@ NonNull Context context , @ NonNull ViewGroup container , @ LayoutRes int layoutRes ) {
44
- load (context , container , layoutRes , null , new AdRequest .Builder ().build (), null );
45
- }
46
-
47
- public static void load (@ NonNull Context context ,
48
- @ NonNull ViewGroup container ,
49
- @ LayoutRes int layoutRes ,
50
- @ androidx .annotation .Nullable AdListener listener ) {
51
- load (context , container , layoutRes , null , new AdRequest .Builder ().build (), listener );
52
- }
53
-
54
- public static void load (@ NonNull Context context ,
55
- @ NonNull ViewGroup container ,
56
- @ LayoutRes int layoutRes ,
57
- @ NonNull AdRequest adRequest ,
58
- @ androidx .annotation .Nullable AdListener listener ) {
59
- load (context , container , layoutRes , null , adRequest , listener );
60
- }
61
-
62
33
public static void load (@ NonNull Context context ,
63
34
@ NonNull ViewGroup container ,
64
35
@ LayoutRes int layoutRes ,
@@ -69,6 +40,7 @@ public static void load(@NonNull Context context,
69
40
? context .getString (R .string .native_ad_fallback_unit_id )
70
41
: adUnitId ;
71
42
43
+ assert resolvedAdUnitId != null ;
72
44
AdLoader .Builder builder = new AdLoader .Builder (context , resolvedAdUnitId )
73
45
.forNativeAd (nativeAd -> {
74
46
LayoutInflater inflater = LayoutInflater .from (context );
@@ -79,7 +51,7 @@ public static void load(@NonNull Context context,
79
51
adView .setPadding (container .getPaddingLeft (), container .getPaddingTop (),
80
52
container .getPaddingRight (), container .getPaddingBottom ());
81
53
container .setPadding (0 , 0 , 0 , 0 );
82
- populateNativeAdView (nativeAd , adView , layoutRes );
54
+ populateNativeAdView (nativeAd , adView );
83
55
container .removeAllViews ();
84
56
container .addView (adView );
85
57
container .requestLayout ();
@@ -98,22 +70,14 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
98
70
adLoader .loadAd (adRequest );
99
71
}
100
72
101
- private static void populateNativeAdView (@ NonNull NativeAd nativeAd ,
102
- @ NonNull NativeAdView adView ,
103
- @ LayoutRes int layoutRes ) {
104
- ViewBinding binding = tryBind (adView , layoutRes );
105
- if (binding == null ) {
106
- Log .w (TAG , "Could not bind native ad view for layout " + layoutRes );
107
- return ;
108
- }
109
-
110
- MediaView mediaView = getBindingField (binding , "adMedia" , MediaView .class );
111
- TextView headlineView = getBindingField (binding , "adHeadline" , TextView .class );
112
- TextView bodyView = getBindingField (binding , "adBody" , TextView .class );
113
- Button callToActionView = getBindingField (binding , "adCallToAction" , Button .class );
114
- ImageView iconView = getBindingField (binding , "adAppIcon" , ImageView .class );
115
- TextView attributionView = getBindingField (binding , "adAttribution" , TextView .class );
116
- AdChoicesView adChoicesView = getBindingField (binding , "adChoices" , AdChoicesView .class );
73
+ private static void populateNativeAdView (@ NonNull NativeAd nativeAd , @ NonNull NativeAdView adView ) {
74
+ MediaView mediaView = adView .findViewById (R .id .ad_media );
75
+ TextView headlineView = adView .findViewById (R .id .ad_headline );
76
+ TextView bodyView = adView .findViewById (R .id .ad_body );
77
+ Button callToActionView = adView .findViewById (R .id .ad_call_to_action );
78
+ ImageView iconView = adView .findViewById (R .id .ad_app_icon );
79
+ TextView attributionView = adView .findViewById (R .id .ad_attribution );
80
+ AdChoicesView adChoicesView = adView .findViewById (R .id .ad_choices );
117
81
118
82
if (mediaView != null ) {
119
83
adView .setMediaView (mediaView );
@@ -152,11 +116,10 @@ private static void populateNativeAdView(@NonNull NativeAd nativeAd,
152
116
}
153
117
154
118
if (attributionView != null ) {
155
- String adLabel = adView .getContext ().getString (R .string .ad );
156
119
if (nativeAd .getAdvertiser () == null ) {
157
- attributionView .setText (adLabel );
120
+ attributionView .setText (R . string . ad );
158
121
} else {
159
- attributionView .setText (adLabel + " " + nativeAd .getAdvertiser ());
122
+ attributionView .setText (adView . getContext (). getString ( R . string . ad_attribution_with_advertiser , nativeAd .getAdvertiser () ));
160
123
}
161
124
}
162
125
@@ -180,53 +143,4 @@ private static void populateNativeAdView(@NonNull NativeAd nativeAd,
180
143
181
144
adView .setNativeAd (nativeAd );
182
145
}
183
-
184
- @ androidx .annotation .Nullable
185
- private static ViewBinding tryBind (@ NonNull NativeAdView adView , @ LayoutRes int layoutRes ) {
186
- try {
187
- String resourceName = adView .getResources ().getResourceEntryName (layoutRes );
188
- String bindingName = toBindingClassName (resourceName );
189
- String fullClassName = adView .getContext ().getPackageName () + ".databinding." + bindingName ;
190
- Class <?> bindingClass = Class .forName (fullClassName );
191
- Method bindMethod = bindingClass .getMethod ("bind" , View .class );
192
- return (ViewBinding ) bindMethod .invoke (null , adView );
193
- } catch (Resources .NotFoundException | ClassNotFoundException | NoSuchMethodException |
194
- IllegalAccessException | InvocationTargetException e ) {
195
- Log .w (TAG , "Failed to create view binding for native ad layout" , e );
196
- return null ;
197
- }
198
- }
199
-
200
- @ androidx .annotation .Nullable
201
- private static <T > T getBindingField (@ NonNull ViewBinding binding ,
202
- @ NonNull String fieldName ,
203
- @ NonNull Class <T > type ) {
204
- try {
205
- Field field = binding .getClass ().getField (fieldName );
206
- Object value = field .get (binding );
207
- if (type .isInstance (value )) {
208
- return type .cast (value );
209
- }
210
- } catch (NoSuchFieldException | IllegalAccessException e ) {
211
- Log .w (TAG , "Unable to access binding field " + fieldName , e );
212
- }
213
- return null ;
214
- }
215
-
216
- @ NonNull
217
- private static String toBindingClassName (@ NonNull String resourceName ) {
218
- StringBuilder builder = new StringBuilder (resourceName .length ());
219
- boolean capitalize = true ;
220
- for (int i = 0 ; i < resourceName .length (); i ++) {
221
- char c = resourceName .charAt (i );
222
- if (c == '_' ) {
223
- capitalize = true ;
224
- } else {
225
- builder .append (capitalize ? Character .toUpperCase (c ) : c );
226
- capitalize = false ;
227
- }
228
- }
229
- builder .append ("Binding" );
230
- return builder .toString ();
231
- }
232
146
}
0 commit comments