From c7d3b6db6c262a5e092d65f508c8c0520bc2b453 Mon Sep 17 00:00:00 2001 From: volgoak Date: Sun, 25 Aug 2019 03:21:11 +0400 Subject: [PATCH] native ads added with google templates --- .idea/codeStyles/Project.xml | 116 +++++++ .idea/gradle.xml | 2 + .idea/modules.xml | 1 + app/build.gradle | 7 +- .../java/com/example/sergey/shlypa2/App.kt | 4 +- .../example/sergey/shlypa2/ads/AdsManager.kt | 14 + .../features_testing/MotionTestFragment.kt | 45 +-- .../shlypa2/screens/main/FirstActivity.kt | 6 +- app/src/main/res/layout/fragment_testing.xml | 14 + build.gradle | 2 + nativetemplates/build.gradle | 39 +++ nativetemplates/proguard-rules.pgcfg | 22 ++ nativetemplates/src/main/AndroidManifest.xml | 9 + .../nativetemplates/NativeTemplateStyle.java | 249 +++++++++++++++ .../ads/nativetemplates/TemplateView.java | 300 ++++++++++++++++++ .../main/res/drawable/gnt_outline_shape.xml | 6 + .../drawable/gnt_rounded_corners_shape.xml | 17 + .../res/layout/gnt_medium_template_view.xml | 218 +++++++++++++ .../res/layout/gnt_small_template_view.xml | 185 +++++++++++ nativetemplates/src/main/res/values/attrs.xml | 7 + .../src/main/res/values/colors.xml | 13 + .../src/main/res/values/dimens.xml | 20 ++ settings.gradle | 2 +- 23 files changed, 1253 insertions(+), 45 deletions(-) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 app/src/main/res/layout/fragment_testing.xml create mode 100644 nativetemplates/build.gradle create mode 100644 nativetemplates/proguard-rules.pgcfg create mode 100644 nativetemplates/src/main/AndroidManifest.xml create mode 100644 nativetemplates/src/main/java/com/google/android/ads/nativetemplates/NativeTemplateStyle.java create mode 100644 nativetemplates/src/main/java/com/google/android/ads/nativetemplates/TemplateView.java create mode 100644 nativetemplates/src/main/res/drawable/gnt_outline_shape.xml create mode 100644 nativetemplates/src/main/res/drawable/gnt_rounded_corners_shape.xml create mode 100644 nativetemplates/src/main/res/layout/gnt_medium_template_view.xml create mode 100644 nativetemplates/src/main/res/layout/gnt_small_template_view.xml create mode 100644 nativetemplates/src/main/res/values/attrs.xml create mode 100644 nativetemplates/src/main/res/values/colors.xml create mode 100644 nativetemplates/src/main/res/values/dimens.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..681f41ae --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 7ac24c77..9d3e8ee9 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -9,9 +9,11 @@ diff --git a/.idea/modules.xml b/.idea/modules.xml index 3f762b57..ab65af2a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -4,6 +4,7 @@ + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2299711d..731170a7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { compileSdkVersion 28 defaultConfig { applicationId "com.attiladroid.shlypa" - minSdkVersion 18 + minSdkVersion 21 targetSdkVersion 28 versionCode 23 versionName "1.1.42" @@ -44,6 +44,7 @@ ext { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation(project(':nativetemplates')) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.1.0-rc01' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -53,11 +54,11 @@ dependencies { implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.preference:preference:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' + implementation "androidx.constraintlayout:constraintlayout:$constraint_layout_version" //firebase implementation "com.google.firebase:firebase-core:17.1.0" - implementation 'com.google.android.gms:play-services-ads:18.1.1' + implementation "com.google.android.gms:play-services-ads:$google_ads_version" //implementation 'com.google.android.gms:play-services-location:16.0.0' implementation 'com.google.android.gms:play-services-gcm:17.0.0' implementation "com.google.firebase:firebase-messaging:20.0.0" diff --git a/app/src/main/java/com/example/sergey/shlypa2/App.kt b/app/src/main/java/com/example/sergey/shlypa2/App.kt index fbaa0b62..3db471b7 100644 --- a/app/src/main/java/com/example/sergey/shlypa2/App.kt +++ b/app/src/main/java/com/example/sergey/shlypa2/App.kt @@ -1,6 +1,6 @@ package com.example.sergey.shlypa2 -import androidx.multidex.MultiDexApplication +import android.app.Application import cat.ereza.customactivityoncrash.config.CaocConfig import com.crashlytics.android.Crashlytics import com.example.sergey.shlypa2.di.appModule @@ -18,7 +18,7 @@ import timber.log.Timber /** * Created by alex on 4/4/18. */ -class App : MultiDexApplication() { +class App : Application() { override fun onCreate() { diff --git a/app/src/main/java/com/example/sergey/shlypa2/ads/AdsManager.kt b/app/src/main/java/com/example/sergey/shlypa2/ads/AdsManager.kt index 2deac00b..7a6252a8 100644 --- a/app/src/main/java/com/example/sergey/shlypa2/ads/AdsManager.kt +++ b/app/src/main/java/com/example/sergey/shlypa2/ads/AdsManager.kt @@ -4,8 +4,10 @@ import android.content.Context import android.os.Bundle import com.example.sergey.shlypa2.extensions.debug import com.google.ads.mediation.admob.AdMobAdapter +import com.google.android.gms.ads.AdLoader import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.MobileAds +import com.google.android.gms.ads.formats.UnifiedNativeAd import org.json.JSONObject import timber.log.Timber @@ -78,6 +80,18 @@ class AdsManager( } } + fun getNativeAd(context: Context, onLoaded: (UnifiedNativeAd) -> Unit): AdLoader? { + val request = buildRequest() ?: return null + val loader = AdLoader.Builder(context, NATIVE_TEST_ID) + .forUnifiedNativeAd { nativeAd -> + onLoaded.invoke(nativeAd) + } + .build() + + loader.loadAd(request) + return loader + } + /** * Creates ad request if showing ads is allowed by the consentManager * otherwise returns null diff --git a/app/src/main/java/com/example/sergey/shlypa2/screens/features_testing/MotionTestFragment.kt b/app/src/main/java/com/example/sergey/shlypa2/screens/features_testing/MotionTestFragment.kt index 94294415..d5559b88 100644 --- a/app/src/main/java/com/example/sergey/shlypa2/screens/features_testing/MotionTestFragment.kt +++ b/app/src/main/java/com/example/sergey/shlypa2/screens/features_testing/MotionTestFragment.kt @@ -2,56 +2,29 @@ package com.example.sergey.shlypa2.screens.features_testing import android.os.Bundle -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.constraintlayout.motion.widget.MotionLayout -import androidx.constraintlayout.motion.widget.MotionScene -import com.bumptech.glide.Glide +import androidx.fragment.app.Fragment import com.example.sergey.shlypa2.R -import com.example.sergey.shlypa2.extensions.onTransitionCompletedOnce -import com.example.sergey.shlypa2.utils.Functions -import com.flurry.sdk.t -import kotlinx.android.synthetic.main.activity_game_result.* -import kotlinx.android.synthetic.main.fragment_game.* -import kotlinx.android.synthetic.main.fragment_game.view.* -import kotlinx.android.synthetic.main.fragment_round_start.* -import kotlinx.android.synthetic.main.fragment_rules.* - -import org.koin.androidx.viewmodel.ext.android.viewModel +import com.example.sergey.shlypa2.ads.AdsManager +import kotlinx.android.synthetic.main.fragment_testing.* +import org.koin.android.ext.android.inject class MotionTestFragment : Fragment() { + private val adsManager by inject() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_round_start, container, false) + return inflater.inflate(R.layout.fragment_testing, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - //tv_winner.text = "Good guys" - tvRoundName.text = "First round" - tvRoundRules.text = - """Lorem ipsum dolor sit amet, consectetur adipiscing elit. - |Suspendisse nisl massa, scelerisque at ex congue, congue fringilla magna. - |Cras viverra enim non neque commodo pretium. Suspendisse dictum lectus libero, - |ut ultrices mi ornare non. Aliquam erat volutpat. Maecenas venenatis at sem ac vestibulum. - """.trimMargin() - Glide.with(this) - .load(Functions.imageNameToUrl("round_avatars/silence.png")) - .into(civRulesAvatar) - - /*rootGame.setTransition(R.id.start, R.id.end) - rootGame.transitionToEnd() - rootGame.onTransitionCompletedOnce { - tvGuideLabel.setText(R.string.skip) - rootGame.setTransition(R.id.start, R.id.endSkip) - rootGame.transitionToEnd() - }*/ + adsManager.getNativeAd(requireContext()) { + my_template.setNativeAd(it) + } } } diff --git a/app/src/main/java/com/example/sergey/shlypa2/screens/main/FirstActivity.kt b/app/src/main/java/com/example/sergey/shlypa2/screens/main/FirstActivity.kt index 1f222cbe..1260affb 100644 --- a/app/src/main/java/com/example/sergey/shlypa2/screens/main/FirstActivity.kt +++ b/app/src/main/java/com/example/sergey/shlypa2/screens/main/FirstActivity.kt @@ -16,8 +16,8 @@ import com.example.sergey.shlypa2.extensions.extraNotNull import com.example.sergey.shlypa2.extensions.observeSafe import com.example.sergey.shlypa2.extensions.selectTheme import com.example.sergey.shlypa2.extensions.setThemeApi21 +import com.example.sergey.shlypa2.screens.features_testing.MotionTestFragment import com.example.sergey.shlypa2.screens.main.pages.LoadStateFragment -import com.example.sergey.shlypa2.screens.main.pages.RulesFragment import com.example.sergey.shlypa2.screens.main.pages.WelcomeFragment import com.example.sergey.shlypa2.screens.players.PlayersActivity import com.example.sergey.shlypa2.screens.settings.SettingsActivity @@ -137,8 +137,8 @@ class FirstActivity : AppCompatActivity() { } private fun startRulesFragment() { - val fragment = RulesFragment() -// val fragment = MotionTestFragment() +// val fragment = RulesFragment() + val fragment = MotionTestFragment() supportFragmentManager.beginTransaction() .replace(R.id.container, fragment) .addToBackStack(null) diff --git a/app/src/main/res/layout/fragment_testing.xml b/app/src/main/res/layout/fragment_testing.xml new file mode 100644 index 00000000..24ce9112 --- /dev/null +++ b/app/src/main/res/layout/fragment_testing.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index ee9e6531..e44dd105 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,8 @@ buildscript { ext.kotlin_version = '1.3.21' + ext.google_ads_version = '18.1.1' + ext.constraint_layout_version = '2.0.0-beta2' repositories { google() jcenter() diff --git a/nativetemplates/build.gradle b/nativetemplates/build.gradle new file mode 100644 index 00000000..eb8b2dc8 --- /dev/null +++ b/nativetemplates/build.gradle @@ -0,0 +1,39 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 26 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pgcfg' + consumerProguardFiles 'proguard-rules.pgcfg' + } + } + + lintOptions { + resourcePrefix 'gnt_' + } +} + + + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:26.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation "androidx.constraintlayout:constraintlayout:$constraint_layout_version" + implementation "com.google.android.gms:play-services-ads:$google_ads_version" +} diff --git a/nativetemplates/proguard-rules.pgcfg b/nativetemplates/proguard-rules.pgcfg new file mode 100644 index 00000000..d51c0ea7 --- /dev/null +++ b/nativetemplates/proguard-rules.pgcfg @@ -0,0 +1,22 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile +-keep,includedescriptorclasses public class com.google.android.ads.nativetemplates { *; } diff --git a/nativetemplates/src/main/AndroidManifest.xml b/nativetemplates/src/main/AndroidManifest.xml new file mode 100644 index 00000000..145fd7e6 --- /dev/null +++ b/nativetemplates/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/NativeTemplateStyle.java b/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/NativeTemplateStyle.java new file mode 100644 index 00000000..c94f824a --- /dev/null +++ b/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/NativeTemplateStyle.java @@ -0,0 +1,249 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.android.ads.nativetemplates; + +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; + +/** A class containing the optional styling options for the Native Template. * */ +public class NativeTemplateStyle { + + // Call to action typeface. + private Typeface callToActionTextTypeface; + + // Size of call to action text. + private float callToActionTextSize; + + // Call to action typeface color in the form 0xAARRGGBB. + private int callToActionTypefaceColor; + + // Call to action background color. + private ColorDrawable callToActionBackgroundColor; + + // All templates have a primary text area which is populated by the native ad's headline. + + // Primary text typeface. + private Typeface primaryTextTypeface; + + // Size of primary text. + private float primaryTextSize; + + // Primary text typeface color in the form 0xAARRGGBB. + private int primaryTextTypefaceColor; + + // Primary text background color. + private ColorDrawable primaryTextBackgroundColor; + + // The typeface, typeface color, and background color for the second row of text in the template. + // All templates have a secondary text area which is populated either by the body of the ad or + // by the rating of the app. + + // Secondary text typeface. + private Typeface secondaryTextTypeface; + + // Size of secondary text. + private float secondaryTextSize; + + // Secondary text typeface color in the form 0xAARRGGBB. + private int secondaryTextTypefaceColor; + + // Secondary text background color. + private ColorDrawable secondaryTextBackgroundColor; + + // The typeface, typeface color, and background color for the third row of text in the template. + // The third row is used to display store name or the default tertiary text. + + // Tertiary text typeface. + private Typeface tertiaryTextTypeface; + + // Size of tertiary text. + private float tertiaryTextSize; + + // Tertiary text typeface color in the form 0xAARRGGBB. + private int tertiaryTextTypefaceColor; + + // Tertiary text background color. + private ColorDrawable tertiaryTextBackgroundColor; + + // The background color for the bulk of the ad. + private ColorDrawable mainBackgroundColor; + + public Typeface getCallToActionTextTypeface() { + return callToActionTextTypeface; + } + + public float getCallToActionTextSize() { + return callToActionTextSize; + } + + public int getCallToActionTypefaceColor() { + return callToActionTypefaceColor; + } + + public ColorDrawable getCallToActionBackgroundColor() { + return callToActionBackgroundColor; + } + + public Typeface getPrimaryTextTypeface() { + return primaryTextTypeface; + } + + public float getPrimaryTextSize() { + return primaryTextSize; + } + + public int getPrimaryTextTypefaceColor() { + return primaryTextTypefaceColor; + } + + public ColorDrawable getPrimaryTextBackgroundColor() { + return primaryTextBackgroundColor; + } + + public Typeface getSecondaryTextTypeface() { + return secondaryTextTypeface; + } + + public float getSecondaryTextSize() { + return secondaryTextSize; + } + + public int getSecondaryTextTypefaceColor() { + return secondaryTextTypefaceColor; + } + + public ColorDrawable getSecondaryTextBackgroundColor() { + return secondaryTextBackgroundColor; + } + + public Typeface getTertiaryTextTypeface() { + return tertiaryTextTypeface; + } + + public float getTertiaryTextSize() { + return tertiaryTextSize; + } + + public int getTertiaryTextTypefaceColor() { + return tertiaryTextTypefaceColor; + } + + public ColorDrawable getTertiaryTextBackgroundColor() { + return tertiaryTextBackgroundColor; + } + + public ColorDrawable getMainBackgroundColor() { + return mainBackgroundColor; + } + + /** A class that provides helper methods to build a style object. * */ + public static class Builder { + + private NativeTemplateStyle styles; + + public Builder() { + this.styles = new NativeTemplateStyle(); + } + + public Builder withCallToActionTextTypeface(Typeface callToActionTextTypeface) { + this.styles.callToActionTextTypeface = callToActionTextTypeface; + return this; + } + + public Builder withCallToActionTextSize(float callToActionTextSize) { + this.styles.callToActionTextSize = callToActionTextSize; + return this; + } + + public Builder withCallToActionTypefaceColor(int callToActionTypefaceColor) { + this.styles.callToActionTypefaceColor = callToActionTypefaceColor; + return this; + } + + public Builder withCallToActionBackgroundColor(ColorDrawable callToActionBackgroundColor) { + this.styles.callToActionBackgroundColor = callToActionBackgroundColor; + return this; + } + + public Builder withPrimaryTextTypeface(Typeface primaryTextTypeface) { + this.styles.primaryTextTypeface = primaryTextTypeface; + return this; + } + + public Builder withPrimaryTextSize(float primaryTextSize) { + this.styles.primaryTextSize = primaryTextSize; + return this; + } + + public Builder withPrimaryTextTypefaceColor(int primaryTextTypefaceColor) { + this.styles.primaryTextTypefaceColor = primaryTextTypefaceColor; + return this; + } + + public Builder withPrimaryTextBackgroundColor(ColorDrawable primaryTextBackgroundColor) { + this.styles.primaryTextBackgroundColor = primaryTextBackgroundColor; + return this; + } + + public Builder withSecondaryTextTypeface(Typeface secondaryTextTypeface) { + this.styles.secondaryTextTypeface = secondaryTextTypeface; + return this; + } + + public Builder withSecondaryTextSize(float secondaryTextSize) { + this.styles.secondaryTextSize = secondaryTextSize; + return this; + } + + public Builder withSecondaryTextTypefaceColor(int secondaryTextTypefaceColor) { + this.styles.secondaryTextTypefaceColor = secondaryTextTypefaceColor; + return this; + } + + public Builder withSecondaryTextBackgroundColor(ColorDrawable secondaryTextBackgroundColor) { + this.styles.secondaryTextBackgroundColor = secondaryTextBackgroundColor; + return this; + } + + public Builder withTertiaryTextTypeface(Typeface tertiaryTextTypeface) { + this.styles.tertiaryTextTypeface = tertiaryTextTypeface; + return this; + } + + public Builder withTertiaryTextSize(float tertiaryTextSize) { + this.styles.tertiaryTextSize = tertiaryTextSize; + return this; + } + + public Builder withTertiaryTextTypefaceColor(int tertiaryTextTypefaceColor) { + this.styles.tertiaryTextTypefaceColor = tertiaryTextTypefaceColor; + return this; + } + + public Builder withTertiaryTextBackgroundColor(ColorDrawable tertiaryTextBackgroundColor) { + this.styles.tertiaryTextBackgroundColor = tertiaryTextBackgroundColor; + return this; + } + + public Builder withMainBackgroundColor(ColorDrawable mainBackgroundColor) { + this.styles.mainBackgroundColor = mainBackgroundColor; + return this; + } + + public NativeTemplateStyle build() { + return styles; + } + } +} diff --git a/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/TemplateView.java b/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/TemplateView.java new file mode 100644 index 00000000..fa413a6c --- /dev/null +++ b/nativetemplates/src/main/java/com/google/android/ads/nativetemplates/TemplateView.java @@ -0,0 +1,300 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.android.ads.nativetemplates; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.google.android.gms.ads.formats.MediaView; +import com.google.android.gms.ads.formats.NativeAd.Image; +import com.google.android.gms.ads.formats.UnifiedNativeAd; +import com.google.android.gms.ads.formats.UnifiedNativeAdView; + +/** Base class for a template view. * */ +public class TemplateView extends FrameLayout { + + private int templateType; + private NativeTemplateStyle styles; + private UnifiedNativeAd nativeAd; + private UnifiedNativeAdView nativeAdView; + + private TextView primaryView; + private TextView secondaryView; + private RatingBar ratingBar; + private TextView tertiaryView; + private ImageView iconView; + private MediaView mediaView; + private Button callToActionView; + private ConstraintLayout background; + + private static final String MEDIUM_TEMPLATE = "medium_template"; + private static final String SMALL_TEMPLATE = "small_template"; + + public TemplateView(Context context) { + super(context); + } + + public TemplateView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initView(context, attrs); + } + + public TemplateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(context, attrs); + } + + public TemplateView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + initView(context, attrs); + } + + public void setStyles(NativeTemplateStyle styles) { + this.styles = styles; + this.applyStyles(); + } + + public UnifiedNativeAdView getNativeAdView() { + return nativeAdView; + } + + private void applyStyles() { + + Drawable mainBackground = styles.getMainBackgroundColor(); + if (mainBackground != null) { + background.setBackground(mainBackground); + if (primaryView != null) { + primaryView.setBackground(mainBackground); + } + if (secondaryView != null) { + secondaryView.setBackground(mainBackground); + } + if (tertiaryView != null) { + tertiaryView.setBackground(mainBackground); + } + } + + Typeface primary = styles.getPrimaryTextTypeface(); + if (primary != null && primaryView != null) { + primaryView.setTypeface(primary); + } + + Typeface secondary = styles.getSecondaryTextTypeface(); + if (secondary != null && secondaryView != null) { + secondaryView.setTypeface(secondary); + } + + Typeface tertiary = styles.getTertiaryTextTypeface(); + if (tertiary != null && tertiaryView != null) { + tertiaryView.setTypeface(tertiary); + } + + Typeface ctaTypeface = styles.getCallToActionTextTypeface(); + if (ctaTypeface != null && callToActionView != null) { + callToActionView.setTypeface(ctaTypeface); + } + + int primaryTypefaceColor = styles.getPrimaryTextTypefaceColor(); + if (primaryTypefaceColor > 0 && primaryView != null) { + primaryView.setTextColor(primaryTypefaceColor); + } + + int secondaryTypefaceColor = styles.getSecondaryTextTypefaceColor(); + if (secondaryTypefaceColor > 0 && secondaryView != null) { + secondaryView.setTextColor(secondaryTypefaceColor); + } + + int tertiaryTypefaceColor = styles.getTertiaryTextTypefaceColor(); + if (tertiaryTypefaceColor > 0 && tertiaryView != null) { + tertiaryView.setTextColor(tertiaryTypefaceColor); + } + + int ctaTypefaceColor = styles.getCallToActionTypefaceColor(); + if (ctaTypefaceColor > 0 && callToActionView != null) { + callToActionView.setTextColor(ctaTypefaceColor); + } + + float ctaTextSize = styles.getCallToActionTextSize(); + if (ctaTextSize > 0 && callToActionView != null) { + callToActionView.setTextSize(ctaTextSize); + } + + float primaryTextSize = styles.getPrimaryTextSize(); + if (primaryTextSize > 0 && primaryView != null) { + primaryView.setTextSize(primaryTextSize); + } + + float secondaryTextSize = styles.getSecondaryTextSize(); + if (secondaryTextSize > 0 && secondaryView != null) { + secondaryView.setTextSize(secondaryTextSize); + } + + float tertiaryTextSize = styles.getTertiaryTextSize(); + if (tertiaryTextSize > 0 && tertiaryView != null) { + tertiaryView.setTextSize(tertiaryTextSize); + } + + Drawable ctaBackground = styles.getCallToActionBackgroundColor(); + if (ctaBackground != null && callToActionView != null) { + callToActionView.setBackground(ctaBackground); + } + + Drawable primaryBackground = styles.getPrimaryTextBackgroundColor(); + if (primaryBackground != null && primaryView != null) { + primaryView.setBackground(primaryBackground); + } + + Drawable secondaryBackground = styles.getSecondaryTextBackgroundColor(); + if (secondaryBackground != null && secondaryView != null) { + secondaryView.setBackground(secondaryBackground); + } + + Drawable tertiaryBackground = styles.getTertiaryTextBackgroundColor(); + if (tertiaryBackground != null && tertiaryView != null) { + tertiaryView.setBackground(tertiaryBackground); + } + + invalidate(); + requestLayout(); + } + + private boolean adHasOnlyStore(UnifiedNativeAd nativeAd) { + String store = nativeAd.getStore(); + String advertiser = nativeAd.getAdvertiser(); + return !TextUtils.isEmpty(store) && TextUtils.isEmpty(advertiser); + } + + public void setNativeAd(UnifiedNativeAd nativeAd) { + this.nativeAd = nativeAd; + + String store = nativeAd.getStore(); + String advertiser = nativeAd.getAdvertiser(); + String headline = nativeAd.getHeadline(); + String body = nativeAd.getBody(); + String cta = nativeAd.getCallToAction(); + Double starRating = nativeAd.getStarRating(); + Image icon = nativeAd.getIcon(); + + String secondaryText; + + nativeAdView.setCallToActionView(callToActionView); + nativeAdView.setHeadlineView(primaryView); + nativeAdView.setMediaView(mediaView); + secondaryView.setVisibility(VISIBLE); + if (adHasOnlyStore(nativeAd)) { + nativeAdView.setStoreView(secondaryView); + secondaryText = store; + } else if (!TextUtils.isEmpty(advertiser)) { + nativeAdView.setAdvertiserView(secondaryView); + secondaryText = advertiser; + } else { + secondaryText = ""; + } + + primaryView.setText(headline); + callToActionView.setText(cta); + + // Set the secondary view to be the star rating if available. + if (starRating != null && starRating > 0) { + secondaryView.setVisibility(GONE); + ratingBar.setVisibility(VISIBLE); + ratingBar.setMax(5); + nativeAdView.setStarRatingView(ratingBar); + } else { + secondaryView.setText(secondaryText); + secondaryView.setVisibility(VISIBLE); + ratingBar.setVisibility(GONE); + } + + if (icon != null) { + iconView.setVisibility(VISIBLE); + iconView.setImageDrawable(icon.getDrawable()); + } else { + iconView.setVisibility(GONE); + } + + if (tertiaryView != null) { + tertiaryView.setText(body); + nativeAdView.setBodyView(tertiaryView); + } + + nativeAdView.setNativeAd(nativeAd); + } + + /** + * To prevent memory leaks, make sure to destroy your ad when you don't need it anymore. This + * method does not destroy the template view. + * https://developers.google.com/admob/android/native-unified#destroy_ad + */ + public void destroyNativeAd() { + nativeAd.destroy(); + } + + public String getTemplateTypeName() { + if (templateType == R.layout.gnt_medium_template_view) { + return MEDIUM_TEMPLATE; + } else if (templateType == R.layout.gnt_small_template_view) { + return SMALL_TEMPLATE; + } + return ""; + } + + private void initView(Context context, AttributeSet attributeSet) { + + TypedArray attributes = + context.getTheme().obtainStyledAttributes(attributeSet, R.styleable.TemplateView, 0, 0); + + try { + templateType = + attributes.getResourceId( + R.styleable.TemplateView_gnt_template_type, R.layout.gnt_medium_template_view); + } finally { + attributes.recycle(); + } + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(templateType, this); + } + + @Override + public void onFinishInflate() { + super.onFinishInflate(); + nativeAdView = (UnifiedNativeAdView) findViewById(R.id.native_ad_view); + primaryView = (TextView) findViewById(R.id.primary); + secondaryView = (TextView) findViewById(R.id.secondary); + tertiaryView = (TextView) findViewById(R.id.body); + + ratingBar = (RatingBar) findViewById(R.id.rating_bar); + ratingBar.setEnabled(false); + + callToActionView = (Button) findViewById(R.id.cta); + iconView = (ImageView) findViewById(R.id.icon); + mediaView = (MediaView) findViewById(R.id.media_view); + background = (ConstraintLayout) findViewById(R.id.background); + } +} diff --git a/nativetemplates/src/main/res/drawable/gnt_outline_shape.xml b/nativetemplates/src/main/res/drawable/gnt_outline_shape.xml new file mode 100644 index 00000000..3c657a12 --- /dev/null +++ b/nativetemplates/src/main/res/drawable/gnt_outline_shape.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/nativetemplates/src/main/res/drawable/gnt_rounded_corners_shape.xml b/nativetemplates/src/main/res/drawable/gnt_rounded_corners_shape.xml new file mode 100644 index 00000000..d03599b8 --- /dev/null +++ b/nativetemplates/src/main/res/drawable/gnt_rounded_corners_shape.xml @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/nativetemplates/src/main/res/layout/gnt_medium_template_view.xml b/nativetemplates/src/main/res/layout/gnt_medium_template_view.xml new file mode 100644 index 00000000..cf7005e3 --- /dev/null +++ b/nativetemplates/src/main/res/layout/gnt_medium_template_view.xml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +