Commit 971ae1f9 authored by Max Lv's avatar Max Lv

Replace banner AdView with NativeAdView

parent 11c09efa
...@@ -30,9 +30,7 @@ import android.os.Bundle ...@@ -30,9 +30,7 @@ import android.os.Bundle
import android.text.format.Formatter import android.text.format.Formatter
import android.util.LongSparseArray import android.util.LongSparseArray
import android.view.* import android.view.*
import android.widget.ImageView import android.widget.*
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.appcompat.widget.TooltipCompat import androidx.appcompat.widget.TooltipCompat
...@@ -53,10 +51,15 @@ import com.github.shadowsocks.utils.readableMessage ...@@ -53,10 +51,15 @@ import com.github.shadowsocks.utils.readableMessage
import com.github.shadowsocks.widget.ListHolderListener import com.github.shadowsocks.widget.ListHolderListener
import com.github.shadowsocks.widget.MainListListener import com.github.shadowsocks.widget.MainListListener
import com.github.shadowsocks.widget.UndoSnackbarManager import com.github.shadowsocks.widget.UndoSnackbarManager
import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.*
import com.google.android.gms.ads.AdSize import com.google.android.gms.ads.formats.MediaView
import com.google.android.gms.ads.AdView import com.google.android.gms.ads.formats.NativeAdOptions
import com.google.android.gms.ads.formats.UnifiedNativeAd
import com.google.android.gms.ads.formats.UnifiedNativeAdView
import net.glxn.qrgen.android.QRCode import net.glxn.qrgen.android.QRCode
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
companion object { companion object {
...@@ -102,7 +105,8 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -102,7 +105,8 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
private val text2 = itemView.findViewById<TextView>(android.R.id.text2) private val text2 = itemView.findViewById<TextView>(android.R.id.text2)
private val traffic = itemView.findViewById<TextView>(R.id.traffic) private val traffic = itemView.findViewById<TextView>(R.id.traffic)
private val edit = itemView.findViewById<View>(R.id.edit) private val edit = itemView.findViewById<View>(R.id.edit)
private var adView: AdView? = null private var currentNativeAd: UnifiedNativeAd? = null
private var isAttached = false
init { init {
edit.setOnClickListener { edit.setOnClickListener {
...@@ -121,32 +125,129 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener { ...@@ -121,32 +125,129 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
TooltipCompat.setTooltipText(share, share.contentDescription) TooltipCompat.setTooltipText(share, share.contentDescription)
} }
fun populateUnifiedNativeAdView(nativeAd: UnifiedNativeAd, adView: UnifiedNativeAdView) {
// You must call destroy on old ads when you are done with them,
// otherwise you will have a memory leak.
currentNativeAd?.destroy()
currentNativeAd = nativeAd
// Set other ad assets.
adView.headlineView = adView.findViewById(R.id.ad_headline)
adView.bodyView = adView.findViewById(R.id.ad_body)
adView.callToActionView = adView.findViewById(R.id.ad_call_to_action)
adView.iconView = adView.findViewById(R.id.ad_app_icon)
adView.starRatingView = adView.findViewById(R.id.ad_stars)
adView.advertiserView = adView.findViewById(R.id.ad_advertiser)
// The headline and media content are guaranteed to be in every UnifiedNativeAd.
(adView.headlineView as TextView).text = nativeAd.headline
// These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
// check before trying to display them.
if (nativeAd.body == null) {
adView.bodyView.visibility = View.INVISIBLE
} else {
adView.bodyView.visibility = View.VISIBLE
(adView.bodyView as TextView).text = nativeAd.body
}
if (nativeAd.callToAction == null) {
adView.callToActionView.visibility = View.INVISIBLE
} else {
adView.callToActionView.visibility = View.VISIBLE
(adView.callToActionView as Button).text = nativeAd.callToAction
}
if (nativeAd.icon == null) {
adView.iconView.visibility = View.GONE
} else {
(adView.iconView as ImageView).setImageDrawable(
nativeAd.icon.drawable)
adView.iconView.visibility = View.VISIBLE
}
if (nativeAd.starRating == null) {
adView.starRatingView.visibility = View.INVISIBLE
} else {
(adView.starRatingView as RatingBar).rating = nativeAd.starRating!!.toFloat()
adView.starRatingView.visibility = View.VISIBLE
}
if (nativeAd.advertiser == null) {
adView.advertiserView.visibility = View.INVISIBLE
} else {
(adView.advertiserView as TextView).text = nativeAd.advertiser
adView.advertiserView.visibility = View.VISIBLE
}
// This method tells the Google Mobile Ads SDK that you have finished populating your
// native ad view with this native ad.
adView.setNativeAd(nativeAd)
// Get the video controller for the ad. One will always be provided, even if the ad doesn't
// have a video asset.
val vc = nativeAd.videoController
// Updates the UI to say whether or not this ad has a video asset.
if (vc.hasVideoContent()) {
// Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
// VideoController will call methods on this object when events occur in the video
// lifecycle.
vc.videoLifecycleCallbacks = object : VideoController.VideoLifecycleCallbacks() {
override fun onVideoEnd() {
super.onVideoEnd()
}
}
}
}
fun attach() { fun attach() {
if (!isAdLoaded && item.host == "198.199.101.152") { isAttached = true
if (adView == null) {
adView = AdView(context).apply { if (item.host == "198.199.101.152") {
layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, val builder = AdLoader.Builder(context, "ca-app-pub-9097031975646651/9333091620")
AdSize.SMART_BANNER.getHeightInPixels(context)).apply { builder.forUnifiedNativeAd { unifiedNativeAd ->
gravity = Gravity.CENTER_HORIZONTAL if (!isAdLoaded && isAttached) {
} // OnUnifiedNativeAdLoadedListener implementation.
adUnitId = "ca-app-pub-9097031975646651/7760346322" val adView = layoutInflater
adSize = AdSize.SMART_BANNER .inflate(R.layout.ad_unified, null) as UnifiedNativeAdView
itemView.findViewById<LinearLayout>(R.id.content).addView(this) populateUnifiedNativeAdView(unifiedNativeAd, adView)
loadAd(AdRequest.Builder().apply { val adContainer = itemView.findViewById<LinearLayout>(R.id.ad_container)
addTestDevice("B08FC1764A7B250E91EA9D0D5EBEB208")
addTestDevice("7509D18EB8AF82F915874FEF53877A64") adContainer.removeAllViews()
}.build()) adContainer.addView(adView)
isAdLoaded = true
} }
} else adView?.visibility = View.VISIBLE }
isAdLoaded = true
} else adView?.visibility = View.GONE val videoOptions = VideoOptions.Builder()
.setStartMuted(true)
.build()
val adOptions = NativeAdOptions.Builder()
.setVideoOptions(videoOptions)
.build()
builder.withNativeAdOptions(adOptions)
val adLoader = builder.build()
adLoader.loadAd(AdRequest.Builder().apply {
addTestDevice("B08FC1764A7B250E91EA9D0D5EBEB208")
addTestDevice("7509D18EB8AF82F915874FEF53877A64")
}.build())
} else {
itemView.findViewById<LinearLayout>(R.id.ad_container).removeAllViews()
}
} }
fun detach() { fun detach() {
if (adView?.visibility == View.VISIBLE) { isAttached = false
if (currentNativeAd != null) {
isAdLoaded = false isAdLoaded = false
adView?.visibility = View.GONE
} }
currentNativeAd?.destroy()
currentNativeAd = null
itemView.findViewById<LinearLayout>(R.id.ad_container).removeAllViews()
} }
fun bind(item: Profile) { fun bind(item: Profile) {
......
<com.google.android.gms.ads.formats.UnifiedNativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FFFFFF"
android:minHeight="40dp"
android:orientation="vertical">
<TextView style="@style/Theme.Shadowsocks.AdAttribution"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:paddingBottom="5dp"
android:paddingRight="5dp"
android:paddingEnd="5dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:maxLines="1"
android:textSize="14sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:textSize="12sp"
android:textStyle="bold"/>
<RatingBar
android:id="@+id/ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:textSize="12sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:orientation="horizontal" >
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:gravity="center"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.formats.UnifiedNativeAdView>
...@@ -90,4 +90,11 @@ ...@@ -90,4 +90,11 @@
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
tools:text="@string/traffic"/> tools:text="@string/traffic"/>
</RelativeLayout> </RelativeLayout>
<LinearLayout
android:id="@+id/ad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:orientation="vertical" />
</LinearLayout> </LinearLayout>
...@@ -3,4 +3,15 @@ ...@@ -3,4 +3,15 @@
<style name="Theme.Shadowsocks.Immersive.Navigation"> <style name="Theme.Shadowsocks.Immersive.Navigation">
<item name="android:statusBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item>
</style> </style>
<style name="Theme.Shadowsocks.AdAttribution">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">left</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">12sp</item>
<item name="android:text">Ad</item>
<item name="android:background">#FFCC66</item>
<item name="android:width">15dp</item>
<item name="android:height">15dp</item>
</style>
</resources> </resources>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment