Flutter中顯示廣點通Banner2廣告之安卓端

純潔的壞蛋發表於2019-05-19

1. 交代背景

我是個人開發者, 然後我的app需要製作ios端, 我的使用者要求出蘋果版, 然後我的swift學得渣, 所以只有學學flutter了. 然而很遺憾的是國內沒有任何一家廣告聯盟出了flutter SDK. 所以不得不收集資料搞一波flutter顯示原生View.

2. 技術交底

搜尋了下, 需要使用到Flutter的外掛機制, 所以請自行熟悉下AndroidView, MethodChannel, PlatformView.

3.效果圖

Flutter中顯示廣點通Banner2廣告之安卓端
下面的Banner2是安卓原生的廣告sdk喲.

4.Android上實現:

class MainActivity : FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        GeneratedPluginRegistrant.registerWith(this)
        //Banner外掛
        BannerPlugin.registerWith(this, this)
    }
}
複製程式碼

BannerPlugin.java

public final class BannerPlugin {

    public static void registerWith(PluginRegistry registry, Activity activity) {
        final String key = BannerPlugin.class.getCanonicalName();
        if (registry.hasPlugin(key)) return;

        PluginRegistry.Registrar registrar = registry.registrarFor(key);
        //這個banner就是flutter呼叫的依據
        registrar.platformViewRegistry().registerViewFactory("banner", new BannerViewFactory(new StandardMessageCodec(), activity, registrar.messenger()));
    }
}

複製程式碼

BannerViewFactory.java

public class BannerViewFactory extends PlatformViewFactory {
    private Activity activity;
    private BinaryMessenger messenger;

    public BannerViewFactory(MessageCodec<Object> createArgsCodec, Activity activity, BinaryMessenger messenger) {
        super(createArgsCodec);
        this.activity = activity;
        this.messenger = messenger;
    }

    @Override
    public PlatformView create(Context context, int id, Object o) {
        return new MyBannerView(activity, messenger, id);
    }
}

複製程式碼

MyBannerView.java

public class MyBannerView implements PlatformView, MethodChannel.MethodCallHandler {
    private UnifiedBannerView bannerView;
    private LinearLayout linearLayout;
    private Activity activity;

    MyBannerView(Activity activity, BinaryMessenger messenger, int id) {
        MethodChannel methodChannel = new MethodChannel(messenger, "banner_" + id);
        methodChannel.setMethodCallHandler(this);
        this.activity = activity;
        if (linearLayout == null) {
            linearLayout = new LinearLayout(activity);
        }
    }

    @Override
    public View getView() {
        return linearLayout;
    }

    @Override
    public void dispose() {
        if (bannerView != null)
            bannerView.destroy();
    }

    @Override
    public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
        switch (methodCall.method) {
            case "setBannerId":
                setText(methodCall, result);
                break;
            default:
                result.notImplemented();
        }
    }

    private void setText(MethodCall methodCall, MethodChannel.Result result) {
        List<String> bannerId = (List<String>) methodCall.arguments;
        System.out.println(bannerId);

        if (bannerView == null){
            bannerView = new UnifiedBannerView(activity, bannerId.get(0), bannerId.get(1), new UnifiedBannerADListener() {
                @Override
                public void onNoAD(AdError adError) {
                    System.out.println(adError.toString());
                }

                @Override
                public void onADReceive() {

                }

                @Override
                public void onADExposure() {

                }

                @Override
                public void onADClosed() {

                }

                @Override
                public void onADClicked() {

                }

                @Override
                public void onADLeftApplication() {

                }

                @Override
                public void onADOpenOverlay() {

                }

                @Override
                public void onADCloseOverlay() {

                }
            });
        }

        linearLayout.addView(bannerView);
        bannerView.loadAD();
        result.success(null);
    }
}
複製程式碼

其中的MethodChannel的onMethodCall就是flutter主動給activity傳值的. 傳值方法是setBannerId, 把APPID和廣告位ID傳送到Native端, 這樣就可以把Banner2新增到linearLayout裡面去了, 是不是很簡單辣, 下面看看Flutter裡面該怎麼用?

Row(
                  children: <Widget>[
                    Expanded(
                      child: Container(
                        child: AndroidView(
                          viewType: "banner",
                          onPlatformViewCreated: (id) {
                            var data = ["1101152570", "4080052898050840"];
                            var channel = MethodChannel("banner_$id");
                            channel.invokeListMethod("setBannerId", data);
                          },
                        ),
                        height: 56,
                      ),
                    ),
                  ],
複製程式碼

主要是AndroidView的banner是Android那邊註冊的view name. 這篇文章是為了記錄我在學習flutter新增banner廣告的過程. 不喜勿噴, 謝謝

相關文章