こんにちは。
Google IO 2019にて発表されたFlutetr for webが発表されましたね。
どんなもんかと思ってさっそく使ってみました。
私が試した方法です。
上のリポジトリをCloneします。
hello_wold
をディレクトリをコピーしてディレクトリ名を変更します。
pubspec.yml
を以下のように書き換えます。
name: qkuronekop.dev environment: # You must be using Flutter >=1.5.0 or Dart >=2.3.0 sdk: '>=2.3.0-dev.0.1 <3.0.0' dependencies: flutter_web: any flutter_web_ui: any dev_dependencies: build_runner: ^1.4.0 build_web_compilers: ^2.0.0 dependency_overrides: flutter_web: git: url: https://github.com/flutter/flutter_web path: packages/flutter_web flutter_web_ui: git: url: https://github.com/flutter/flutter_web path: packages/flutter_web_ui
サンプルのままだとflutter_web
やflutter_web_ui
が相対パスになっているので直しただけですね。
あと、nameのところを変更しました。
ここまでできればあとはlib/main.dart
を自由に書き換えればOKですね。
動かし方はflutter_webのリポジトリのREADMEに詳しくあるのですが、flutter pub global activate webdev
でwevdevをインストールしておきます。
先ほど作ったプロジェクトのルートでflutter pub upgrade
します。
webdev serve
しビルドに成功するとhttp://127.0.0.1:8080
で接続できます。
開発中はwebdev serve --auto restart
で起動するとホットリロードしてくれます。
せっかくなので、Firbase hostingでページを公開してみました。
flutter for webで作ったページをfirebaseで公開する方法はこちらの記事を参考にさせていただきました。
作ったページはこちら。
すごく簡素な感じなのでおいおい色々試して行きたいです。 あと、スマホで見ると文字が切れてるかも。
main.dart // Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter_web/material.dart'; import 'dart:js' as js; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. primarySwatch: Colors.deepPurple, primaryColorDark: Colors.deepPurpleAccent), home: Scaffold( appBar: AppBar( title: Text( 'qkuronekop.dev', textDirection: TextDirection.ltr, ), ), body: SingleChildScrollView( child: Stack( children: <Widget>[ Column( children: <Widget>[ Container( margin: EdgeInsets.all(16.0), child: Column( children: <Widget>[ SizedBox( height: 16.0, ), Center( child: Text( 'Profile', textDirection: TextDirection.ltr, style: TextStyle( fontSize: 28.0, fontWeight: FontWeight.bold), ), ), SizedBox( height: 24.0, ), Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( height: 48.0, width: 48.0, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage( '画像URL'), fit: BoxFit.fill), borderRadius: BorderRadius.circular(24.0), boxShadow: [ BoxShadow( color: Colors.black38, offset: Offset(2.0, 2.0)) ], ), ), SizedBox( width: 16.0, ), Container( width: 400.0, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text('こんにちは。\n辻村里美(@qkuronekop)と申します。'), Text( 'Androidアプリ開発が得意です。\n現在は、KotlinでのAndroid開発やFlutterでのAndroid、iOS開発をしています。'), Text('上記以外に興味があるのはGo言語でのWebアプリ開発です。'), ], ), ) ], ), ), Container( margin: EdgeInsets.symmetric(vertical: 32.0), width: 300.0, height: 2.0, color: Colors.purpleAccent, ), Center( child: Text( 'Github', textDirection: TextDirection.ltr, style: TextStyle( fontSize: 28.0, fontWeight: FontWeight.bold), ), ), SizedBox( height: 24.0, ), GestureDetector( child: Text( 'https://github.com/qkuronekop', style: TextStyle( color: Colors.deepPurpleAccent, decoration: TextDecoration.underline, decorationColor: Colors.deepPurpleAccent, decorationStyle: TextDecorationStyle.solid, ), ), onTap: () { js.context.callMethod( "open", ["https://github.com/qkuronekop"]); }, ), Container( margin: EdgeInsets.symmetric(vertical: 32.0), width: 300.0, height: 2.0, color: Colors.purpleAccent, ), Center( child: Text( 'Blog', textDirection: TextDirection.ltr, style: TextStyle( fontSize: 28.0, fontWeight: FontWeight.bold), ), ), SizedBox( height: 24.0, ), GestureDetector( child: Text('http://qkuronekop.hatenablog.jp/', style: TextStyle( color: Colors.deepPurpleAccent, decoration: TextDecoration.underline, decorationColor: Colors.deepPurpleAccent, decorationStyle: TextDecorationStyle.solid, )), onTap: () { js.context.callMethod("open", ["http://qkuronekop.hatenablog.jp/"]); }, ), Container( margin: EdgeInsets.symmetric(vertical: 32.0), width: 300.0, height: 2.0, color: Colors.purpleAccent, ), SizedBox( height: 24.0, ), Center( child: Text( 'App', textDirection: TextDirection.ltr, style: TextStyle( fontSize: 28.0, fontWeight: FontWeight.bold), ), ), SizedBox( height: 24.0, ), GestureDetector( child: Container( width: 320.0, child: Image.network( '画像URL'), ), onTap: () { js.context.callMethod("open", [ "https://play.google.com/store/apps/developer?id=qkuronekop&hl=ja" ]); }, ) ], ), ), ], ), ], ), ))); } }
現状感じていること
- 外部リンクができないので
dart:js
で外部リンクを開くスクリプトを書かねばならない。リンクではなくonTapを使っているのでPCでみた時にカーソルが変化しないのがちょっと微妙かな。 - 当たり前だけど今あるNativeアプリに依存するようなpackageは使えないのでweb用のライブラリとかが充実してくるといいな。
- Image.assetが使えないんだけど私だけ???
- CSS書かなくてもいい感じのUIが作れるのは最高。
2019/6/26追記
Image.assetについて勘違いしていたことがあって、Nativeの時みたいにpubspec.ymlにパスかいて使うのではなくweb/assets/
にリソースを置いて、そこのパスを書けばいいんですね。
しかし、ローカルでは表示されるけどfirebase hostingにアップすると表示されなくなる……なぜだ。。。
ちょっと色々デザインいじってみました。 gitにも公開したので興味ある方はみてください!