Marriage and dating source code, to achieve a plug-in transparent background

Why did you write this article

The reason why I wrote this article on modifying the transparent background of the source code of marriage and dating is because I changed the official plug-in WebView of fluent_ flutter. Flutter's official plug-ins are all in one gitHub warehouse The databases maintained on the are related to each other. [see figure below]

Therefore, the function of changing the source code of marriage and dating is actually the second. How to modify the plug-ins you need in this huge Flutter plug-in library and maintain them by yourself is the key!!! I think it is necessary to share it with you.

Demand background

The reason for this change is that the background of fluent webview is always white, and the theme of marriage and dating source code is black. In this way, when H5 is embedded, H5 colleagues need to set a black background. At the same time, when the web page is not loaded, there will be a white background, which makes the experience very poor. If the background of webview can be set to transparent, H5 does not need to set the background color, which will improve maintainability and experience. Therefore, the demand arises at the historic moment.

Implementation steps

  1. clone the plugin repository from github, and then open the webview folder separately with Android studio. You can see that it contains three plugins.

2. Change the main plug-in dependency

Enter the webview directory of the main plug-in and see that yaml depends on the plug-in above pub. Therefore, we change the source code under other directories. Yaml does not depend at all and will not take effect.

flutter:
  plugin:
    platforms:
      android:
        default_package: webview_flutter_android
      ios:
        default_package: webview_flutter_wkwebview

dependencies:
  flutter:
    sdk: flutter
  webview_flutter_platform_interface: ^1.0.0
  webview_flutter_android: ^2.0.13
  webview_flutter_wkwebview: ^2.0.13

So I need to change the yaml dependency to a relative path first, so that our changes to the code will take effect. After changing the fluent pub get, follow the source code, and you can enter the local source file, good 👍🏻

  1. Start code change

In the build method of WebView, you can see the parameters passed in through WebView.platform.build, and then judge the platform to return to the corresponding view.

