- 投稿日:2020-03-19T22:56:48+09:00
Flutterを始めてListViewが難しい
きっかけ
長期休みに入り興味があったFlutterを始めた。
いろいろやってみて、まずListViewにつまづいた。つまづいたポイントとして、
- クラスの使い方
- 要素のUIの構成
- どのように要素にデータを渡すか
がある。
開発はXamarinを軽く触ったことがある程度で、初心者。
書籍は基礎から学ぶFlutterを購入し、公式サイトも見ながらスタートしたFlutter超初心者。また、Flutterを開発するにあたって日本語の記事が異常に少ないので書こうと思った。これからも何かつまづくことがあればちょくちょく書く予定。ListView
ListViewとは要素をスクロールできる画面に表示していくウィジェット。
FlutterにはYoutubeに公式チャンネルがあり、多くのウィジェットの紹介動画があり、短く、見やすい動画となっているのでおすすめ。もちろんListViewの動画もある。
ListView (Flutter Widget of the Week)ListView.separated
ちょっと調べてみて、
ListView.separated
コンストラクタが使いやすそうだったので使ってみた。
他にもListView
、ListView.builder
、ListView.custom
があるがまだよくわからない(そのうち追記するかも)。
ListView.separated
コンストラクタの使用例は、最後に書いたので参考にして欲しい。公式サイトによると、このコンストラクタは以下のようになっているらしい。
https://api.flutter.dev/flutter/widgets/ListView/ListView.separated.html
ListView.separated({
Key key,
Axis scrollDirection: Axis.vertical,
bool reverse: false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap: false,
EdgeInsetsGeometry padding,
@required IndexedWidgetBuilder itemBuilder,
@required IndexedWidgetBuilder separatorBuilder,
@required int itemCount,
bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true,
bool addSemanticIndexes: true,
double cacheExtent
})
@required
がついているものは必須の引数で、これらを解説する。itemBuilder
この引数には、
ListView
のアイテムを作るウィジェットを入れる。ここのウィジェットで作ったものがListViewの1アイテムとしてitemCount
の数分作られる。
また、関数はsample.dartWidget functionName(BuildContext context, int index){}のように書く。
separatorBuilder
itemBuilder
と同様の形式の関数を書く。公式サイトより引用し、sample.dart(BuildContext context, int index) => Divider()と書いたが、よくわかっていないため後に追記する。
(知っている方いたら教えてください!)itemCount
要素数。
int
型の整数値のみを入れる。List<T> list
を使う場合、list.length
を使うといいっぽい。使用例
書いてみたプログラムと実行結果を示す。
プログラム
sample.dartimport 'package:flutter/material.dart'; import 'dart:math'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MainPage(), ); } } class Person { int age; final String name; Person({this.age, this.name}); } class MainPage extends StatelessWidget { List<Person> _data = [ Person(age: 20, name: "Satou"), Person(age: 18, name: "Suzuki"), Person(age: 30, name: "Tanaka") ]; Widget MyListView() { return ListView.separated( itemBuilder: (BuildContext context, int index) { return Container( padding: EdgeInsets.all(10), child: Row( children: <Widget>[ Container( alignment: Alignment.topLeft, child: Text( _data[index].name, style: TextStyle(fontSize: 25) ), ), Spacer(), Container( alignment: Alignment.bottomRight, child: Text( _data[index].age.toString(), style: TextStyle(fontSize: 20) ), ) ], ) ); }, separatorBuilder: (BuildContext context, int index) => Divider(), itemCount: _data.length); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text("List Page")), body: Container(color: Colors.white, child: MyListView()))); } }実行結果
- 投稿日:2020-03-19T21:27:12+09:00
[Android R (11)] 国内版(docomo版)Pixel 3 XLにAndroid 11 DP 2を入れる
こんばんわ。
さよならメモリーズって曲を最近知ったんですけどめっちゃ気に入りました。本題
Android 11 DP 2出た!
でもまだAndroid Beta登録(端末単体のアプデでAndroidの開発版が入れられるやつ)始まってないんですよね。
というわけで今回は少し怖い(メイン機なので)ですがPCを使った方法で入れていこうと思います。読むのめんどいわって人は「Android Flash Toolで導入する」のところまで飛ばしてください。
環境
なまえ あたい 端末 Pixel 3 XL (docomoで買った) PC Windows 10 / Chrome 80 公式サイト
https://developer.android.com/preview/get
OTA Update vs Factory Image vs Android Flash Tool
Android 11 DPを入れる方法はこの3つです。
公式サイトにはOTAでの導入方法がありませんがOTAでもできるそうです(海外サイト見た)。
できること OTA Update Factory Image Android Flash Tool アップデート ○ ○ ○ ダウングレード ☓ ○ ? 作業にAndroid端末が初期化されるか? ☓ ○ ○ Bootloaderアンロックが必要か? ☓ ○ ○ 特に一番下のBootloaderアンロックは保証対象外になる可能性が
OTAでインストールした結果
起動しませんでした。理由は国内版だからかな?
3回ぐらいブートアニメーション→電源落ちるを繰り返した後何故かAndroid 10が起動しました。Android Flash Toolで導入する
仕方ないのでブートローダーをアンロックして導入することにします。
これにより二つの問題が発生します。
・端末が初期化される
・ブートローダーをアンロックするので保証が効かなくなる可能性が(デバイスの改造にあたりそう)あるadb用意しておいてね
OEMロック解除をON
開発者向けオプション→OEMロック解除をON
なんですが
docomoで購入した端末はこの項目がグレーアウト(会社によって利用できないみたいなメッセージが表示されている)SIMロック解除する (docomoで買ったときのみ)
OEMロック解除を有効にするためにはSIMロック解除をする必要があります。
My docomoからオンラインで無料で出来ます。
結構下の方までスクロールしないと無いAndroid Flash Toolを使う
https://developer.android.com/preview/download#flashtool
ここからアップデートする端末(今回はPixel 3 XL)のリンクを押します。
そしてこの画面までいって「Add new device」を押します。
あとUSBデバッグの許可をしておきましょう。
そしたら端末名のところを押します。
あとは「Install」を押しましょう。
Reselect your device
Still waiting for fastboot to come up
when flashing a device for the first time you must select it again
since you are running windows you may also see this every time the device reboots
when flashing a device for the first time you must select it again. To continue reselect your device from the browser menu.
Note : It may have a different name such as "Android"これなんかよく出てくるんですがその時は「Reselect device」をクリックしてデバイスを選ぶ必要があります。(ちなみに私は「Pixel 3 XL」以外の名前で出てきた)
この画面インストール中に何回か出たのでそのときは選んであげてください。
途中でブートローダーのアンロックを求めてくる
これはブートローダーがロックされている場合に出ると思います。
「Start」を押して端末の操作をします。
音量キーを操作して「Unlock the bootloader」に合わせて電源ボタンを押します。
この作業をすると端末が初期化されますSoftware successfully updated
このあと少し待つと端末に初期設定画面が表示されてるはずです。おめでとう!!!!
ブートローダーをロックする
初期設定したあとでもする前でもいいですがこれの作業は必要です(多分)。
ブートローダーをロックするとデータが初期化されます。コマンドプロンプトで以下の一行を入力
adb reboot bootloader
そしたら続けて以下の一行を入力
fastboot flashing lock
初期設定終わったあとだともう一回初期設定をする必要があるので初期設定前にやるといいと思います。
以上、Android 11 DP 2の導入方法でした。
通知が別れてる!?!?!?
生存確認(おま環かもしれない)
おサイフケータイアプリの起動はできた。
(決済できるかは見てない。お金もったいないので。あでも自販機にのリーダーにかざしたら残高表示はされた。)
モバイルSuicaアプリも起動できた。
というかUIどうにかならないのこれ。
Google Pay経由でチャージする事ができることは確認した。(1円チャージした。)
Google PayのID/QuickPay登録は失敗した。
あとなんか起動する条件が厳しそうなやつ
Kyash 起動できた 三井住友銀行 起動できた(USBデバッグ無効化必須) なんか出来ないことあったら追記すると思います。
おわりに
参考にしました。:https://mobilelaby.com/blog-entry-how-to-install-android-11-developer-preview.html
- 投稿日:2020-03-19T15:08:46+09:00
1人でアプリを作る
はじめに
こんにちは。
今回から、『Unity』を使ってスクロールゲームを作っていきます。
企画から完成までの過程を日記感覚で記録していきます!制作環境
macOS Mojave バージョン 10.14.6
Unity 2019.2.19f1企画
「近未来の世界で、主人公は機械で...」という、妄想を膨らませながら、
イメージを紙にサラサラと書いていきます。
ステージ構成や、プレイしてもらう時間、ターゲットなどをじっくり考えました。実際に書いたものが下記画像になります。(きたない...)
まあ、見づらくても、自分が分かっていればいいと思います。
ただ、他の人に見せるなら綺麗にまとめた方がいいかもしれません...。
今回は、一人で作るので、このまま進めます。イメージイラスト
世界観や、設定が決まったので、イメージイラストを書きます。
手が動くままに書きました。
イメージイラストを書いてから、世界観や設定を決めていってもいいかもしれません。
まとめ
今回は、企画をかんがえました。
内容を、事細かに説明していないので短くなっちゃいました...。次回は、ゲームの流れがわかる、簡易的なモックアップを作ります。
- 投稿日:2020-03-19T15:08:46+09:00
1人でアプリを作る【その1】
はじめに
こんにちは。
今回から、『Unity』を使ってスクロールゲームを作っていきます。
企画から完成までの過程を日記感覚で記録していきます!制作環境
macOS Mojave バージョン 10.14.6
Unity 2019.2.19f1企画
「近未来の世界で、主人公は機械で...」という、妄想を膨らませながら、
イメージを紙にサラサラと書いていきます。
ステージ構成や、プレイしてもらう時間、ターゲットなどをじっくり考えました。実際に書いたものが下記画像になります。(きたない...)
まあ、見づらくても、自分が分かっていればいいと思います。
ただ、他の人に見せるなら綺麗にまとめた方がいいかもしれません...。
今回は、一人で作るので、このまま進めます。イメージイラスト
世界観や、設定が決まったので、イメージイラストを書きます。
手が動くままに書きました。
イメージイラストを書いてから、世界観や設定を決めていってもいいかもしれません。
まとめ
今回は、企画をかんがえました。
内容を、事細かに説明していないので短くなっちゃいました...。次回は、ゲームの流れがわかる、簡易的なモックアップを作ります。
- 投稿日:2020-03-19T10:02:50+09:00
Android StudioにおけるBuild Outputの文字化けを解消
- 投稿日:2020-03-19T07:39:53+09:00
flutter + firebaseで本番環境と開発環境を切り替える
この記事ですること
flutter run
とflutter run --release
でfirebaseの環境(プロジェクト)を切り替えるflutter run
とflutter run --release
でflutterの環境を切り替えるこの記事でしないこと
- 別アプリ化
- ステージング環境の構築
対象
個人開発者など、複雑な環境構築を必要としないけど、最低限、本番と開発環境を分けたい人
複雑に環境を分けたい人は
以下の記事が参考になります。
flutterで本番/ステージング/開発を切り替える - Qiita
Flutterで環境ごとにビルド設定を切り替える — iOS編
【iOS】FlutterでFlavorを使って環境ごとに切り替えてビルドする(debug/stg/prod)flutterのcreate
defalutでorganaizationがcom.exampleとなっていますが、exampleだとandroid play storeが受け付けてくれませんので、exampleはやめましょう。
com.exampleは禁止されているため、別のパッケージ名を使用する必要があります。
アプリケーション ID の設定よりfirebaseの設定
プロジェクトの追加
Firebaseプロジェクトから本番用と開発用の2つのプロジェクトを作ります。
名前は何でもいいです。規則やルールはありません。私は開発に-devと名付けています。
本番はbase-appで開発はbase-app-devと名付けました。アプリの追加
firebaseのプロジェクトの設定からアプリを追加してください。
androidとiosの設定を本番環境(base-app)と開発環境(base-app-dev)の両方に作ってください。iosのアプリの追加
IOSのバンドルIDはここのBundle Identiferです。
androidのアプリの追加
androidのバンドルIDはandroid -> app -> src -> main -> AndroidManifest.xmlの2行目
デバッグ用の署名証明書問題
デバッグ用の署名証明書 SHA-1(省略可)はgoogle sign in などで使用しますが、重複できませんので、本番環境側に入力しておきます。
重複するとこのパッケージ名と SHA-1 の組み合わせを持つ OAuth2 クライアントは、別のプロジェクトに既に存在しますというエラーがでます。
この手順の既存のプロジェクトはインポートしたくなく、Invites は使用していない。
の指示に従うと、開発と本番の両方でgoogle sign in が使用できるようになるのらしいですが、私はうまくいきませんでした。(詳細求む)firebase sdkの追加をします。ここでは省略します。
設定ファイルをダウンロードしておいてください。本番と開発が混ざらないように注意してください。
この時点でandroidとiosの2設定ファイル × 本番と開発の2環境 = 4ファイルflutterのiosの設定(xcode上)
iosの設定は少し面倒です。
targetのrunnerを開いてください。開き方がわからない方は下のgifを見てください。
一番左のフォルダマークをクリック -> Runnerをクリック -> TERGETSのRunnerをクリック
Build Phasesをクリックします。
+ボタンからnew run script phase
をクリック一番下に
Run Script
ができますので、リネームします。なんでもいいです。私はChoose Firebase Environment
と名付けました。ドラッグアンドドロップで
Run Script
の真下に持ってきます。
shellに以下を上書きしてください。
echo文いらないですね。必要ない人は削ってください。# Type a script or drag a script file from your workspace to insert its path. rm -rf "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" echo "★★★" echo "-----${CONFIGURATION}-----" echo "-----${SRCROOT}-----" echo "-----${BUILT_PRODUCTS_DIR}-----" echo "-----${PRODUCT_NAME}-----" if [ "${CONFIGURATION}" = "Debug" ] ; then cp "$SRCROOT/Runner/GoogleService-Info-dev.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" echo "Development GoogleService-Info copied." elif [ "${CONFIGURATION}" = "Release" ] ; then cp "$SRCROOT/Runner/GoogleService-Info-release.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" echo "Release GoogleService-Info copied." fi何をしているのかというと、ビルドの度に
"${CONFIGURATION}"
で開発か本番か判断してビルドされたデータのGoogleService-Info.plist
を書き換えているのです。
力技でゴリ押してますね。次にコピー元ファイルを作ります。
GoogleService-Info-dev.plist
とGoogleService-Info-release.plist
を作ってRunner配下においてください。
名前は上記のshellと一致していればなんでもいいでです。
androidと同じようにフォルダつくってもいいかもしれません。私は試したことないですが。
xcodeの右側の画面を確認してみてください。FullPathがdownloadフォルダになっていないことを確認してください。
これでfirebaseの環境の切り替え設定が完了しました。
(補足) info.plistを分けたい場合
info.plistはアプローチが変わります。
下記のように$(変数名)
と指定します。
じゃあ、その変数はどこで設定するかというと、
TARGETのRunner -> Build Swtting -> +ボタン -> Add User-Defined Settingから設定します。
flutterのandroidの設定
androidの設定は簡単です。
以下のスクショと同じになるようにしてください。
開発環境
android/app/src/debug
フォルダに開発(base-app-dev)のgoogle-services.josn
を格納する本番環境
android/app/src/
にreleaseフォルダを作るandroid/app/src/release/
に本番(base-app)のgoogle-services.josn
を格納する
フォルダ名は必ずrelease
です。階層もdebugと同じ階層です。オリジナルのフォルダ名やオリジナルの階層ではいけません。
どうやら、debugとreleaseはandroid側のデフォルトの設定のようです。ですから、本番と開発だけなら複雑な設定なしで簡単に切り替えられるみたいです。詳細はこちら最後に
実際に
google-services.josn
を開いて5行目のproject_id
などから開発と本番が逆になってないか確かめてください。
あと、android studioから同期とflutter clean
コマンドを打つとよいでしょう。本番と開発が分離できているか確かめる
firestoreのデータを取得してみて環境の切り替えができているか確かめます。
firebase(firestore)の設定
テストモードで開始します。30日間で期限切れるのがいいですね。
ロケーションには気をつけましょう。変更できませんので。
asia-northeast1が東京、2が大阪です。データを作成します。
checkコレクションにドキュメントidは自動で、"name" = "本番"もしくは"開発"をつくることにします。
flutterの設定
- pubspec.yamlにcloud_firestoreを記述
- main.dartを以下に書き換え
main.dartimport 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } // 本番かリリースかを判断するには bool.fromEnvironment('dart.vm.product')を使う。 // よりわかりやすくするためにラップして使っている。 bool isRelease() { bool _bool; bool.fromEnvironment('dart.vm.product') ? _bool = true : _bool = false; return _bool; } class MyApp extends StatelessWidget { // This widget is the root of your application. @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.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Center( child: Text( 'firestoreの動作確認\n(${isRelease() ? 'リリース' : 'デバック'}モード)'))), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text(isRelease() ? "リリースモード" : "デバッグモード", style: Theme.of(context).textTheme.title), NewWidget(), ], ), ), ); } } class NewWidget extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: Firestore.instance.collection('check').snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } switch (snapshot.connectionState) { case ConnectionState.waiting: return CircularProgressIndicator(); default: return Text('取得した値: ${snapshot.data.documents[0]['name']}'); } }, ); } }うまくいくと画面はこうなります。
実機でのリリースビルド
リリースビルドはシュミレーターでは動きませんので実機を使用します。
PCにはPixel3が接続されています。ビルドします。
android:flutter build apk
ios:flutter build ios
コンソールから
flutter devices
を実行します。このコマンドでインストール先のデバイスを探します。
実機にインストール
flutter install -d 8
先頭の1文字だけでもいいのが良いですね。
スクリーンは省略しますが、「本番」という値が取得できます。
- 投稿日:2020-03-19T01:20:57+09:00
Android + C++ で wav 音声再生するための Oboe ライブラリのメモ
背景
- Android で手っ取り早く C++ で wav 音声を再生したい
- Android Vulkan で compute shader で STFT 処理とか spatial audio 処理した音声データを再生したい
- Vulkan と一緒に使いたいので, Android 8 以降対応でよい.
Native audio library
AAduio(Android 8.0 or later) と OpenSLES がありますが, どちらも低レイヤーなので, wav をお手軽再生とかはできません.
https://developer.android.com/ndk/guides/audio
既存ライブラリ
手っ取り早く Android C++ で wav 再生は SoLoud があります.
https://sol.gfxile.net/soloud/
クロスプラットフォームでよいのですが, Android はあまりメンテされていないようで, CMake 用の設定がなかったり, backend は SLES だけだったり, logcat になぜか多量の debug warning が出たりといまいちです.
Oboe
C++14 or later になりますが(Android NDK は最近 C++17 or later 対応なので問題はない), Oboe https://github.com/google/oboe が推奨っぽいので使ってみます. 実態としては AAudio, OpenSLES のラッパーです.
クロスプラットフォームだとうれしかったですが, Android 限定です. PC を使うときは SoLoud にするなどと切り替えるとよいかもです.
Oboe 自体も, 本体は wav load とかはには対応していませんが, samples の parselib に wav などのローダがあります.
https://github.com/google/oboe/tree/master/samples/parselib/src/main/cpp
github issue を見ると, 古い Android では動かなかったりあるようですが, とりあえず AAudio(Android 8) 以降の端末では大丈夫そうでしょうか.
C++14
Android で C++14 だと, spdlog と組み合わせるときに不都合がありました. ヘッダのインクルード順にはお気をつけください.
Android NDK + C++14 設定 cmake で no member named
make_unique
in namespacestd
エラーなどが出る
https://qiita.com/syoyo/items/5274fcde46520ff301f4組み込む
CMake 設定がありますので, これを参考にするとよいでしょう.
Oboe を使っての wav のロードと再生は, drumthumber サンプルを参考にします.
https://github.com/google/oboe/tree/master/samples/drumthumper
同じく samples にある,
iolib
(play/stop とか簡単に使える API?),parselib
(wav loader) を使っています.
これらは, ファイル数は多くないので, 自前の CMakeLists にソースコードリスト直追加が楽かと思います.
(add_subdirectory だと循環参照があって,--whole-archive
リンカオプションを指定しないとリンクエラーになる)
iolib
に wav をロードして再生するSimpleMultiPlayer
があります. ただ, エラーチェックが無かったり, 初期化せずに wav ロードすると seg fault するなど, コード品質が微妙です.音声の再生
SimpleMultiPlayer
の triggerDown で再生できます. triggerUp で再生を終了できます.
再生の停止(pause)はなさそうなので自前実装が必要そうです.wav のロード
dr_libs
https://github.com/mackron/dr_libsで読んでもいいかもしれません.
Permission は?
audio を鳴らすだけなら, AndroidManifest.xml での permission 設定(+ アプリ側での permission request)は不要です.
マイクから録音するときは permission が必要になります.