Flutter中显示广点通Banner2广告之安卓端

3,511 阅读2分钟

1. 交代背景

我是个人开发者, 然后我的app需要制作ios端, 我的用户要求出苹果版, 然后我的swift学得渣, 所以只有学学flutter了. 然而很遗憾的是国内没有任何一家广告联盟出了flutter SDK. 所以不得不收集资料搞一波flutter显示原生View.

2. 技术交底

搜索了下, 需要使用到Flutter的插件机制, 所以请自行熟悉下AndroidView, MethodChannel, PlatformView.

3.效果图

下面的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广告的过程. 不喜勿喷, 谢谢