Dodawanie banera AdMob i natywnych reklam wbudowanych do aplikacji Flutter

1. Wprowadzenie

W tym ćwiczeniu z programowania zaimplementujesz w aplikacji Flutter baner AdMob i reklamę natywną wbudowaną AdMob.

Co utworzysz

W tym samouczku dowiesz się, jak zaimplementować w aplikacji Flutter baner wstawiony i natywne reklamy wstawione AdMob za pomocą wtyczki Google Mobile Ads do Fluttera.

Jeśli podczas wykonywania tego laboratorium napotkasz jakiekolwiek problemy (błędy w kodzie, błędy gramatyczne, niejasne sformułowania itp.), zgłoś je, korzystając z linku Zgłoś błąd w lewym dolnym rogu laboratorium.

Czego się nauczysz

  • Jak skonfigurować wtyczkę reklam mobilnych Google do Fluttera
  • Jak wdrożyć wbudowany baner i reklamy z nagrodą w aplikacji Flutter

Czego potrzebujesz

  • Android Studio w wersji 4.1 lub nowszej
  • Xcode 12 lub nowsza wersja (do tworzenia aplikacji na iOS)

Jak oceniasz swoje doświadczenie z AdMob?

Początkujący Średnio zaawansowany Zaawansowany

Jak oceniasz swoje doświadczenie z Flutterem?

Początkujący Średnio zaawansowany Zaawansowany

2. Konfigurowanie środowiska programistycznego Fluttera

Aby ukończyć ten moduł, potrzebujesz 2 programów: pakietu SDK Flutteredytora.

Codelab możesz uruchomić na dowolnym z tych urządzeń:

  • fizyczne urządzenie z Android lub iOS podłączone do komputera i ustawione w trybie deweloperskim;
  • Symulator iOS (wymaga zainstalowania narzędzi Xcode).
  • Android Emulator (wymaga konfiguracji w Android Studio).
  • przeglądarka (do debugowania wymagana jest Chrome);
  • Jako aplikacja komputerowa na Windows, Linux lub macOS. Musisz tworzyć aplikację na platformie, na której zamierzasz ją wdrożyć. Jeśli chcesz opracować aplikację na komputery z systemem Windows, musisz to zrobić na komputerze z tym systemem, aby mieć dostęp do odpowiedniego łańcucha kompilacji. Istnieją wymagania dotyczące poszczególnych systemów operacyjnych, które są szczegółowo opisane na stronie docs.flutter.dev/desktop.

Pobieranie kodu

Po pobraniu pliku ZIP wyodrębnij jego zawartość. Zobaczysz folder o nazwie admob-inline-ads-in-flutter-main.

Możesz też sklonować repozytorium GitHub z poziomu wiersza poleceń:

$ git clone https://github.com/googlecodelabs/admob-inline-ads-in-flutter

Repozytorium zawiera 3 foldery:

  • android_studio_folder.png starter:kod początkowy, który będziesz rozwijać w ramach tych ćwiczeń z programowania.
  • android_studio_folder.png complete:ukończony kod do tych ćwiczeń z programowania. (Java i Objective-C w przypadku kodu natywnego)
  • android_studio_folder.png complete_kotlin_swift: ukończony kod do tych ćwiczeń z programowania. (Kotlin i Swift w przypadku kodu natywnego)

3. Konfigurowanie aplikacji w AdMob i jednostek reklamowych

Flutter to pakiet SDK na wiele platform, dlatego w AdMob musisz dodać aplikację i jednostki reklamowe zarówno na Androida, jak i na iOS.

Konfigurowanie na Androidzie

Aby skonfigurować aplikację na Androida, musisz dodać aplikację na Androida i utworzyć jednostki reklamowe.

Dodawanie aplikacji na Androida

  1. W konsoli AdMob w menu Aplikacje kliknij DODAJ APLIKACJĘ.
  2. Gdy pojawi się pytanie Czy aplikacja została opublikowana w Google Play lub App Store?, kliknij NIE.
  3. Wpisz AdMob inline ads w polu nazwy aplikacji i jako platformę wybierz Android.

d51828db0e2e4f6c.png

  1. Włączenie danych o użytkownikach nie jest konieczne do ukończenia tego ćwiczenia. Zalecamy jednak, aby to zrobić, ponieważ pozwala to lepiej poznać zachowania użytkowników. Aby ukończyć proces, kliknij DODAJ.

b918bf44362813a9.png

Tworzenie jednostek reklamowych

Aby dodać jednostki reklamowe:

  1. W menu Aplikacje w konsoli AdMob wybierz aplikację Reklamy wbudowane AdMob.
  2. Kliknij menu Jednostki reklamowe.

Banner

  1. Kliknij DODAJ JEDNOSTKĘ REKLAMOWĄ.
  2. Jako format wybierz Baner.
  3. W polu Nazwa jednostki reklamowej wpisz android-inline-banner.
  4. Aby zakończyć proces, kliknij UTWÓRZ JEDNOSTKĘ REKLAMOWĄ.

Reklamy natywne

  1. Kliknij DODAJ JEDNOSTKĘ REKLAMOWĄ.
  2. Jako format wybierz Zaawansowana reklama natywna.
  3. W polu Nazwa jednostki reklamowej wpisz android-inline-native.
  4. Aby zakończyć proces, kliknij UTWÓRZ JEDNOSTKĘ REKLAMOWĄ.

Zanim nowa jednostka reklamowa zacznie wyświetlać reklamy, zwykle mija kilka godzin.

Jeśli chcesz od razu przetestować działanie reklamy, użyj identyfikatorów testowych aplikacji i jednostek reklamowych podanych w tabelach identyfikatorów aplikacji i jednostek reklamowych na Androida oraz iOS.

Konfigurowanie na urządzeniu z iOS

Aby skonfigurować usługę pod kątem iOS, musisz dodać aplikację na iOS i utworzyć jednostki reklamowe.

Dodawanie aplikacji na iOS

  1. W konsoli AdMob w menu Aplikacje kliknij DODAJ APLIKACJĘ.
  2. Gdy pojawi się pytanie Czy aplikacja została opublikowana w Google Play lub App Store?, kliknij NIE.
  3. iOS jako platformę.

a4c963c9aa09519.png

  1. Włączenie danych o użytkownikach nie jest konieczne do ukończenia tego ćwiczenia. Zalecamy jednak, aby to zrobić, ponieważ pozwala to lepiej poznać zachowania użytkowników. Aby ukończyć proces, kliknij DODAJ.

b918bf44362813a9.png

Tworzenie jednostek reklamowych

Aby dodać jednostki reklamowe:

  1. W menu Aplikacje w konsoli AdMob wybierz aplikację Reklamy wbudowane AdMob.
  2. Kliknij menu Jednostki reklamowe.

Banner

  1. Kliknij DODAJ JEDNOSTKĘ REKLAMOWĄ.
  2. Jako format wybierz Baner.
  3. W polu Nazwa jednostki reklamowej wpisz ios-inline-banner.
  4. Aby zakończyć proces, kliknij UTWÓRZ JEDNOSTKĘ REKLAMOWĄ.

Reklamy natywne

  1. Kliknij DODAJ JEDNOSTKĘ REKLAMOWĄ.
  2. Jako format wybierz Zaawansowana reklama natywna.
  3. W polu Nazwa jednostki reklamowej wpisz ios-inline-native.
  4. Aby zakończyć proces, kliknij UTWÓRZ JEDNOSTKĘ REKLAMOWĄ.

Zanim nowa jednostka reklamowa zacznie wyświetlać reklamy, zwykle mija kilka godzin.

Jeśli chcesz od razu przetestować działanie reklamy, użyj identyfikatora aplikacji testowej i identyfikatorów jednostek reklamowych podanych w tabeli poniżej.

Opcjonalnie: użyj testowej aplikacji w AdMob i jednostek reklamowych

Jeśli chcesz wykonać ćwiczenie z programowania zamiast tworzyć własną aplikację i jednostki reklamowe, możesz użyć testowych identyfikatorów aplikacji w AdMob i jednostek reklamowych podanych w tabelach poniżej.

Identyfikator aplikacji na Androida lub jednostki reklamowej

Produkt

Identyfikator aplikacji lub jednostki reklamowej

Identyfikator aplikacji w AdMob

ca-app-pub-3940256099942544~3347511713

Baner

ca-app-pub-3940256099942544/6300978111

Natywna

ca-app-pub-3940256099942544/2247696110

Identyfikator aplikacji na iOS lub identyfikator jednostki reklamowej

Produkt

Identyfikator aplikacji lub jednostki reklamowej

Identyfikator aplikacji w AdMob

ca-app-pub-3940256099942544~1458002511

Baner

ca-app-pub-3940256099942544/2934735716

Natywna

ca-app-pub-3940256099942544/3986624511

Więcej informacji o reklamach testowych znajdziesz w dokumentacji dla deweloperów dotyczącej reklam testowych na Androidareklam testowych na iOS.

4. Dodawanie wtyczki reklam mobilnych Google do Fluttera

Flutter korzysta z wtyczek, aby zapewnić dostęp do szerokiej gamy usług specyficznych dla danej platformy. Wtyczki umożliwiają dostęp do usług i interfejsów API na każdej platformie.

Wtyczka google_mobile_ads obsługuje wczytywanie i wyświetlanie banerów, reklam pełnoekranowych, reklam z nagrodą i reklam natywnych za pomocą interfejsu AdMob API.

Flutter to pakiet SDK na wiele platform, więc wtyczka google_mobile_ads ma zastosowanie zarówno w przypadku iOS, jak i Androida. Jeśli więc dodasz wtyczkę do aplikacji Flutter, będzie ona używana zarówno w wersji aplikacji z reklamami wbudowanymi AdMob na Androida, jak i na iOS.

Dodawanie wtyczki reklam mobilnych Google jako zależności

Aby uzyskać dostęp do interfejsów API AdMob z projektu reklam wbudowanych AdMob, dodaj google_mobile_ads jako zależność do pliku pubspec.yaml znajdującego się w katalogu głównym projektu.

pubspec.yaml

...
dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^0.3.9

  # TODO: Add google_mobile_ads as a dependency
  google_mobile_ads: ^1.2.0

...

Kliknij Pub get, aby zainstalować wtyczkę w projekcie AdMob inline ads.

93ef6061e58ebc86.png

Aktualizacja pliku AndroidManifest.xml (Android)

  1. Otwórz plik android/app/src/main/AndroidManifest.xml w Android Studio.
  2. Dodaj identyfikator aplikacji w AdMob, dodając tag <meta-data> o nazwie com.google.android.gms.ads.APPLICATION_ID. Jeśli na przykład identyfikator aplikacji w AdMob to ca-app-pub-3940256099942544~3347511713, musisz dodać te wiersze do pliku AndroidManifest.xml.

