Android Flutter Native笔记

在native中add flutter fragment

方法1:

// Get a reference to the Activity's FragmentManager to add a new
    // FlutterFragment, or find an existing one.
    FragmentManager fragmentManager = getSupportFragmentManager();

    // Attempt to find an existing FlutterFragment, in case this is not the
    // first time that onCreate() was run.
    flutterFragment = (FlutterFragment) fragmentManager.findFragmentByTag(TAG_FLUTTER_FRAGMENT);
    // Create and attach a FlutterFragment if one does not exist.
    if (flutterFragment == null) {
      flutterFragment = FlutterFragment.createDefault();

      fragmentManager
          .beginTransaction()
          .add(
              R.id.fragment_container,
              flutterFragment,
              TAG_FLUTTER_FRAGMENT
          )
          .commit();
    }

方法2:

// With a new FlutterEngine.
    FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
        .initialRoute("myInitialRoute/")
        .build();
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_container, flutterFragment);
    fragmentTransaction.commit();

flutter与native之间的通信

native端:

  • MainActivity
String initParams = getIntent().getStringExtra(INIT_PARAMS);
    FlutterView flutterView = Flutter.createView(this, getLifecycle(), initParams);
    FrameLayout.LayoutParams layout =
        new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    setContentView(flutterView, layout);
    eventChannelPlugin = EventChannelPlugin.registerWith(flutterView);
    //注册Flutter plugin
    MethodChannelPlugin.registerWith(flutterView);
    basicMessageChannelPlugin = BasicMessageChannelPlugin.registerWith(flutterView);
    uiPresenter = new UIPresenter(this, "通信与混合开发", this);
  • BasicMessageChannelPlugin
import android.app.Activity;
import android.widget.Toast;

import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.StringCodec;
import io.flutter.view.FlutterView;

public class BasicMessageChannelPlugin implements BasicMessageChannel.MessageHandler<String>, BasicMessageChannel.Reply<String> {
  private final Activity activity;
  private final BasicMessageChannel<String> messageChannel;

  static BasicMessageChannelPlugin registerWith(FlutterView flutterView) {
    return new BasicMessageChannelPlugin(flutterView);
  }

  private BasicMessageChannelPlugin(FlutterView flutterView) {
    this.activity = (Activity) flutterView.getContext();
    this.messageChannel = new BasicMessageChannel<>(flutterView, "BasicMessageChannelPlugin", StringCodec.INSTANCE);
    //设置消息处理器,处理来自Dart的消息
    messageChannel.setMessageHandler(this);
  }

  @Override
  public void onMessage(String s, BasicMessageChannel.Reply<String> reply) {//处理Dart发来的消息
    reply.reply("BasicMessageChannel收到:" + s);//可以通过reply进行回复
    if (activity instanceof IShowMessage) {
      ((IShowMessage) activity).onShowMessage(s);
    }
    Toast.makeText(activity, s, Toast.LENGTH_SHORT).show();
  }

  /**
   * 向Dart发送消息,并接受Dart的反馈
   *
   * @param message  要给Dart发送的消息内容
   * @param callback 来自Dart的反馈
   */
  void send(String message, BasicMessageChannel.Reply<String> callback) {
    messageChannel.send(message, callback);
  }

  @Override
  public void reply(String s) {

  }
}
  • MethodChannelPlugin
import android.app.Activity;
import android.widget.Toast;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.view.FlutterView;

public class MethodChannelPlugin implements MethodChannel.MethodCallHandler {
  private final Activity activity;

  /**
   * Plugin registration.
   */
  public static void registerWith(FlutterView flutterView) {
    MethodChannel channel = new MethodChannel(flutterView, "MethodChannelPlugin");
    MethodChannelPlugin instance = new MethodChannelPlugin((Activity) flutterView.getContext());
    channel.setMethodCallHandler(instance);
  }

  private MethodChannelPlugin(Activity activity) {
    this.activity = activity;
  }

  @Override
  public void onMethodCall(MethodCall call, MethodChannel.Result result) {
    switch (call.method) {//处理来自Dart的方法调用
      case "send":
        showMessage(call.arguments());
        result.success("MethodChannelPlugin收到:" + call.arguments);//返回结果给Dart
        break;
      default:
        result.notImplemented();
    }
  }

  /**
   * 展示来自Dart的数据
   *
   * @param arguments
   */
  private void showMessage(String arguments) {
    if (activity instanceof IShowMessage) {
      ((IShowMessage) activity).onShowMessage(arguments);
    }
    Toast.makeText(activity, arguments, Toast.LENGTH_SHORT).show();
  }
}
  • EventChannelPlugin
import io.flutter.plugin.common.EventChannel;
import io.flutter.view.FlutterView;

public class EventChannelPlugin implements EventChannel.StreamHandler {
  private EventChannel.EventSink eventSink;

  static EventChannelPlugin registerWith(FlutterView flutterView) {
    EventChannelPlugin plugin = new EventChannelPlugin();
    new EventChannel(flutterView, "EventChannelPlugin").setStreamHandler(plugin);
    return plugin;
  }

  void send(Object params) {
    if (eventSink != null) {
      eventSink.success(params);
    }
  }

  @Override
  public void onListen(Object args, EventChannel.EventSink eventSink) {
    this.eventSink = eventSink;
  }

  @Override
  public void onCancel(Object o) {
    eventSink = null;
  }
}
  • IShowMessage
public interface IShowMessage {
  void onShowMessage(String message);
  void sendMessage(String message,boolean useEventChannel);
}
  • UIPresenter
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;

public class UIPresenter implements View.OnClickListener {
  private final IShowMessage iShowMessage;
  Activity activity;
  TextView textShow;
  EditText input;
  String title;
  boolean useEventChannel;
  public UIPresenter(@NonNull Activity activity, String title, IShowMessage iShowMessage) {
    this.activity = activity;
    this.title = title;
    this.iShowMessage = iShowMessage;
    initUI();
  }

  private void initUI() {
    ViewGroup contentView = activity.findViewById(android.R.id.content);
    View view = LayoutInflater.from(activity).inflate(R.layout.item_container, null);
    ViewGroup.LayoutParams layoutParams =
        new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    contentView.addView(view, layoutParams);
    textShow = view.findViewById(R.id.textShow);
    input = view.findViewById(R.id.input);
    TextView titleView = view.findViewById(R.id.title);
    titleView.setText(title);
    view.findViewById(R.id.btnSend).setOnClickListener(this);
    RadioGroup radioGroup = view.findViewById(R.id.radioGroup);
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(RadioGroup group, int checkedId) {
        if (checkedId == R.id.mode_basic_message_channel) {
          useEventChannel = false;
        } else if (checkedId == R.id.mode_event_channel) {
          useEventChannel = true;
        }
      }
    });
    input.addTextChangedListener(new TextWatcher() {
      @Override
      public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

      }

      @Override
      public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        iShowMessage.sendMessage(charSequence.toString(),useEventChannel);
      }

      @Override
      public void afterTextChanged(Editable editable) {

      }
    });
  }

  public void showDartMessage(String message) {
    textShow.setText("收到Dart消息:" + message);
  }

  @Override
  public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.btnSend) {
      InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
      //隐藏软键盘
      imm.hideSoftInputFromWindow(input.getWindowToken(), 0);

      String data = input.getText().toString();
      //            sendEvent(data);
    }
  }
}

flutter端:

import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp(
  initParams: window.defaultRouteName,
));

class MyApp extends StatelessWidget {
  final String initParams;

  const MyApp({Key key, this.initParams}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 混合开发',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(
        title: 'Flutter 混合开发',
        initParams: initParams,
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title, this.initParams}) : super(key: key);

  final String title;
  final String initParams;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const EventChannel _eventChannelPlugin =
  EventChannel('EventChannelPlugin');
  String showMessage = "";
  static const MethodChannel _methodChannelPlugin =
  const MethodChannel('MethodChannelPlugin');
  static const BasicMessageChannel<String> _basicMessageChannel =
  const BasicMessageChannel('BasicMessageChannelPlugin', StringCodec());
  bool _isMethodChannelPlugin = false;
  StreamSubscription _streamSubscription;

  @override
  void initState() {
    _streamSubscription = _eventChannelPlugin
        .receiveBroadcastStream('123')
        .listen(_onToDart, onError: _onToDartError);
    //使用BasicMessageChannel接受来自Native的消息,并向Native回复
    _basicMessageChannel
        .setMessageHandler((String message) => Future<String>(() {
      setState(() {
        showMessage = 'BasicMessageChannel:'+message;
      });
      return "收到Native的消息:" + message;
    }));
    super.initState();
  }

  @override
  void dispose() {
    if (_streamSubscription != null) {
      _streamSubscription.cancel();
      _streamSubscription = null;
    }
    super.dispose();
  }

  void _onToDart(message) {
    setState(() {
      showMessage = 'EventChannel:'+message;
    });
  }

  void _onToDartError(error) {
    print(error);
  }

  void _onTextChange(value) async {
    String response;
    try {
      if (_isMethodChannelPlugin) {
        //使用BasicMessageChannel向Native发送消息,并接受Native的回复
        response = await _methodChannelPlugin.invokeMethod('send', value);
      } else {
        response = await _basicMessageChannel.send(value);
      }
    } on PlatformException catch (e) {
      print(e);
    }
    setState(() {
      showMessage = response ?? "";
    });
  }

  void _onChanelChanged(bool value) =>
      setState(() => _isMethodChannelPlugin = value);

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = TextStyle(fontSize: 20);
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        alignment: Alignment.topLeft,
        decoration: BoxDecoration(color: Colors.lightBlueAccent),
        margin: EdgeInsets.only(top: 70),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            SwitchListTile(
              value: _isMethodChannelPlugin,
              onChanged: _onChanelChanged,
              title: Text(_isMethodChannelPlugin
                  ? "MethodChannelPlugin"
                  : "BasicMessageChannelPlugin"),
            ),
            TextField(
              onChanged: _onTextChange,
              decoration: InputDecoration(
                  focusedBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: Colors.white)),
                  enabledBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: Colors.white))),
            ),
            Text(
              '收到初始参数initParams:${widget.initParams}',
              style: textStyle,
            ),
            Text(
              'Native传来的数据:' + showMessage,
              style: textStyle,
            )
          ],
        ),
      ),
    );
  }
}
发布了36 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/j18874964028sss/article/details/103946880