11package com .d4rk .androidtutorials .java .ads .managers ;
22
33import android .content .Context ;
4- import android .content .res .Resources ;
54import android .text .TextUtils ;
65import android .util .Log ;
76import android .view .LayoutInflater ;
1312
1413import androidx .annotation .LayoutRes ;
1514import androidx .annotation .NonNull ;
16- import androidx .viewbinding .ViewBinding ;
1715
1816import com .d4rk .androidtutorials .java .R ;
1917import com .google .android .gms .ads .AdListener ;
2523import com .google .android .gms .ads .nativead .NativeAd ;
2624import com .google .android .gms .ads .nativead .NativeAdView ;
2725
28- import java .lang .reflect .Field ;
29- import java .lang .reflect .InvocationTargetException ;
30- import java .lang .reflect .Method ;
31-
3226/**
3327 * Helper class to load AdMob native ads into a container.
3428 */
3529public class NativeAdLoader {
3630
3731 private static final String TAG = "NativeAdLoader" ;
3832
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-
6233 public static void load (@ NonNull Context context ,
6334 @ NonNull ViewGroup container ,
6435 @ LayoutRes int layoutRes ,
@@ -69,6 +40,7 @@ public static void load(@NonNull Context context,
6940 ? context .getString (R .string .native_ad_fallback_unit_id )
7041 : adUnitId ;
7142
43+ assert resolvedAdUnitId != null ;
7244 AdLoader .Builder builder = new AdLoader .Builder (context , resolvedAdUnitId )
7345 .forNativeAd (nativeAd -> {
7446 LayoutInflater inflater = LayoutInflater .from (context );
@@ -79,7 +51,7 @@ public static void load(@NonNull Context context,
7951 adView .setPadding (container .getPaddingLeft (), container .getPaddingTop (),
8052 container .getPaddingRight (), container .getPaddingBottom ());
8153 container .setPadding (0 , 0 , 0 , 0 );
82- populateNativeAdView (nativeAd , adView , layoutRes );
54+ populateNativeAdView (nativeAd , adView );
8355 container .removeAllViews ();
8456 container .addView (adView );
8557 container .requestLayout ();
@@ -98,22 +70,14 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
9870 adLoader .loadAd (adRequest );
9971 }
10072
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 );
11781
11882 if (mediaView != null ) {
11983 adView .setMediaView (mediaView );
@@ -152,11 +116,10 @@ private static void populateNativeAdView(@NonNull NativeAd nativeAd,
152116 }
153117
154118 if (attributionView != null ) {
155- String adLabel = adView .getContext ().getString (R .string .ad );
156119 if (nativeAd .getAdvertiser () == null ) {
157- attributionView .setText (adLabel );
120+ attributionView .setText (R . string . ad );
158121 } else {
159- attributionView .setText (adLabel + " " + nativeAd .getAdvertiser ());
122+ attributionView .setText (adView . getContext (). getString ( R . string . ad_attribution_with_advertiser , nativeAd .getAdvertiser () ));
160123 }
161124 }
162125
@@ -180,53 +143,4 @@ private static void populateNativeAdView(@NonNull NativeAd nativeAd,
180143
181144 adView .setNativeAd (nativeAd );
182145 }
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- }
232146}
0 commit comments