AndroidManifest.xml

<manifest>
    ...
    <application>
       ...
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>

</manifest>

Aktualizowanie pliku Info.plist (iOS)

  1. Otwórz plik ios/Runner/Info.plist w Android Studio.
  2. Dodaj klucz GADApplicationIdentifier z identyfikatorem aplikacji w AdMob jako ciągiem znaków. Jeśli na przykład identyfikator aplikacji w AdMob to ca-app-pub-3940256099942544~1458002511, musisz dodać te wiersze do pliku Info.plist.

ios/Runner/Info.plist

...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...

5. Dodawanie klasy pomocniczej do reklam

Utwórz nowy plik o nazwie ad_helper.dart w katalogu lib. Następnie wdróż klasę AdHelper, która udostępnia identyfikator aplikacji w AdMob oraz identyfikatory jednostek reklamowych na Androida i iOS.

Pamiętaj, aby zastąpić identyfikator aplikacji w AdMob (ca-app-pub-xxxxxx~yyyyy) i identyfikator jednostki reklamowej (ca-app-pub-xxxxxxx/yyyyyyyy) identyfikatorami utworzonymi w poprzednim kroku.

ad_helper.dart

import 'dart:io';

class AdHelper {

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_BANNER_AD_UNIT_ID";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_BANNER_AD_UNIT_ID>";
    } else {
      throw UnsupportedError("Unsupported platform");
    }
  }

  static String get nativeAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_NATIVE_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_NATIVE_AD_UNIT_ID>";
    } else {
      throw UnsupportedError("Unsupported platform");
    }
  }
}

Jeśli chcesz użyć testowego identyfikatora aplikacji w AdMob i testowych identyfikatorów jednostek reklamowych, użyj tego fragmentu kodu.

ad_helper.dart

import 'dart:io';

class AdHelper {
  
  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/6300978111';
    } else if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/2934735716';
    }
    throw UnsupportedError("Unsupported platform");
  }

  static String get nativeAdUnitId {
    if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/2247696110';
    } else if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/3986624511';
    }
    throw UnsupportedError("Unsupported platform");
  }
}

6. Inicjowanie pakietu SDK do reklam mobilnych Google

Zanim wczytasz reklamy, musisz zainicjować pakiet SDK do reklam mobilnych Google. Otwórz plik lib/home_page.dart i zmodyfikuj _initGoogleMobileAds(), aby zainicjować pakiet SDK przed wczytaniem strony głównej.

Pamiętaj, że aby uzyskać wynik inicjowania pakietu SDK po jego zakończeniu, musisz zmienić typ zwracany metody _initGoogleMobileAds()Future<dynamic> na Future<InitializationStatus>.

home_page.dart

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'package:flutter/material.dart';

...

class HomePage extends StatelessWidget {

  ...

  Future<InitializationStatus> _initGoogleMobileAds() {
    // TODO: Initialize Google Mobile Ads SDK
    return MobileAds.instance.initialize();
  }
}

7. Dodawanie reklamy banerowej

W tej sekcji wyświetlasz baner reklamowy na środku listy, jak pokazano na zrzucie ekranu poniżej.

62c405c962909fd3.png

  1. Otwórz plik lib/banner_inline_page.dart.
  2. Zaimportuj ad_helper.dartgoogle_mobile_ads.dart, dodając te wiersze:
...

// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

class BannerInlinePage extends StatefulWidget {
  ...
}
  1. W klasie _BannerInlinePageState dodaj te elementy i metody w przypadku banera reklamowego.

Pamiętaj, że _kAdIndex oznacza indeks, w którym będzie wyświetlany baner reklamowy, i jest używany do obliczania indeksu elementu za pomocą metody _getDestinationItemIndex().

banner_inline_page.dart

class _BannerInlinePageState extends State<BannerInlinePage> {

  // TODO: Add _kAdIndex
  static final _kAdIndex = 4;

  // TODO: Add a banner ad instance
  BannerAd? _ad;

  ...

  // TODO: Add _getDestinationItemIndex()
  int _getDestinationItemIndex(int rawIndex) {
    if (rawIndex >= _kAdIndex && _ad != null) {
      return rawIndex - 1;
    }
    return rawIndex;
  }

  ...
}
  1. W metodzie initState() utwórz i wczytaj BannerAd dla banera 320x50 (AdSize.banner). Pamiętaj, że detektor zdarzeń reklamy jest skonfigurowany tak, aby aktualizować interfejs (setState()) po wczytaniu reklamy.

banner_inline_page.dart

@override
void initState() {
  super.initState();

  // TODO: Load a banner ad
  BannerAd(
    adUnitId: AdHelper.bannerAdUnitId,
    size: AdSize.banner,
    request: AdRequest(),
    listener: BannerAdListener(
      onAdLoaded: (ad) {
        setState(() {
          _ad = ad as BannerAd;
        });
      },
      onAdFailedToLoad: (ad, error) {
        // Releases an ad resource when it fails to load
        ad.dispose();
        print('Ad load failed (code=${error.code} message=${error.message})');
      },
    ),
  ).load();
}
  1. Zmodyfikuj metodę build(), aby w razie dostępności wyświetlać baner reklamowy.
  2. Zaktualizuj itemCount,, aby zliczać wyświetlenia banera reklamowego, i zaktualizuj itemBuilder,, aby renderować baner reklamowy w indeksie reklamy (_kAdIndex) po wczytaniu reklamy.
  3. Zaktualizuj kod, aby używać metody _getDestinationItemIndex() do pobierania indeksu elementu treści.

banner_inline_page.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    ...
    body: ListView.builder(
      // TODO: Adjust itemCount based on the ad load state
      itemCount: widget.entries.length + (_ad != null ? 1 : 0),
      itemBuilder: (context, index) {
        // TODO: Render a banner ad
        if (_ad != null && index == _kAdIndex) {
          return Container(
            width: _ad!.size.width.toDouble(),
            height: 72.0,
            alignment: Alignment.center,
            child: AdWidget(ad: _ad!),
          );
        } else {
          // TODO: Get adjusted item index from _getDestinationItemIndex()
          final item = widget.entries[_getDestinationItemIndex(index)];

          return ListTile(
            ...
          );
        }
      },
    ),
  );
}
  1. Zwolnij zasób powiązany z obiektem BannerAd, wywołując metodę BannerAd.dispose() w metodzie wywołania zwrotnego dispose().

banner_inline_page.dart

@override
void dispose() {
  // TODO: Dispose a BannerAd object
  _ad?.dispose();

  super.dispose();
}

To wszystko. Uruchom projekt i na stronie głównej kliknij przycisk Banerowa reklama wbudowana. Po wczytaniu reklamy zobaczysz baner reklamowy na środku listy.

a5f857a850539fe9.png c32af50872514224.png

8. Dodawanie reklamy natywnej

W tej sekcji wyświetlasz reklamę natywną na środku listy, jak pokazano na zrzucie ekranu poniżej.

f1671b0fa349ccf8.png

Reklamy natywne są wyświetlane użytkownikom za pomocą komponentów interfejsu, które są natywne dla platformy (np. View na Androidzie lub UIView na iOS).

Nie można jednak tworzyć natywnych komponentów interfejsu bezpośrednio za pomocą widżetów Fluttera. Dlatego musisz zaimplementować NativeAdFactory na każdej platformie. Służy on do tworzenia widoku reklamy natywnej na daną platformę (NativeAdView na Androidzie i GADNativeAdView na iOS) z obiektu reklamy natywnej (NativeAd na Androidzie i GADNativeAd na iOS).

Implementacja klasy NativeAdFactory na Androidzie (Java)

  1. Otwórz plik android/build.gradle (lub dowolny plik w folderze android) i kliknij Otwórz do edycji w Android Studio, aby otworzyć projekt aplikacji na Androida.

623ad3d2282ccbf8.png

  1. Jeśli pojawi się prośba o wybranie okna, w którym ma zostać otwarty nowy projekt, kliknij New Window (Nowe okno), aby projekt Flutter pozostał otwarty podczas pracy nad projektem aplikacji na Androida.

d188bb51cf7c2d08.png

Tworzenie układu reklamy natywnej

  1. Po otwarciu projektu aplikacji na Androida kliknij prawym przyciskiem myszy app w panelu projektu w Android Studio i z menu kontekstowego wybierz New > Android Resource File (Nowy > Plik zasobów Androida).

2b629ee277a68fd7.png

  1. W oknie Nowy plik zasobu wpisz list_tile_native_ad.xml jako nazwę pliku.
  2. Jako typ zasobu wybierz Układ i wpisz com.google.android.gms.ads.nativead.NativeAdView jako element główny.
  3. Aby utworzyć nowy plik układu, kliknij OK.

575f126dd018bc0.png

  1. Wdróż układ reklamy w ten sposób: Pamiętaj, że układ powinien być zgodny z wyglądem platformy, dla której jest przeznaczony.

list_tile_native_ad.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#F19938"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:textSize="12sp" />

        <ImageView
            android:id="@+id/iv_list_tile_native_ad_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:scaleType="fitXY"
            tools:background="#EDEDED" />

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_large"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:background="#F19938"
            android:gravity="center"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:visibility="invisible" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="80dp"
            android:layout_marginLeft="80dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_list_tile_native_ad_headline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#000000"
                android:textSize="16sp"
                tools:text="Headline" />

            <TextView
                android:id="@+id/tv_list_tile_native_ad_body"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#828282"
                android:textSize="14sp"
                tools:text="body" />

        </LinearLayout>

    </FrameLayout>

</com.google.android.gms.ads.nativead.NativeAdView>

Utwórz klasę ListTileNativeAdFactory

  1. W okienku Project (Projekt) kliknij prawym przyciskiem myszy pakiet com.codelab.flutter.admobinlineads i wybierz New > Java Class (Nowy > Klasa Java).

9f3f111dd207a9b4.png

  1. Wpisz ListTileNativeAdFactory jako nazwę i wybierz z listy Klasa.

47ff82d92676e26.png

  1. Gdy pojawi się okno Nowe zajęcia, pozostaw wszystkie pola puste i kliknij OK.

Zobaczysz, że klasa ListTileNativeAdFactory została utworzona w pakiecie com.codelab.flutter.admobinlineads.

e4ed232c358ffb19.png

  1. Zaimplementuj klasę ListTileNativeAdFactory w ten sposób: Zwróć uwagę, że klasa implementuje metodę createNativeAd() w interfejsie GoogleMobileAdsPlugin.NativeAdFactory.

Klasa fabryczna odpowiada za tworzenie obiektu widoku do renderowania reklamy natywnej. Jak widać w kodzie, klasa fabryki tworzy obiekt UnifiedNativeAdView i wypełnia go obiektem NativeAd.

ListTileNativeAdFactory.java

// TODO: Implement ListTileNativeAdFactory class

package com.codelab.flutter.admobinlineads;

import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.Map;

import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;

class ListTileNativeAdFactory implements GoogleMobileAdsPlugin.NativeAdFactory {

    private final Context context;

    ListTileNativeAdFactory(Context context) {
        this.context = context;
    }

    @Override
    public NativeAdView createNativeAd(
            NativeAd nativeAd, Map<String, Object> customOptions) {
        NativeAdView nativeAdView = (NativeAdView) LayoutInflater.from(context)
                .inflate(R.layout.list_tile_native_ad, null);

        TextView attributionViewSmall = nativeAdView
                .findViewById(R.id.tv_list_tile_native_ad_attribution_small);
        TextView attributionViewLarge = nativeAdView
                .findViewById(R.id.tv_list_tile_native_ad_attribution_large);

        ImageView iconView = nativeAdView.findViewById(R.id.iv_list_tile_native_ad_icon);
        NativeAd.Image icon = nativeAd.getIcon();
        if (icon != null) {
            attributionViewSmall.setVisibility(View.VISIBLE);
            attributionViewLarge.setVisibility(View.INVISIBLE);
            iconView.setImageDrawable(icon.getDrawable());
        } else {
            attributionViewSmall.setVisibility(View.INVISIBLE);
            attributionViewLarge.setVisibility(View.VISIBLE);
        }
        nativeAdView.setIconView(iconView);

        TextView headlineView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_headline);
        headlineView.setText(nativeAd.getHeadline());
        nativeAdView.setHeadlineView(headlineView);

        TextView bodyView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_body);
        bodyView.setText(nativeAd.getBody());
        bodyView.setVisibility(nativeAd.getBody() != null ? View.VISIBLE : View.INVISIBLE);
        nativeAdView.setBodyView(bodyView);

        nativeAdView.setNativeAd(nativeAd);

        return nativeAdView;
    }
}

Zarejestruj klasę ListTileNativeAdFactory

Aby można było używać instancji NativeAdFactory po stronie Fluttera, należy ją zarejestrować w GoogleMobileAdsPlugin.

  1. Otwórz plik MainActivity.java i zastąp metody configureFlutterEngine() oraz cleanUpFlutterEngine().
  2. Zarejestruj klasę ListTileNativeAdFactory za pomocą unikalnego identyfikatora ciągu tekstowego (listTile) w metodzie configureFlutterEngine().

MainActivity.java

public class MainActivity extends FlutterActivity {

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        // TODO: Register the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "listTile",
                new ListTileNativeAdFactory(getContext()));
    }

    ...
}
  1. Każde wystąpienie typu NativeAdFactory powinno zostać wyrejestrowane podczas procesu czyszczenia. Wyrejestruj klasę ListTileNativeAdFactory w metodzie cleanUpFlutterEngine().

MainActivity.java

public class MainActivity extends FlutterActivity {

    ...

    @Override
    public void cleanUpFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.cleanUpFlutterEngine(flutterEngine);

        // TODO: Unregister the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile");
    }
}

Możesz teraz użyć klasy ListTileNativeAdFactory do renderowania reklam natywnych na Androidzie.

Implementacja NativeAdFactory na Androidzie (Kotlin)

  1. Otwórz plik android/build.gradle (lub dowolny plik w folderze android) i kliknij Otwórz do edycji w Android Studio, aby otworzyć projekt aplikacji na Androida.

623ad3d2282ccbf8.png

  1. Jeśli pojawi się prośba o wybranie okna, w którym ma zostać otwarty nowy projekt, kliknij New Window (Nowe okno), aby projekt Flutter pozostał otwarty podczas pracy nad projektem aplikacji na Androida.

d188bb51cf7c2d08.png

Tworzenie układu reklamy natywnej

  1. Po otwarciu projektu aplikacji na Androida kliknij prawym przyciskiem myszy app w panelu projektu w Android Studio i z menu kontekstowego wybierz New > Android Resource File (Nowy > Plik zasobów Androida).

2b629ee277a68fd7.png

  1. W oknie Nowy plik zasobu wpisz list_tile_native_ad.xml jako nazwę pliku.
  2. Jako typ zasobu wybierz Układ i wpisz com.google.android.gms.ads.nativead.NativeAdView jako element główny.
  3. Aby utworzyć nowy plik układu, kliknij OK.

575f126dd018bc0.png

  1. Wdróż układ reklamy w ten sposób: Pamiętaj, że układ powinien być zgodny z wyglądem platformy, dla której jest przeznaczony.

list_tile_native_ad.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#F19938"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:textSize="12sp" />

        <ImageView
            android:id="@+id/iv_list_tile_native_ad_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:scaleType="fitXY"
            tools:background="#EDEDED" />

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_large"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:background="#F19938"
            android:gravity="center"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:visibility="invisible" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="80dp"
            android:layout_marginLeft="80dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_list_tile_native_ad_headline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#000000"
                android:textSize="16sp"
                tools:text="Headline" />

            <TextView
                android:id="@+id/tv_list_tile_native_ad_body"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#828282"
                android:textSize="14sp"
                tools:text="body" />

        </LinearLayout>

    </FrameLayout>

</com.google.android.gms.ads.nativead.NativeAdView>

Utwórz klasę ListTileNativeAdFactory

  1. W panelu Project (Projekt) kliknij prawym przyciskiem myszy pakiet com.codelab.flutter.admobinlineads i wybierz New > Kotlin File/Class (Nowy > Plik/klasa Kotlin).

7311744cb97cad75.png

  1. Wpisz ListTileNativeAdFactory jako nazwę i wybierz z listy Klasa.

25691151b5814867.png

  1. Zobaczysz, że klasa ListTileNativeAdFactory została utworzona w pakiecie com.codelab.flutter.admobinlineads.
  2. Zaimplementuj klasę ListTileNativeAdFactory w ten sposób: Zwróć uwagę, że klasa implementuje metodę createNativeAd() w interfejsie GoogleMobileAdsPlugin.NativeAdFactory.

Klasa fabryczna odpowiada za tworzenie obiektu widoku do renderowania reklamy natywnej. Jak widać w kodzie, klasa fabryki tworzy obiekt NativeAdView i wypełnia go obiektem NativeAd.

ListTileNativeAdFactory.kt

// TODO: Implement ListTileNativeAdFactory class

package com.codelab.flutter.admobinlineads

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin

class ListTileNativeAdFactory(val context: Context) : GoogleMobileAdsPlugin.NativeAdFactory {

    override fun createNativeAd(
            nativeAd: NativeAd,
            customOptions: MutableMap<String, Any>?
    ): NativeAdView {
        val nativeAdView = LayoutInflater.from(context)
                .inflate(R.layout.list_tile_native_ad, null) as NativeAdView

        with(nativeAdView) {
            val attributionViewSmall =
                    findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_small)
            val attributionViewLarge =
                    findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_large)

            val iconView = findViewById<ImageView>(R.id.iv_list_tile_native_ad_icon)
            val icon = nativeAd.icon
            if (icon != null) {
                attributionViewSmall.visibility = View.VISIBLE
                attributionViewLarge.visibility = View.INVISIBLE
                iconView.setImageDrawable(icon.drawable)
            } else {
                attributionViewSmall.visibility = View.INVISIBLE
                attributionViewLarge.visibility = View.VISIBLE
            }
            this.iconView = iconView

            val headlineView = findViewById<TextView>(R.id.tv_list_tile_native_ad_headline)
            headlineView.text = nativeAd.headline
            this.headlineView = headlineView

            val bodyView = findViewById<TextView>(R.id.tv_list_tile_native_ad_body)
            with(bodyView) {
                text = nativeAd.body
                visibility = if (nativeAd.body.isNotEmpty()) View.VISIBLE else View.INVISIBLE
            }
            this.bodyView = bodyView

            setNativeAd(nativeAd)
        }

        return nativeAdView
    }
}

Zarejestruj klasę ListTileNativeAdFactory

Aby można było używać instancji NativeAdFactory po stronie Fluttera, należy ją zarejestrować w GoogleMobileAdsPlugin.

  1. Otwórz plik MainActivity.kt i zastąp metody configureFlutterEngine() oraz cleanUpFlutterEngine().
  2. Zarejestruj klasę ListTileNativeAdFactory za pomocą unikalnego identyfikatora ciągu tekstowego (listTile) w metodzie configureFlutterEngine().

MainActivity.kt

class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        // TODO: Register the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.registerNativeAdFactory(
                flutterEngine, "listTile", ListTileNativeAdFactory(context))
    }

    ...
}
  1. Każde wystąpienie typu NativeAdFactory powinno zostać wyrejestrowane podczas procesu czyszczenia. Wyrejestruj klasę ListTileNativeAdFactory w metodzie cleanUpFlutterEngine().

MainActivity.kt

class MainActivity: FlutterActivity() {
    ...

    override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
        super.cleanUpFlutterEngine(flutterEngine)

        // TODO: Unregister the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
    }
}

Możesz teraz użyć klasy ListTileNativeAdFactory do renderowania reklam natywnych na Androidzie.

Implementacja NativeAdFactory na iOS (Objective-C)

Otwórz plik ios/Podfile (lub dowolny plik w folderze ios) i kliknij Open iOS module in Xcode (Otwórz moduł iOS w Xcode), aby otworzyć projekt iOS.

62aa12c10e6d671f.png

Przygotowywanie układu reklamy natywnej

Do rozmieszczenia komponentów reklamy natywnej musisz mieć widok niestandardowy (*.xib). W tym ćwiczeniu używamy wstępnie skonfigurowanego widoku, aby ułatwić Ci pracę.

Po otwarciu projektu iOS w Xcode sprawdź, czy w projekcie Runner znajduje się plik ListTileNativeAdView.xib.

a5f04a32f1868d4f.png

Utwórz klasę ListTileNativeAdFactory

  1. W nawigatorze projektu kliknij prawym przyciskiem myszy grupę Runner i wybierz New File (Nowy plik), aby utworzyć plik nagłówkowy dla nowej klasy.

6455aab9e9881ca.png

  1. W oknie szablonu wybierz Plik nagłówka i nadaj mu nazwę ListTileNativeAdFactory.
  2. Po utworzeniu pliku ListTileNativeAdFactory.h zdefiniuj klasę ListNativeAdFactory w ten sposób:

ListTileNativeAdFactory.h

#ifndef ListTileNativeAdFactory_h
#define ListTileNativeAdFactory_h

// TODO: Import FLTGoogleMobileAdsPlugin.h
#import "FLTGoogleMobileAdsPlugin.h"

// TODO: Declare ListTileNativeAdFactory
@interface ListTileNativeAdFactory : NSObject<FLTNativeAdFactory>

@end


#endif /* ListTileNativeAdFactory_h */
  1. Utwórz plik Objective-C, wybierając New File (Nowy plik) w grupie Runner.
  2. W następnym oknie dialogowym wpisz ListTileNativeAdFactory w polu Plik i wybierz Pusty plik jako typ pliku.

2c9c998c48db3a0.png

  1. Po kliknięciu Dalej pojawi się prośba o wybranie folderu, w którym ma zostać utworzony nowy plik. Pozostaw wszystko bez zmian i kliknij Utwórz.

8635ffe502d1f4ab.png

  1. Zaimplementuj klasę ListTileNativeFactory w ten sposób: Zwróć uwagę, że klasa implementuje metodę createNativeAd() w protokole FLTNativeAdFactory.

Klasa fabryczna odpowiada za tworzenie obiektu widoku do renderowania reklamy natywnej. Jak widać w kodzie, klasa fabryki tworzy obiekt GADNativeAdView i wypełnia go obiektem GADNativeAd.

ListTileNativeAdFactory.m

// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"

// TODO: Implement ListTileNativeAdFactory
@implementation ListTileNativeAdFactory

- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                             customOptions:(NSDictionary *)customOptions {
  GADNativeAdView *nativeAdView =
    [[NSBundle mainBundle] loadNibNamed:@"ListTileNativeAdView" owner:nil options:nil].firstObject;

  ((UILabel *)nativeAdView.headlineView).text = nativeAd.headline;

  ((UILabel *)nativeAdView.bodyView).text = nativeAd.body;
  nativeAdView.bodyView.hidden = nativeAd.body ? NO : YES;

  ((UIImageView *)nativeAdView.iconView).image = nativeAd.icon.image;
  nativeAdView.iconView.hidden = nativeAd.icon ? NO : YES;

  nativeAdView.callToActionView.userInteractionEnabled = NO;

  nativeAdView.nativeAd = nativeAd;

  return nativeAdView;
}

@end

Zarejestruj klasę ListTileNativeAdFactory

Implementacja FLTNativeAdFactory musi zostać zarejestrowana w FLTGoogleMobileAdsPlugin, zanim będzie można jej używać po stronie Fluttera.

Otwórz plik AppDelegate.m i zarejestruj ListTileNativeAdFactory za pomocą unikalnego identyfikatora ciągu znaków (listTile), wywołując metodę [FLTGoogleMobileAdsPlugin registerNativeAdFactory].

AppDelegate.m

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"

// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  // TODO: Register ListTileNativeAdFactory
  ListTileNativeAdFactory *listTileFactory = [[ListTileNativeAdFactory alloc] init];
  [FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
                                        factoryId:@"listTile"
                                  nativeAdFactory:listTileFactory];

  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Teraz możesz użyć ListTileNativeAdFactory do renderowania reklam natywnych na iOS.

Implementacja NativeAdFactory na iOS (Swift)

Otwórz plik ios/Podfile (lub dowolny plik w folderze ios) i kliknij Open iOS module in Xcode (Otwórz moduł iOS w Xcode), aby otworzyć projekt iOS.

62aa12c10e6d671f.png

Przygotowywanie układu reklamy natywnej

Do rozmieszczenia komponentów reklamy natywnej musisz mieć widok niestandardowy (*.xib). W tym ćwiczeniu używamy wstępnie skonfigurowanego widoku, aby ułatwić Ci pracę.

Po otwarciu projektu iOS w Xcode sprawdź, czy w projekcie Runner znajduje się plik ListTileNativeAdView.xib.

a5f04a32f1868d4f.png

Utwórz klasę ListTileNativeAdFactory

  1. W nawigatorze projektu kliknij prawym przyciskiem myszy grupę Runner i wybierz New File (Nowy plik), aby utworzyć plik nagłówkowy dla nowej klasy.

9115c92543345ef1.png

  1. W oknie szablonu wybierz Plik Swift i nadaj mu nazwę ListTileNativeAdFactory.
  2. Po utworzeniu pliku ListTileNativeAdFactory.swift zaimplementuj klasę ListNativeAdFactory.

Zwróć uwagę, że klasa implementuje metodę createNativeAd() w protokole FLTNativeAdFactory.

Klasa fabryczna odpowiada za tworzenie obiektu widoku do renderowania reklamy natywnej. Jak widać w kodzie, klasa fabryki tworzy obiekt GADNativeAdView i wypełnia go obiektem GADNativeAd.

ListTileNativeAdFactory.swift

// TODO: Import google_mobile_ads
import google_mobile_ads

// TODO: Implement ListTileNativeAdFactory
class ListTileNativeAdFactory : FLTNativeAdFactory {

    func createNativeAd(_ nativeAd: GADNativeAd,
                        customOptions: [AnyHashable : Any]? = nil) -> GADNativeAdView? {
        let nibView = Bundle.main.loadNibNamed("ListTileNativeAdView", owner: nil, options: nil)!.first
        let nativeAdView = nibView as! GADNativeAdView

        (nativeAdView.headlineView as! UILabel).text = nativeAd.headline

        (nativeAdView.bodyView as! UILabel).text = nativeAd.body
        nativeAdView.bodyView!.isHidden = nativeAd.body == nil

        (nativeAdView.iconView as! UIImageView).image = nativeAd.icon?.image
        nativeAdView.iconView!.isHidden = nativeAd.icon == nil

        nativeAdView.callToActionView?.isUserInteractionEnabled = false

        nativeAdView.nativeAd = nativeAd

        return nativeAdView
    }
}

Zarejestruj klasę ListTileNativeAdFactory

Implementacja FLTNativeAdFactory musi zostać zarejestrowana w FLTGoogleMobileAdsPlugin, zanim będzie można jej używać po stronie Fluttera.

Otwórz plik AppDelegate.m i zarejestruj ListTileNativeAdFactory za pomocą unikalnego identyfikatora ciągu znaków (listTile), wywołując metodę FLTGoogleMobileAdsPlugin.registerNativeAdFactory().

AppDelegate.swift

import UIKit
import Flutter

// TODO: Import google_mobile_ads
import google_mobile_ads

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    // TODO: Register ListTileNativeAdFactory
    let listTileFactory = ListTileNativeAdFactory()
    FLTGoogleMobileAdsPlugin.registerNativeAdFactory(
        self, factoryId: "listTile", nativeAdFactory: listTileFactory)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Teraz możesz użyć ListTileNativeAdFactory do renderowania reklam natywnych na iOS.

Integrowanie reklamy natywnej z widżetami Fluttera

  1. Otwórz plik lib/native_inline_page.dart. Następnie zaimportuj ad_helper.dartgoogle_mobile_ads.dart, dodając te wiersze:

native_inline_page.dart

...

// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

class NativeInlinePage extends StatefulWidget {
  ...
}
  1. W klasie _NativeInlinePageState dodaj te elementy i metody reklamy natywnej:

Pamiętaj, że _kAdIndex oznacza indeks, w którym będzie wyświetlany baner reklamowy, i jest używany do obliczania indeksu elementu za pomocą metody _getDestinationItemIndex().

native_inline_page.dart

class _NativeInlinePageState extends State<NativeInlinePage> {

  // TODO: Add _kAdIndex
  static final _kAdIndex = 4;

  // TODO: Add a native ad instance
  NativeAd? _ad;

  ...

  // TODO: Add _getDestinationItemIndex()
  int _getDestinationItemIndex(int rawIndex) {
    if (rawIndex >= _kAdIndex && _ad != null) {
      return rawIndex - 1;
    }
    return rawIndex;
  }

  ...
}
  1. W metodzie initState() utwórz i wczytaj obiekt NativeAd, który używa funkcji ListTileNativeAdFactory do generowania widoku reklamy natywnej.

Pamiętaj, że używany jest ten sam identyfikator fabryki (listTile), który został użyty do zarejestrowania fabryki w przypadku wtyczki.

native_inline_page.dart

@override
void initState() {
  super.initState();

  // TODO: Create a NativeAd instance
  _ad = NativeAd(
    adUnitId: AdHelper.nativeAdUnitId,
    factoryId: 'listTile',
    request: AdRequest(),
    listener: NativeAdListener(
      onAdLoaded: (ad) {
        setState(() {
          _ad = ad as NativeAd;
        });
      },
      onAdFailedToLoad: (ad, error) {
        // Releases an ad resource when it fails to load
        ad.dispose();
        print('Ad load failed (code=${error.code} message=${error.message})');       },
    ),
  );

  _ad.load();
}
  1. Zmodyfikuj metodę build(), aby w razie dostępności wyświetlać baner reklamowy.
  2. Zaktualizuj itemCount,, aby zliczać wejścia w baner reklamowy, i zaktualizuj itemBuilder,, aby renderować baner reklamowy w indeksie reklamy (_kAdIndex), gdy reklama zostanie wczytana.
  3. Zaktualizuj kod, aby używać metody _getDestinationItemIndex() do pobierania indeksu elementu treści.

native_inline_page.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    ...
    body: ListView.builder(
      // TODO: Adjust itemCount based on the ad load state
      itemCount: widget.entries.length + (_ad != null ? 1 : 0),
      itemBuilder: (context, index) {
        // TODO: Render a banner ad
        if (_ad != null && index == _kAdIndex) {
          return Container(
            height: 72.0,
            alignment: Alignment.center,
            child: AdWidget(ad: _ad!),
          );
        } else {
          // TODO: Get adjusted item index from _getDestinationItemIndex()
          final item = widget.entries[_getDestinationItemIndex(index)];

          return ListTile(
            ...
          );
        }
      },
    ),
  );
}
  1. Zwolnij zasób powiązany z obiektem NativeAd, wywołując metodę NativeAd.dispose() w metodzie wywołania zwrotnego dispose().

native_inline_page.dart

@override
void dispose() {
  // TODO: Dispose a NativeAd object
  _ad?.dispose();

  super.dispose();
}

To wszystko. Uruchom projekt i na stronie głównej kliknij przycisk Reklama wbudowana. Po wczytaniu reklamy natywnej zobaczysz ją na środku listy.

f1671b0fa349ccf8.png 5ead873222c800eb.png

9. Wszystko gotowe

To już koniec samouczka. Gotowy kod do tego ćwiczenia znajdziesz w folderze android_studio_folder.pngcomplete lub android_studio_folder.png complete_kotlin_swift.