/// webview_flutter/webview_flutter/lib/src/webview.dart
@override
  Widget build(BuildContext context) {
    return WebView.platform.build(
      context: context,
      onWebViewPlatformCreated: _onWebViewPlatformCreated,
      webViewPlatformCallbacksHandler: _platformCallbacksHandler,
      javascriptChannelRegistry: _javascriptChannelRegistry,
      gestureRecognizers: widget.gestureRecognizers,
      creationParams: _creationParamsfromWidget(widget),
    );
  }

  ///Return the corresponding view according to the device type
  static WebViewPlatform get platform {
    if (_platform == null) {
      switch (defaultTargetPlatform) {
        case TargetPlatform.android:
          _platform = AndroidWebView();
          break;
        case TargetPlatform.iOS:
          _platform = CupertinoWebView();
          break;
        default:
          throw UnsupportedError(
              "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
      }
    }
    return _platform!;
  }

///Set the parameter. Here I added an additional transparentBackground parameter, which is of bool type
CreationParams _creationParamsfromWidget(WebView widget) {
  return CreationParams(
    initialUrl: widget.initialUrl,
    webSettings: _webSettingsFromWidget(widget),
    javascriptChannelNames: _extractChannelNames(widget.javascriptChannels),
    userAgent: widget.userAgent,
    autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
    transparentBackground: widget.transparentBackground,
  );
}

Take the source code of marriage and dating as an example, come to WebView_ flutter_ WebView of Android_ Android.dart. You can see that the native view is introduced through AndroidView and matched through the ID 'plugins. Fluent. IO / WebView'.

/// webview_flutter/webview_flutter_android/lib/webview_android.dart
return GestureDetector(
      onLongPress: () {},
      excludeFromSemantics: true,
      child: AndroidView(
        viewType: 'plugins.flutter.io/webview',
        onPlatformViewCreated: (int id) {
          if (onWebViewPlatformCreated == null) {
            return;
          }
          onWebViewPlatformCreated(MethodChannelWebViewPlatform(
            id,
            webViewPlatformCallbacksHandler,
            javascriptChannelRegistry,
          ));
        },
        gestureRecognizers: gestureRecognizers,
        layoutDirection: Directionality.maybeOf(context) ?? TextDirection.rtl,
        creationParams:
            MethodChannelWebViewPlatform.creationParamsToMap(creationParams),
        creationParamsCodec: const StandardMessageCodec(),
      ),
    );

Then enter the android directory, find the corresponding FlutterWebView file, and judge whether the source code of marriage and dating needs to enable transparent background by obtaining the parameters passed in by methodcCannel. If it is true, set the backgroundColor to transparent.

Ps: as you can see here, the writing of native plug-ins is very simple. As long as the communication is carried out through the methodChannel, the parameters are passed into the fluent layer, and the parameters are parsed after the native layer obtains them. Note that data transmission is converted to string type, and even json string is used for data transmission in many cases.
At the same time, the native view is also returned. The view corresponding to the PlatformViewFactory is returned by binding the ID through the PlatformView. The ID is also a string type.
So it's very stupid. Flutter only provides a communication bridge to realize cross platform. The native code still has to be written by yourself. From this point of view, is flutter really cross platform? What is the necessity of an active open source community for flutter? It is worth pondering!

The ios side is the same. The core code is to change the background color of wkWebview to transparent

/// webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m
    NSNumber* transparentEnabled = args[@"transparentBackground"];
    NSLog(@"transparentBackground >>> %i", [transparentEnabled boolValue]);
    // Set the background color to transparent
    if([transparentEnabled boolValue]){
        NSLog(@"Start setting background color");
        _webView.opaque = NO;
        _webView.backgroundColor = UIColor.clearColor;
    }

Key points: how to introduce it into the project and maintain it independently

After the function is realized, we should consider how to introduce it into the source code of marriage and dating. In the past, plug-ins developed by individuals were generally introduced through git warehouse, so I created a new GitHub warehouse and uploaded the whole webview directory. I was pleasantly surprised to find that I failed after I joined the shuttle pub get in the project!
The reason is that there is no yaml file in the root directory, which is an unqualified Plugin for Flutter. Therefore, we need to specify the root directory of the plug-in and specify it to the webview folder through path.

 # webview component
  webview_flutter:
    git:
      url: git://github.com/~~~/webview_flutter_enable_transparent.git
      ref: main
      path: webview_flutter # Specify path

Continue to get, surprise again!!! The reason is: the corresponding plug-in cannot be found in the relative path.. / XXXX. Is this reasonable?
It's reasonable because Flutter must ensure that your package is the smallest. Since you specify the dependent library, I will only download the corresponding library, not the whole git. So when we use the relative path, we can't find other plug-ins in the root directory at all.
Solution: the plug-ins that webview relies on in its yaml file also need to be introduced with git

dependencies:
  flutter:
    sdk: flutter
  webview_flutter_platform_interface:
    git:
      url: https://github.com/~~~/webview_flutter_enable_transparent.git
      ref: main
      path: webview_flutter_platform_interface
  webview_flutter_android:
    git:
      url: https://github.com/~~~/webview_flutter_enable_transparent.git
      ref: main
      path: webview_flutter_android
  webview_flutter_wkwebview:
    git:
      url: https://github.com/~~~/webview_flutter_enable_transparent.git
      ref: main
      path: webview_flutter_wkwebview

Once again, the love and marriage dating source code runs up, very perfect! 👌🏻

WebView(
  initialUrl: "xxxxx",
  javascriptMode: JavascriptMode.unrestricted,
  transparentBackground: true,
)

Write at the end

This time, the change of the source code plug-in for marriage and dating is not difficult. However, I think I have learned a lot about the changes to the official plug-in of Flutter and the maintenance on my git. Quickly create a warehouse and set up an internal plug-in library according to the above method!
Statement: This article is forwarded by cloudleopard technology from Karl_wei blog, if there is infringement, please contact the author to delete

Tags: Java Android Android Studio

Posted on Wed, 10 Nov 2021 17:49:06 -0500 by coreycollins