flutter友盟統計のインタフェース統計

4930 ワード

2020.10.20日更新:
RouteAwareを使用してルーティングを傍受するより良い方法が最近発見されました.次は実装コードです.
初期化:
RouteObserverは、グローバル属性として明示し、パラメータとしてMaterial Appに入力する必要があります.
static final RouteObserver routeObserver = RouteObserver();

@override
 Widget build(BuildContext context) {
   return MaterialApp(
     navigatorObservers: [AppRoutesManager.routeObserver],
     ...
   );
 }

使用
abstract class BaseState extends State with RouteAware {
  String pageName;
  E viewModel;
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() {
    AppRoutesManager.routeObserver.subscribe(this, ModalRoute.of(context)); //  
    super.didChangeDependencies();
 print("didChangeDependencies: ${pageName}  ");
  }

  @override
  void didPush() {
    debugPrint("------> didPush-  ${pageName}");
    super.didPush();
  }

  @override
  void didPop() {
    debugPrint("------> didPop  ${pageName}");
    super.didPop();
  }

  @override
  void didPopNext() {
    debugPrint("------> didPopNext-  ${pageName}");
    super.didPopNext();
  }

  @override
  void didPushNext() {
    debugPrint("------> didPushNext-${pageName}       ");
    super.didPushNext();
  }

  @override
  void dispose() {
    AppRoutesManager.routeObserver.unsubscribe(this); //    
    super.dispose();
//    print("dispose   ${pageName}  ");
    print("  ${pageName}  ");
  }

しかし、この方法には一定の欠陥があります.1、AlertView、showGeneralDialogなどのポップアップボックスの中のpushのルーティングは傍受できません.私の解決策は、メインインタフェースにルーティングのpushを処理するためにコールバック関数を書くことです.2,PageViewを使用してインタフェースを切り替える場合,リスニングも有効ではなく,この場合にはRouteAware内の関数を手動で呼び出す必要がある.
以下に、従来の実装方法を示します.
以前のプロジェクトは友盟統計の機能を統合して、flutterインタフェース統計が実現できないことを発見して、iOSの中で私達はControllerのライフサイクルの中のviewWillAppear:を通じていつインタフェースviewWillDisappearに入ることを処理することができます:いつインタフェースを開いて、インタフェースの処理を離れて、flutterのコンポーネントもライフサイクルがありますが、しかし、そのライフサイクルは私たちの正確な統計をサポートするのに十分ではありません.私たちはinitStateで入る論理をして、disposeで離れる論理をすることができますが、initStateはコンポーネントが初めて初期化されたときにのみジャンプして、disposeはコンポーネントが破壊されたときにのみ呼び出されます.Navigatorを使うとpushが現在のインタフェースを離れて次のインタフェースに入ると、私たちは処理することができません.もちろん、私たちもpushの場所ごとに処理することができますが、このように大量の重複コードが現れ、明らかに私たちの初心に合わないので、考えてみてください.私は次のような案を提供しました.
1、ベースクラスBaseStateがStateから継承されていることを書きます.パラメータpageNameがあります.
abstract class BaseState extends State {
  String pageName;
  void initState() {
    // TODO: implement initState
    super.initState();
    print("initState   ${pageName}  ");
    FlutterBlUmpushPlugin.umengEnterViewWithName(pageName);
  }

 @override
  Widget build(BuildContext context) {
    return build(context);
  }
 @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    print("dispose   ${pageName}  ");
    print("  ${pageName}  ");
    FlutterBlUmpushPlugin.umengOutViewWithName(pageName);
  }
}

2,ひとつのpush関数を実現して、統一的なインタフェースのジャンプをして、Futureの特性を利用してインタフェースの離れることをして、論理処理に入ります:
 //    
  void push({Widget page, Function popCallback}) {
    print("push:   ${pageName}  ");
   FlutterBlUmpushPlugin.umengOutViewWithName(pageName);
    Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
      return page;
    })).then((data) {
      print("pop   ${pageName}  ");
      FlutterBlUmpushPlugin.umengEnterViewWithName(pageName);
      if (popCallback != null) {
        popCallback(data);
      }
    });
  }

  //    
  void routerPush({String route, Function popCallback}) {
    print("routerPush:   ${pageName}  ");
   FlutterBlUmpushPlugin.umengOutViewWithName(pageName);
    AppRoutesManager.router.navigateTo(context, route).then((data) {
      print("pop   ${pageName}  ");
      FlutterBlUmpushPlugin.umengEnterViewWithName(pageName);
      if (popCallback != null) {
        popCallback(data);
      }
    });
  }

次の操作を行います.
class MinePage extends StatefulWidget {
  @override
  _MinePageState createState() => _MinePageState();
}

class _MinePageState extends BaseState with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    // TODO: implement initState
    pageName = "    ";
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(
        title: pageName,
      ),
      body: GestureDetector(
        onTap: () {
          routerPush(route: AppRoutesManager.mall, popCallback: (data) {});
        },
        child: Container(
          color: Colors.red,
        ),
      ),
    );
  }
}

注意:アンドロイドであればinitState()、deactivate()にboolタイプのパラメータ処理を加えることができますが、iOS側のdeactivate()関数がpushの次のインタフェースで呼び出されない理由が分かりません.