13
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Flutter] タブを切り替えるたびに、無駄にリビルドされないようにする

Posted at

タブを使う時に注意することとしては、

タブを切り替えるたびに、無駄にリビルドされないようにするという点です。

これを回避する方法として、wantKeepAliveを使用する方法があります。

wantKeepAliveを使うことによって

  • 一つの画面の中で複数の画面を切り替える時にリロードされないようにする
  • AutomaticKeepAliveMixinを使うと、Stateが破棄されずに、画面をそのまま保った状態で画面を切り替えられる。

事前情報

  • inappwebviewを使用
pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  flutter_inappwebview: ^5.7.2+3

画面の仕様

  • 全ての画面をStatelessで作成した
  • 3つのWebViewを作成(Flutter・Swift・Kotlin)

ソースコード

main.dart
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(tabs: <Widget>[
              Tab(icon: Icon(Icons.flutter_dash)),
              Tab(icon: Icon(Icons.apple)),
              Tab(icon: Icon(Icons.android)),
            ]),
          ),
          body: const TabBarView(
            children: <Widget>[
              Page1(),
              Page2(),
              Page3(),
            ],
          ),
        ),
      ),
    );
  }
}

class Page1 extends StatelessWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://flutter.dev/',
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://developer.apple.com/jp/swift/',
        ),
      ),
    );
  }
}

class Page3 extends StatelessWidget {
  const Page3({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://kotlinlang.org/',
        ),
      ),
    );
  }
}



wantKeepAliveを使用すると。。

画面の仕様

  • 3つのWebViewでStatefulWidgetを使用
  • wantKeepAliveを使用
  • 3つのWebViewを作成(Flutter・Swift・Kotlin)

使い方

1、StatefulWidgetを使用する。
2、Stateのところに、AutomaticKeepAliveClientMixinを追加する。
3、@override
bool get wantKeepAlive => true; を追加する。
4、 Build関数内にsuper.build(context);を追加する。

使用例

class Page1 extends StatefulWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  State<Page1> createState() => _Page1State();
}

class _Page1State extends State<Page1> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
  ・・・省略
  }
}

ソースコード

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(tabs: <Widget>[
              Tab(icon: Icon(Icons.flutter_dash)),
              Tab(icon: Icon(Icons.apple)),
              Tab(icon: Icon(Icons.android)),
            ]),
          ),
          body: const TabBarView(
            children: <Widget>[
              Page1(),
              Page2(),
              Page3(),
            ],
          ),
        ),
      ),
    );
  }
}

class Page1 extends StatefulWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  State<Page1> createState() => _Page1State();
}

class _Page1State extends State<Page1> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://flutter.dev/',
        ),
      ),
    );
  }
}

class Page2 extends StatefulWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  State<Page2> createState() => _Page2State();
}

class _Page2State extends State<Page2> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://developer.apple.com/jp/swift/',
        ),
      ),
    );
  }
}

class Page3 extends StatefulWidget {
  const Page3({Key? key}) : super(key: key);

  @override
  State<Page3> createState() => _Page3State();
}

class _Page3State extends State<Page3> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return InAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          'https://kotlinlang.org/',
        ),
      ),
    );
  }
}

一つ目のコード 2つ目のコード(wantKeepAliveを使用したコード)
Simulator-Screen-Recording-iPhone-14-Pro-2023-05-28-at-09.20.11.gif Simulator-Screen-Recording-iPhone-14-Pro-2023-05-28-at-09.18.31.gif
13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?