Flutterでハマった点/Kotlinからの変換メモ①

2020/10/04 00:00公開
Table of Contents
  1. AppBar (Androidで言うToolBar)
  2. BottomNavigaton
  3. アイコン
  4. ページの作成
  5. ページ遷移
  6. タップ音(操作音)フィードバック
  7. DartからKotlinコード呼び出し
    1. Kotlin側
    2. Dart側
  8. onDestroy()
  9. ファイル転送関連
    1. UDP bind
    2. 自身のIPアドレスの取得
    3. 自身のモデル名等を取得

AppBar (Androidで言うToolBar)

・ScaffoldにAppBar引数があるため、そこにAppBarをインスタンス化して追加

BottomNavigaton

・ScaffoldにbottomNavigation引数があるため、そこにBottomNavigationをインスタンス化して追加

アイコン

・Iconsクラスに大量に有用なアイコンが並んでいるので、Icon(Icons.xxx)のように使う。

ページの作成

import 'package:flutter/cupertino.dart';

class PageName extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _PageNameState();
}

class _PageNameState extends State<PageName> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("Hello World!"),
    );
  }
}

PageNameの部分にページ名。

・「stful」と入力すると、一発で作成できる。

ページ遷移

Navigator.push(context, MaterialPageRoute(builder: (context) => PageName()));

PageNameの部分に遷移先ページ名。

タップ音(操作音)フィードバック

Feedback.forTap(context);

DartからKotlinコード呼び出し

Qiitaにあった情報はちょっと古かったので、公式ドキュメントのお世話に。

Kotlin側

class MainActivity: FlutterActivity() {
    companion object {
        const val BATTERY_CHANNEL = "sample.channel/battery" // 適当な文字列。普通は「パッケージ名/チャンネル名(任意の名称)」
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BATTERY_CHANNEL).setMethodCallHandler { call, result ->
            when(call.method) {
                "getBatteryLevel" -> {
                    val level = batteryLevel
                    when {
                        Build.VERSION.SDK_INT < Build.VERSION_CODES.P && level == 0 -> result.error(null, "Battery Level returned illegal value.", null)
                        Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && level == Int.MIN_VALUE -> result.error(null, "Battery Level returned illegal value.", null)
                        else -> result.success(level)
                    }
                }
                else -> result.notImplemented()
            }
        }
    }

    val batteryLevel: Int get() {
        return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    }
}

※Android 5.0以降を対象にした実装です。

Dart側

MethodChannel("sample.channel/battery").invokeMethod("getBatteryLevel").then((result) {
    print(result);
});

※「Open for Editing in Android Studio」をクリックして編集する。

※反映にはAndroid側のプロジェクトでビルドする必要がある。

onDestroy()

  @override
  void dispose() {
    // process
    super.dispose();
  }

ファイル転送関連

UDP bind

UDP.bind(Endpoint.broadcast(port: Port(port)));

自身のIPアドレスの取得

    NetworkInterface.list(type: InternetAddressType.IPv4).then((result) {
      String address;
      result.forEach((element) {
        if (address != null) return;
        try {
          address = element.addresses.firstWhere((element) => element.address.startsWith("192.168.0.")).address;
        } catch (e) {}
      });
      address // アドレス
    });

自身のモデル名等を取得

・pubspec.yamlの依存関係に以下を追記

device_info: ">=0.4.2+8 <2.0.0"

・DeviceInfoPluginをインスタンス化→取得

var devInfo = DeviceInfoPlugin();

// Android
if (Platform.isAndroid)
var modelName = (await devInfo.androidInfo).model;

// iOS
if (Platform.isIOS)
var modelName = (await devInfo.iosInfo).utsname.machine;