-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.xml
2166 lines (2166 loc) · 498 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Androg</title><link>https://kwmt27.net/post/</link><description>Recent content in Posts on Androg</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Mon, 08 Jan 2024 17:30:00 +0900</lastBuildDate><atom:link href="https://kwmt27.net/post/index.xml" rel="self" type="application/rss+xml"/><item><title>2024年の目標</title><link>https://kwmt27.net/2024/01/08/new-years-resolution/</link><pubDate>Mon, 08 Jan 2024 17:30:00 +0900</pubDate><guid>https://kwmt27.net/2024/01/08/new-years-resolution/</guid><description>昨年までももちろん頑張ってきたつもりですが、現職が2年を過ぎたところで、ちょっと自分に甘えてるところありそうだなと思い、今年は気合いを入れ直すためにも目標を立てて公開することにしました。
英語発音を良くしたい英語は単語と単語がくっついて発音されたり、単語のアルファベットの単体の発音が変わるようにきこえることがある(たとえば、tはティー と発音すると教わってきたが、下の動画のように waterの場合は dに近い発音に変わる)と思うのですが、このことで簡単な単語でも聞き取ることができない(単語単語をはっきり言ってもらうと理解できる状態)という課題が数年続いていました。
自分の考えとしては、聞く練習をするよりも、自分の発音を流暢に話せるようになることでリスニングも良くなると信じています。 発音を中心に勉強してよくしていきたいと思う。
1年後目標TODO
12月にはペラペラになる 半年目標TODO
6月までに 3ヶ月後目標TODO
1ヶ月後目標TODO
1月中 ブログをたくさん書く昨年までは既知で広まってるようなことは書くと雑音になるだけなので書かなくていいやって思ってたのですが(つまり、自分が知ってることはみんなも知ってると同義な気がする)、以下のメリットがあるので今年は書いていこうと思います。
自分が知ってることでも頭の中にあるだけの状態だと、あとで自分も忘れるので、備忘録として有意義ななず。 自分の言葉で文書にすることで、まいかい口頭で教えていたのを、記事を共有することで伝えやすくなる 記事にまとめると正しい情報を書く必要があるので、少し曖昧だったこととが鮮明になり勉強になる 書く内容についての方針 どんな些細なことでもメモ程度でいいから書いて公開する 技術記事はzennにかく クラフトビールについてや、写真つきのさっと書きたいことが出てきたらnoteにかく クラフトビールを飲み行ったときの紹介。 どこにいったか、なにを飲んだか、雰囲気どうだったかとか たとえば地域ごとにまとまってると良さそうとかはありかも。 資産運用の見直し新NISAを始める早く始めるほど良いので、1月中には開始したい。 NISA口座は開設しているので、あとはどれを買うか決めるだけなはず。
Bitcoinの見直し conicheckのつみたてが気になっている。 bitflyerでも買っていた気がするが、確認する。 最低でも1曲は作曲したい昨年10月ぐらいからとても曲をつくりたくなった。 前々から音楽っていいなぁとは思っていて、電子ピアノを誕生日プレゼントに貰ったので、作曲していきたい。 方針はコード進行というのをまずは作るのが良いらしく、それが作れるようになりたい。
月間目標TODO
月間目標を決めるのをまずは目標とする。
体力あげる 体重が理想よりも+10kg(1年間で+8kg)増えてるので、理想に近づけたい。 体力の衰えはあまり感じないが、いずれ確実に衰えていくはずなので、体力を向上したい。 そのためには、これまでマラソンを走ってるときは調子良かった気がするので、マラソンを走れるようにすることにする。
さっそく4月のハーフマラソンに申し込んだので、完走できるように準備していきたい!
https://akabane-marathon.tokyo/sakura/
残り88日</description></item><item><title>2021年振り返り</title><link>https://kwmt27.net/2021/12/31/looking-back-2021/</link><pubDate>Fri, 31 Dec 2021 23:59:00 +0900</pubDate><guid>https://kwmt27.net/2021/12/31/looking-back-2021/</guid><description>はじめに昨年に引き続き8回目の振り返りを書くぞ!
2020年の目標達成状況 ❌ やっぱりGoogle IOなどを英語でちゃんと理解したいので、英語の発音をちゃんと理解できるようになりたい。 英語の勉強という勉強はやってない気がします。英語のYoutubeはいくつか見ましたが、英語の勉強というより動画の内容重視で見たので、勉強はしてないです。 趣味趣味アプリではQRコードリーダーを公開していますが、それをJetpack Composeで置き換えたりしてました。まだ全部ではないですが、カメラ部分はCameraXとJetpackComposeの組み合わせてです。
仕事関連Android今年も大半はAndroid開発をやっていました。 1月の最初の1週間ぐらいですがP社さんで、Android Studio4.1対応、targetSdkVersion 30対応や各種ライブラリのバージョンアップ、動いていなかったPlayStoreやDeployGateへの配信まわりのCI(Bitrise)整備をやりました。このあたりはよくやってることですが、動かないのを動くようにできたときは、いつになってもやっぱ嬉しいものがありますね。
あと残りは11月末までは昨年に引き続きT社のアプリ開発とアプリの一部をSDKとして提供するためのSDK開発をやらせて頂きました。主にアプリ開発よりSDK開発が多かったように思います。
SDKの開発方針としてはアプリがモノモジュールだったので、SDKとして切り出したい機能をマルチモジュール化して、そのモジュールと関連モジュールをmavenにpublishするという方式をとっています。(そのため、依存はバリバリあるのは問題だと認識しているのですが、仕方なく、、という状況です。)マルチモジュール化したり、モジュールをフレーバーごとに切り替えれるようにしたり、mavenにpublishできるようにしたりする仕組みを作ったりしてました。いまではテストしか使われないモジュールも含めて23個のモジュールがあります。モジュール分割やmavenへのpublishに関しては別途記事を書けるといいなと思っています。
別れと出会い今年は別れと出会いが多かった年になりました。 一緒にAndroidチームとして活躍していた方が3月末に1名、4月中旬に1名、卒業することになりました。12月には1名プロジェクトに参加して頂きました。また、11月には6名の方との技術面接の面接官をさせて頂き、そこでしっかり一人ひとりの方との出会いに感謝しながら向き合いました。 本業以外では、多くの企業様とカジュアル面談をさせていただきました。最初は副業を考えていたからです。そのときにも多くの出会い・再会がありました。
転職上で11月末までは昨年に引き続きT社のアプリ開発と言ったのは、11月末でtechveinを退職したからです。12月からAppBrewというLIPSを開発している会社に転職しました。 現在はLIPSサービスのグロースを担当しています。ユーザーのデータを見て検証したり、Android,iOS,サーバーサイドの開発を担当しています。東京にある会社ですが、大阪でフルリモートさせてもらっています。詳しくはまたどこかでまとめたいと思いますが、AppBrewに興味があればぜひ話をしましょう。いろんな職種で募集しています。 https://herp.careers/v1/appbrew
さいごに今年一年を表す漢字一文字とは?「謝」だと思います。 Android開発もtechリードとして、技術的に挑戦し、やりたいことをやらせてもらいましたので、とても感謝しています。 多くの人との出会いがあり、僕と関わってくれた方に感謝です。
今年もお世話になりました。来年もよろしくおねがいします!</description></item><item><title>Camera2APIでカメラプレビュー中に光センサーの値によってライトを自動でON/OFFにする</title><link>https://kwmt27.net/2021/07/30/android-camera2-light-on-by-light-sensor/</link><pubDate>Fri, 30 Jul 2021 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2021/07/30/android-camera2-light-on-by-light-sensor/</guid><description>はじめに Camera2APIを使って、カメラプレビュー中に(フラッシュではなく)ライトをONにできるのか? 周りが暗くなったら自動でライトをONにできるか? というのが気になって調べたのでメモしておく。
camera-samplesをベースに試した全体的なコードはこちら。 https://github.com/kwmt/camera-samples/pull/1/
1. Camera2APIを使って、カメラプレビュー中に(フラッシュではなく)ライトをONにできるのか?調べている中で、ライトのことをTorch Modeというらしいことを知った。
まず目に入ったのが、CameraMangaer#setTorchModeというメソッドで、これを(ドキュメントを読まずに^^;)試してみたら(カメラプレビュー中にコールする)、CAMERA_IN_USEという例外がスローされてしまう。
これはよくよくドキュメントを見ると
Set the flash unit&rsquo;s torch mode of the camera of the given ID without opening the camera device.
カメラデバイスを開かずに、指定されたIDのカメラのフラッシュユニットのトーチモードを設定します。
とあり、カメラプレビュー中ということはカメラをopenしている状態なので、openしてない場合に使えるメソッドであることがわかった。
別の方法を検討する。
こちらのstackoverflowで次のようなことを見つけた。 https://stackoverflow.com/a/57331014/2520998
Once the camera is open, you can use FLASH_MODE and set it to TORCH in your preview capture request. This means you need to keep AE_MODE to either ON or OFF, not one of the FLASH modes, so that auto-exposure isn&rsquo;t controlling the flash.</description></item><item><title>Jetpack ComposeでCameraXを実装する</title><link>https://kwmt27.net/2021/06/12/jetpack-compose-camerax/</link><pubDate>Sat, 12 Jun 2021 21:25:00 +0900</pubDate><guid>https://kwmt27.net/2021/06/12/jetpack-compose-camerax/</guid><description>はじめにcomposeバージョンは下記です。
Jetpack ComposeでのCameraXの実装を試したのでメモしておきたいと思います。 下の動画のようなイメージです。
ソースはGitHubにおいてます。 https://github.com/kwmt/JetpackComposePlayGround/tree/main/camerax/src/main/java/net/kwmt27/camerax
実行するときはConfigurationをcameraxを選択してから実行してみてください。
CameraXはAndroidViewを使う現在のところ、CameraXを使うにはAndroidViewを使うしかなさそうです。 以下のようにしました。
usecaseをバインドするusecaseをバインドしてるところは下記のところです。 使用しているUseCaseは、Preview、ImageAnalysisです。 この部分はいままでのcomposeを使わない場合と同じですね。
RuntimePermissionの実装カメラはもちろんRuntimePermissionの実装が必要でそれは次のようにやっています。
まず、カメラパーミッションが拒否されたときの画面を作成します。
このとき、設定画面にstartActivityResultで行って、戻ってきたときのイベントを伝えるために callback: () -&gt; Unitを渡していますので、設定画面から戻ってきたら handler.requestがよばれます。
handlerはPermissionHandlerという自前のクラスを作っていて、そこでカメラパーミッションが許可されてなければ、設定画面に遷移するし、許可されていれば、onGrantedというFlowに通知します。
以上です。</description></item><item><title>Android targetSdkVersionを28から30への変更したときのメモ</title><link>https://kwmt27.net/2021/06/12/android-update-targertsdk-from-28-to-30/</link><pubDate>Sat, 12 Jun 2021 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2021/06/12/android-update-targertsdk-from-28-to-30/</guid><description>Activityエラー内容e: /Users/kwmt/work/personal/QRCodeReader/core/presentation/src/main/java/net/kwmt27/presentation/MainActivity.kt: (61, 5): &#39;onRestoreInstanceState&#39; overrides nothing 原因onRestoreInstanceStateメソッドの引数のsavedInstanceStateに@NonNullアノテーションがついたため、 protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState)
対策- override fun onRestoreInstanceState(savedInstanceState: Bundle?) { + override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) 該当箇所 API level 28 https://cs.android.com/android/platform/superproject/+/android-9.0.0_r8:frameworks/base/core/java/android/app/Activity.java;bpv=1;bpt=1;l=1131
API Level 29 https://cs.android.com/android/platform/superproject/+/android-10.0.0_r30:frameworks/base/core/java/android/app/Activity.java;l=1566
ConnectivityManagerエラー内容e: /Users/kwmt/work/personal/QRCodeReader/core/presentation/src/main/java/net/kwmt27/presentation/WifiLifeCycle.kt: (66, 17): &#39;onAvailable&#39; overrides nothing e: /Users/kwmt/work/personal/QRCodeReader/core/presentation/src/main/java/net/kwmt27/presentation/WifiLifeCycle.kt: (71, 17): &#39;onLost&#39; overrides nothing 原因これもNonNullアノテーションがついたため
対策該当箇所 onAvailable https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/net/ConnectivityManager.java;l=3409?q=ConnectivityManager&ss=android%2Fplatform%2Fsuperproject
onLost https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/net/ConnectivityManager.java;l=3449?q=ConnectivityManager&ss=android%2Fplatform%2Fsuperproject
ClipboardManagerエラー内容e: /Users/kwmt/work/personal/QRCodeReader/core/presentation/src/main/java/net/kwmt27/presentation/common/Navigator.kt: (41, 9): Val cannot be reassigned val clipboardManager = fragment.context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager ?: return clipboardManager.</description></item><item><title>Jetpack Composeでインクリメンタルサーチ(SearchBar UI)を実装するには</title><link>https://kwmt27.net/2021/05/15/jetpack-compose-searchbar/</link><pubDate>Sat, 15 May 2021 13:20:00 +0900</pubDate><guid>https://kwmt27.net/2021/05/15/jetpack-compose-searchbar/</guid><description>はじめにcomposeバージョンは 1.0.0-beta04 です。
検索入力欄に検索した文字列を入れるとリストが絞り込まれる、いわゆるインクリメンタルサーチを実装したいとおもいます。下の動画のようなイメージです。
SearchBarのUIを作るには? だいたいこんな感じで作れます。
ROOMで部分検索するには@Dao interface QrResultDao { @Query(&#34;SELECT * from qr_results WHERE text LIKE &#39;%&#39; || :query || &#39;%&#39; &#34; + &#34;OR name LIKE &#39;%&#39; || :query || &#39;%&#39; ORDER BY updated_at DESC&#34;) suspend fun search(query: String): List&lt;QrResultEntity&gt; } こんな感じ。
ViewModelの実装は SearchQrResultUseCaseを使ってますが、基本的にはDaoのsearchまでの橋渡しなので省略。型変換とかはしています。
SearchBarとリストをくっつけると listを監視して、検索されたらUIに通知するみたいな感じです。
以上です。</description></item><item><title>コールバックをFlowに変換するには</title><link>https://kwmt27.net/2021/04/29/coroutine-flow-callbackflow/</link><pubDate>Thu, 29 Apr 2021 13:00:00 +0900</pubDate><guid>https://kwmt27.net/2021/04/29/coroutine-flow-callbackflow/</guid><description>はじめにinterface OnChangeListener { fun onChange() } のようなコールバックを、Flowに変換するにはどうすればいいかを調べました。
RxJavaでいうところ、Observable.create のようなことを実現するにはどうすればいいかという記事です。
結論callbackFlowというAPIがcoroutineに用意されてるので、それを使うと良さそうです。
これは、cold flowを生成します。つまり、collectされるまで動きません。
サンプルサンプルを書いてみました。
flowFlow関数で、callbackFlowを使ってコールバックからFlowに変換しています。 OnChangeListener#onChangeの実装でofferを使用してチャンネルに追加しています。 容量がいっぱいの場合は例外がなげられるとのこと。
awaitClose でunregsiterやcancel処理を実装する必要があります。 これを実装しなければ、実行時に
IllegalStateException: &lsquo;awaitClose { yourCallbackOrListener.cancel() }&rsquo; should be used in the end of callbackFlow block.
というエラーがでます。(感想ですが、クローズ処理を忘れないので、良い仕組みだと思います!)
callbackからflowに変換できたので、あとはcollectしてあげるだけです。 このサンプルでは、1秒ごとにログに値が出力されます。
onchange: 1 onchange: 2 onchange: 3 onchange: 4 onchange: 5 onchange: 6 onchange: 7 ...</description></item><item><title>Jetpack Compose PlayGround</title><link>https://kwmt27.net/2021/03/28/jetpack-compose-playground/</link><pubDate>Sun, 28 Mar 2021 19:00:00 +0900</pubDate><guid>https://kwmt27.net/2021/03/28/jetpack-compose-playground/</guid><description>はじめに※こちらは更新予定です。
確認環境は下記です。
compose_version: 1.0.0-beta02 kotlin version: 1.4.31 Android Studio version: Android Studio Arctic Fox | 2020.3.1 Canary 12 確認したコードはGitHubにおいてます。
https://github.com/kwmt/JetpackComposePlayGround
縦方向(Vertical)のリスト表示するには縦方向(Vertical)のリストを表示するには、LazyColumn を使います。
import androidx.compose.foundation.lazy.LazyColumn @Composable fun SampleList() { LazyColumn { items(5) { index -&gt; // 各要素で表示したいUIを書く。 ListItem(index) } } } 多くのアイテムやサイズのわからないリストを表示する必要がある場合、Columnのようなレイアウトを使用すると、全てのアイテムが表示されるかどうかに関わらずレイアウトされるので、パフォーマンスに影響があります。 LazyColumnやLazyRowは表示されるアイテムのみをレイアウトするコンポーネントになります。(RecyclerViewと同じ概念)
ついでに、リストの各要素はComposableListItemは自作のComposable関数で、リストアイテムのUIを定義しています。
@Composable fun ListItem(index: Int = 0) { Column { Box( modifier = Modifier .height(200.dp) .background(Color.Blue) .fillMaxWidth() ) { Text( modifier = Modifier.align(Alignment.Center), text = &#34;index: $index&#34;, style = TextStyle(color = Color.</description></item><item><title>Jetpack Compose Dev Challenge Week3で学んだことまとめ</title><link>https://kwmt27.net/2021/03/15/jetpack-compose-dev-challenge-week3/</link><pubDate>Mon, 15 Mar 2021 12:00:00 +0900</pubDate><guid>https://kwmt27.net/2021/03/15/jetpack-compose-dev-challenge-week3/</guid><description>jetpack compose
全体にかかわること(テーマなど)背景を入れるにはSurface(color = MaterialTheme.colors.primary) が大事
Welcome画面Login画面Textの途中でリンクを入れるhttps://stackoverflow.com/questions/65567412/jetpack-compose-text-hyperlink-some-section-of-the-text
EditTextの枠線の色を変更するにはoutlinedTextFieldColorsの部分
OutlinedTextField( modifier = Modifier .height(56.dp) .fillMaxWidth(), value = &#34;&#34;, onValueChange = { /*TODO*/ }, placeholder = { Text( text = &#34;Password (8+ characters)&#34;, style = DevChallengeTheme.typography.body1, color = DevChallengeTheme.colors.textBody1, ) }, colors = outlinedTextFieldColors( cursorColor = DevChallengeTheme.colors.textBody1, focusedBorderColor = DevChallengeTheme.colors.textBody1.copy(alpha = ContentAlpha.high), unfocusedBorderColor = DevChallengeTheme.colors.textBody1, ), singleLine = true, ) 検索ボックスを作成(SearchBar)ここが参考になりそう。 https://github.com/android/compose-samples/blob/main/Jetsnack/app/src/main/java/com/example/jetsnack/ui/home/search/Search.kt
ホーム画面###BottomNavigation
https://developer.android.com/jetpack/compose/navigation#bottom-nav https://proandroiddev.com/implement-bottom-bar-navigation-in-jetpack-compose-b530b1cd9ee2
BottomItemを切り替えまくっても、バックで、startDestinationに戻る(cart -&gt; Profileと遷移してバックし場合cartに戻っていたのをhomeに戻るようにする) navController.navigate(screen.route) { // BottomItemを切り替えまくっても、バックで、startDestinationに戻る popUpTo = navController.</description></item><item><title>Animation and Jetpack Compose</title><link>https://kwmt27.net/2021/03/06/jetpack-compose-animation/</link><pubDate>Sat, 06 Mar 2021 12:30:00 +0900</pubDate><guid>https://kwmt27.net/2021/03/06/jetpack-compose-animation/</guid><description>はじめにJetpack Compose: Animation
単一アニメーション@Composable fun AnimateAsStateDemo() { var blue by remember { mutableStateOf(true) } val color = if (blue) Blue else Orange Column { Button(onClick = { blue = !blue }) { Text(text = &#34;CHANGE COLOR&#34;) } Spacer(modifier = Modifier.height(16.dp)) Box( modifier = Modifier .size(128.dp) .background(color) ) } } この例では、BooleanのStateの値blueを持っていて、 ボタンをクリックするとそのStateは反転します。
BoxのカラーがそのBooleanの状態によって切り替わります。
カラーの変更部分をanimateColorAsSate関数でラップすることで、簡単にアニメーションすることができます。(デフォルトはフェードアニメーションなのかな?)
val color by animateColorAsState(if (blue) Blue else Orange) (初回だけアニメーションしてないように見える)
複数のアニメーションを同時に実行したい以下はBoxのサイズとカラーの値を同時に変更しています。まだアニメーションはしていません。
private enum class BoxState { Small, Large } @Composable fun UpdateTransitionDemo() { var boxState by remember { mutableStateOf(BoxState.</description></item><item><title>State and Jetpack Compose</title><link>https://kwmt27.net/2021/03/06/jetpack-compose-state/</link><pubDate>Sat, 06 Mar 2021 12:30:00 +0900</pubDate><guid>https://kwmt27.net/2021/03/06/jetpack-compose-state/</guid><description>はじめに基本的には、書きを参考に自分なりにまとめたものです。
State and Jetpack Compose Jetpack Compose 入門 composeバージョンは 1.0.0-beta01 です。 StateComposeでは状態をStateというもので扱います。
外から変更可能な MutableStateと外からは変更できないStateがあります。
@Stable interface MutableState&lt;T&gt; : State&lt;T&gt; { override var value: T operator fun component1(): T operator fun component2(): (T) -&gt; Unit } @Stable interface State&lt;T&gt; { val value: T } var expanded by remember { mutableStateOf(false) } mutableStateOfで新しいBooleanのStateを作成しています。
Buttonのクリックイベントの中でその値を変更しています。
onClick = { expanded = true } Stateを使っている箇所が再描画されます。
Composable関数は必要に応じて再実行されます。これをrecomposition(再構成) とよびます。
stateを宣言する時、by はKotlinのデリゲートプロパティという機能。
byを使わず =を使うこともできますが、expanded.value = trueのように.valueをつける必要があります。
var expanded = remember { mutableStateOf(false) } rememberrememberもComposable関数です.</description></item><item><title>Layout in Jetpack compose</title><link>https://kwmt27.net/2021/02/07/jetpack-compose-layout/</link><pubDate>Sun, 07 Feb 2021 14:30:00 +0900</pubDate><guid>https://kwmt27.net/2021/02/07/jetpack-compose-layout/</guid><description>はじめに基本的には、こちらのコードラボをメモしたものです。 https://developer.android.com/codelabs/jetpack-compose-layouts
試したことはこちらに置いてます。
縦に並べるにはColumn を使う
Column { Text(&#34;Alfred Sisley&#34;, fontWeight = FontWeight.Bold) Providers(AmbientContentAlpha provides ContentAlpha.medium) { Text(&#34;3 minutes ago&#34;, style = MaterialTheme.typography.body2) } } 横に並べるにはRowを使う
Row { Surface( modifier = Modifier.preferredSize(50.dp), shape = CircleShape, color = MaterialTheme.colors.onSurface.copy(alpha = 0.2f) ) { // image goes here } Column { Text(&#34;Alfred Sisley&#34;, fontWeight = FontWeight.Bold) Providers(AmbientContentAlpha provides ContentAlpha.medium) { Text(&#34;3 minutes ago&#34;, style = MaterialTheme.typography.body2) } } } ここでは、円形画像のプレースホルダーを作るためにSurfaceを使って、先程のColumnと横に並べています。
プレースホルダーとテキストの間に、パディングをいれるには- Column { + Column( + modifier = Modifier.</description></item><item><title>Jetpack ComposeでBitmapを表示するには</title><link>https://kwmt27.net/2021/01/31/jetpack-compose-about-bitmap/</link><pubDate>Sun, 31 Jan 2021 22:50:00 +0900</pubDate><guid>https://kwmt27.net/2021/01/31/jetpack-compose-about-bitmap/</guid><description>Jetpack ComposeでBitmapを表示するには、Image関数を使い、引数にBitmapを渡せばいいのですが、そのときImageBitmapに変換する必要があるようで、 そのためにasImageBitmap()という拡張関数が生えてるので、それを使えばよさそうです。
import androidx.compose.foundation.Image import androidx.compose.ui.graphics.asImageBitmap Image( bitmap.asImageBitmap(), )</description></item><item><title>Jetpack Composeでダークテーマ設定変更によるステータスバーカラーの切り替え方</title><link>https://kwmt27.net/2021/01/24/jetpack-compose-about-swtich-status-bar/</link><pubDate>Sun, 24 Jan 2021 22:50:00 +0900</pubDate><guid>https://kwmt27.net/2021/01/24/jetpack-compose-about-swtich-status-bar/</guid><description>はじめにAndroid端末でダークテーマの切り替えをしたとき、Jetpack Composeでステータスバーカラーの切りかえをする方法を調べたので、メモ。
方法Jetpack Composeのサンプル、Jetsnackのコードを参考にしています。
interface SystemUiController { fun setStatusBarColor( color: Color, darkIcons: Boolean = color.luminance() &gt; 0.5f ) } fun SystemUiController(window: Window): SystemUiController { return SystemUiControllerImpl(window) } /** * An [androidx.compose.runtime.Ambient] holding the current [SysUiController]. Defaults to a * no-op controller; consumers should [provide][androidx.compose.runtime.Providers] a real one. */ val SysUiController = staticAmbientOf&lt;SystemUiController&gt; { FakeSystemUiController } private class SystemUiControllerImpl(private val window: Window) : SystemUiController { override fun setStatusBarColor( color: Color, darkIcons: Boolean ) { window.</description></item><item><title>Jetpack ComposeのAmbientについて</title><link>https://kwmt27.net/2021/01/17/jetpack-compose-about-ambient/</link><pubDate>Sun, 17 Jan 2021 22:50:00 +0900</pubDate><guid>https://kwmt27.net/2021/01/17/jetpack-compose-about-ambient/</guid><description>はじめにJetpack Composeでステータスバーのカラーを変更するにはどうすればいいか調べていたら、ambientというキーワードが出てきて、なにものかがわからなかったのでメモです。
AmbientとはAmbientとは、FlutterのProviderのようなものです。
サンプルコードを見たほうがわかりやすいと思いますので、見てみましょう。
// ① Ambientを作ります。 val ActiveUser = ambientOf&lt;User&gt; { error(&#34;No active user found!&#34;) } @Composable fun App(user: User) { // ② `Providers`コンポーネントを使用して、ambinentに値を渡します。 Providers(ActiveUser provides user) { SomeScreen() } } // ③ツリーの間にあるコンポーネントはAmbientの値を知る必要はありません。 @Composable fun SomeScreen() { UserPhoto() } @Composable fun UserPhoto() { // ④ `current`プロパティを使うことでAmbinentの値を使うことができます。 val user = ActiveUser.current ProfileIcon(src = user.profilePhotoUrl) } もしAmbientを使わなければ、コンポーネントに引数で渡していくことになり、渡された値が必要のないコンポーネントまで余計なものを知る必要が出てきてしまいます。
ambientOfとstaticAmbinentOfの違いについてJetpack Compose - What is the Difference Between ambientOf and staticAmbientOf こちらが詳しいです。
各ドキュメントはこちら
ambientOf staticAmbientOf テーマの変更、端末の言語設定など変更機会が少なく、読み込みが書き込みより多い場合に staticAmbientOfを使うそうです。</description></item><item><title>Jetpack Composeを既存のアプリと共存するには</title><link>https://kwmt27.net/2021/01/16/jetpack-compose/</link><pubDate>Sat, 16 Jan 2021 22:50:00 +0900</pubDate><guid>https://kwmt27.net/2021/01/16/jetpack-compose/</guid><description>現象次のエラーが出た。
Execution failed for task &#39;:core:presentation:prepareDebugKotlinCompileTask&#39;. &gt; Could not resolve all files for configuration &#39;:core:presentation:kotlin-extension&#39;. &gt; Could not find androidx.compose:compose-compiler:1.0.0-alpha08. Searched in the following locations: - https://dl.google.com/dl/android/maven2/androidx/compose/compose-compiler/1.0.0-alpha08/compose-compiler-1.0.0-alpha08.pom - https://jcenter.bintray.com/androidx/compose/compose-compiler/1.0.0-alpha08/compose-compiler-1.0.0-alpha08.pom - https://www.jitpack.io/androidx/compose/compose-compiler/1.0.0-alpha08/compose-compiler-1.0.0-alpha08.pom - https://oss.sonatype.org/content/repositories/snapshots/androidx/compose/compose-compiler/1.0.0-alpha08/compose-compiler-1.0.0-alpha08.pom - https://kotlin.bintray.com/kotlinx/androidx/compose/compose-compiler/1.0.0-alpha08/compose-compiler-1.0.0-alpha08.pom Required by: project :core:presentation Possible solution: - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html 原因Android Gradle Pluginのバージョンが古かったため
対策 classpath(&#34;com.android.tools.build:gradle:4.1.0&#34;) + classpath(&#34;com.android.tools.build:gradle:7.0.0-alpha02&#34;) -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-all.zip 現象AGPのバージョンを7.0.0にするとGradle Syncで以下のエラーが出る classpath(&ldquo;com.android.tools.build:gradle:7.0.0-alpha02&rdquo;)
Unable to find method &#39;&#39;void com.android.build.gradle.internal.dsl.BaseAppModuleExtension.onVariants(kotlin.jvm.functions.Function1)&#39;&#39; &#39;void com.</description></item><item><title>2020振り返り</title><link>https://kwmt27.net/2020/12/31/looking-back-2020/</link><pubDate>Thu, 31 Dec 2020 23:59:00 +0900</pubDate><guid>https://kwmt27.net/2020/12/31/looking-back-2020/</guid><description>昨年は振り返る時間がなくて振り返りを書いてないが、一昨年まで書いていたので1年越し7回目の振り返りを書いておこう。
2019年の目標達成状況2018年末に立てた目標だが、できているか確認しておこうと思う。
❌ 年収を倍にする!
2020年は3回チャンスがあったと思うがどれもものにできませんでした。 転職だけが年収を倍にできるというわけではないと思いますが、3回ともお声がけ頂いてどのチャンスも逃してしまったのはまだまだ頑張りが足りないと思いました。 1回目は、2020年1月。 それはL社のプログラミングの実技試験があった。転職の試験だった。2019年末からその試験に向けてコンピュータ・サイエンスに関する勉強をしていた。具体的にはLeetCode を数問解いただけではあるのですが。この試験は正直難しかった。ただいくつかは手応えがあったのですが、このあとのオンライン面接で、結果0点といわれた。いい感じなところもあったらしいが、おそらkUnit Testを実行した結果failしていたんだと思う。 要因としては、競技プログラミングが仕事としてやりたいことではないと思いながらやっていたのがいけなかったと思う。競技プログラミングでアルゴリズムを理解したいというのはあるが、急には難しいので徐々にやっていければいいと思う。一回解くのに1,2時間(それ以上かも?)は余裕でかかってしまうので、余裕があるときにやっていきたい。 2回目は2020年7月に知人からお誘いがありました。 が、その後連絡してません・・・。ちゃんとその企業を調べてから連絡しようと思ったのですが、あまり調べていないので。 3回目は2020年8月末に幼馴染からお誘いの連絡がきた。 こちらはその幼馴染と直接あって(福岡帰って)話を聞いたり、自分で調べたり、なんどかカジュアル面談がある中でチャレンジしてみたいと思い面接に進みましたが、結果はご縁がありませんでした。 こちらはかなり良い印象を持って頂いたと思っているので、とくにこちらがダメだったということがわからないのですが、ほんとうにポジションがなかったんだと信じたいと思います。 ❌ 英語をスムーズに話せるようなる!
今年は英語の勉強をしなかったと思う。 来年は発音を練習するために、耳から聞いた言葉をそのまま言う練習をしていきたい。 Google I/OなどのカンファレンスのYoutube聞いて、英語の発音に慣れたいと思う。 ❌ 海外カンファレンスに参加したい!
新型コロナウィルスという感染症が流行ったということもあり、海外カンファレンスがなくなったため、参加することありませんでした。 ✅ お腹を引っ込める!
2019年夏ぐらいから2020年夏ぐらいまでの1年間ほとんど毎日やりました。健康診断では腹部が4cm減ったのはよかったですが、夏にパタッとやめてしまいました。 ✅ クラフトビールに関するアプリを作る
デザインをFigmaに描いて、Nuxt.jsで形だけはできた状態です。APIはGAE+Ktor+Kotlinで作成中で止まっています。完成していませんが進めたので、✅付けました。 仕事関連2020年は1年中T社アプリ開発に携わらせていただきました。 Androidアプリを新規リリースしました。 そのアプリの機能追加&改善の年でした。 いままで受託してて、自分で課題見つけて改善できたのは初めてだったので、とても勉強させてもらいました。
いろいろダメなところありました。 チーム開発も初めてでした。 Tech リードとしてやらせてもらいました。 一人で書くコードと、チームの一員として書くコードは違うんやなということを思いました。 たとえば、Rxをつかててチェイン・チェイン・チェイン・チェイン・・・・とつなげるととてもかっこいいしスッキリ書けるけど、パット見た感じはなにやってるかわからない。 何やってるか名前を付けていくと他の人が読んでも わかりやすくなる気がしています。 質問されたときにTech リードとしてちゃんとこたえなくちゃいけないから、自分がわからないことはちゃんと調べます。 どんなにあいてからわからないと言われてもちゃんと向き合って答えます。
そんな開発をやってきました。
2021年はT社アプリはまだ続くと思います。
カメラまわりでまだ機種依存のような不具合がでてしまっているので、Camera2 からCameraXに乗り換えるのはありかもしれません。
他の技術も取りいれていきたいですね。 そのためにはキャッチアップしていかないと。
来年の目標 やっぱりGoogle IOなどを英語でちゃんと理解したいので、英語の発音をちゃんと理解できるようになりたい。 そのためには、何度も聞いてなれるしかないと思う。 まとめ</description></item><item><title>Python勉強</title><link>https://kwmt27.net/2020/12/26/python/</link><pubDate>Sat, 26 Dec 2020 19:24:00 +0900</pubDate><guid>https://kwmt27.net/2020/12/26/python/</guid><description>こちらをやるにあたってメモしていこうと思う。 https://qiita.com/yoshizaki_kkgk/items/79f4056901dd9c059afb
仮想通貨のデータを取得するPoloniexを使ってBitcoinのデータを取得することが出来る。
requirements.txtに以下のように追加した。
# 仮想通貨データを取得するPoloniexのwrapper # https://github.com/s4w3d0ff/python-poloniex poloniexapi==0.5.7 使い方の例として、
from poloniex import Poloniex polo = Poloniex() json = polo.returnChartData(currencyPair=&#39;USDT_BTC&#39;, period=polo.DAY, start=time.time() - polo.DAY * 500, end=time.time()) このように書き、これで
1日間隔で、現在から500日前までのUSDT_BTCのJSON形式のデータを取得することができる。 JSONをPandasに変換するPandasとば、データ解析を支援する機能を提供するライブラリとのこと(https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a) データを扱うにはPandasを使うのが扱いやすいとのことで、JSONからPandasのDataFrameという型に変換するには、
import pandas as pd df = pd.DataFrame(json) とするだけで良い。
ちなみに、下記のように書くとdate,low,high,open,closeのデータなどが取れる。
print(df.loc[0:9,[&#39;date&#39;, &#39;low&#39;, &#39;high&#39;, &#39;open&#39;, &#39;close&#39;]]) date low high open close 0 1565758004 10052.17796145 10052.17796145 10052.17796145 10052.17796145 1 1565827200 9523.4400982 10445.99999999 10054.59980013 10311.39375692 2 1565913600 9750 10520 10305.65100999 10349.64220512 3 1566000000 10001.</description></item><item><title>macOSのダイアログでフォーカスをタブで移動させるには</title><link>https://kwmt27.net/2020/12/13/shortcut-for-moving-daialog-focus/</link><pubDate>Sun, 13 Dec 2020 19:24:00 +0900</pubDate><guid>https://kwmt27.net/2020/12/13/shortcut-for-moving-daialog-focus/</guid><description>macOSで保存していないときなど下のようなダイアログが出ると思いますが、saveにフォーカスがあたっていてEnterキーを押すと保存されてしまいます。 しかし保存したくないときはDont't Saveをクリックすればいいのですが、マウスやトラックパッドを使わずキーボードだけでDont't Saveを押したい場合ないですか? それがしばらく分からなかった(調べようともしてませんでしたが)のですが、ようやく調べたのでメモしておこうと思います。
System Preferences &gt; Keyboard -&gt; Shortcutタブ といき、下部に
Use Keyboard navigation to move focus between controls というチェックボックスがあるので、そこをチェックするだけです。
これでダイアログが出ている状態でタブを押すとフォーカスが移動してくれて、冒頭の例だとDont't Saveの位置にタブで移動し、Enterキーを押せばキーボードだけで保存しないようにできます。
ちなみに、確認したOSはBig Surです。</description></item><item><title>Flutterでバックボタンの色を変更するには</title><link>https://kwmt27.net/2020/05/06/how-to-change-backbutton-color/</link><pubDate>Wed, 06 May 2020 13:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/05/06/how-to-change-backbutton-color/</guid><description>FlutterでたとえばNavigator.pushした先の画面で、バックボタンを表示しているとき、そのボタンのカラーを変えたい。
たとえば、下図の例では白色に変えていますが、このようにしたいという話です。
何もしなかったら、下図のように黒色になります(正確には primaryColor によって、黒か白か決まります1)。
その色を変更する方法として、AppBar に iconTheme を設定できますので、そこに次のようにIconThemeData を使って変更したいカラーを設定します。
return Scaffold( appBar: AppBar( title: Text(&#34;プロフィールの編集&#34;), iconTheme: IconThemeData(color: Colors.white), // ここで色を決めることができる。 ただ、これだと、画面ごとに毎回設定しなくてはならないので、アプリ全体として設定したくなると思います。それをするには、
MaterialApp( theme: ThemeData( primaryColor: AppColors.appBar, primaryTextTheme: TextTheme(title: TextStyle(color: Colors.white)), primaryIconTheme: IconThemeData(color: Colors.white), // ここを追加 のように、MaterialApp の theme に ThemeData を設定できますが、さらに ThemeData の primaryIconTheme でバックボタンのカラー設定することで、アプリ全体のカラーを変更することができます。
ちなみに、両方(MaterialAppでprimaryIconThemeと、AppBarでiconThemeの両方)を設定していた場合、AppBarで設定したiconThemeが優先されます。
theme_data.dart を参照ください。primaryIconTheme は primaryIsDark によって白か黒かを決めていて、primaryIsDarkは estimateBrightnessForColor(primaryColor) と primaryColorによって決まっているのが分かるかと思います。&#160;&#x21a9;&#xfe0e;</description></item><item><title>Flutterでの画面遷移まとめ</title><link>https://kwmt27.net/2020/03/26/summary-of-screen-transitions-in-flutter/</link><pubDate>Thu, 26 Mar 2020 02:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/summary-of-screen-transitions-in-flutter/</guid><description>はじめに先日Flutter製チャットアプリを支える技術でチャットアプリを作ったときの内容を書いて今年は終わりかなと思っていたら、こちらの枠が空いていたので前回触れなかった画面遷移について書きたいと思います。
Flutterの画面遷移についてはNavigation &amp; routingを見ると基本的には良いと思います。
ですが、実際アプリを作った際にこれだけでは足りないと思いますので、画面遷移をiOS・Androidのそれぞれの動画+実装という形でまとめておきたいと思います。
別の画面に遷移したい iOS Android たとえば、ルーム一覧画面からパスを&quot;/rooms/&lt;roomId&gt;&ldquo;とするルーム詳細画面(RoomScreen)に遷移したいときは次のようにします。1
Navigator.push( context, MaterialPageRoute( settings: RouteSettings(name: &#34;/rooms/&lt;roomId&gt;&#34;), builder: (BuildContext context) =&gt; RoomScreen(roomId)), ); 前の画面に戻りたい iOS Android Navigator.pushを使って画面遷移したあと、左上のバックボタンをタップして戻る場合は特に処理は必要ありませんが、それ以外のボタンから戻りたい場合もあるかと思います。その場合は戻りたいタイミングで次のようにします。(上の動画では、下部のバツボタンをタップしています)
Navigator.pop(context); ダイアログを出したい iOS Android showDialogとAlertDialogの組み合わせです。AlertDialogの方のドキュメントにもサンプルが載っています。
Future&lt;bool&gt; showDialogMessage(BuildContext context, {String title, String message, bool isOkOnly = false}) { return showDialog&lt;bool&gt;( context: context, builder: (context) =&gt; _buildDialog(context, title, message, isOkOnly: isOkOnly), ); } Widget _buildDialog(BuildContext context, String title, String message, {bool isOkOnly = false}) { if (title == null &amp;&amp; message == null) { throw ArgumentError(&#34;titleとmessageのどちらともnullです。どちらかは指定してください。&#34;); } List&lt;Widget&gt; actions = List(); if (!</description></item><item><title>Flutter製チャットアプリを支える技術</title><link>https://kwmt27.net/2020/03/26/the-technology-behind-flutter-chat-app/</link><pubDate>Thu, 26 Mar 2020 02:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/the-technology-behind-flutter-chat-app/</guid><description>はじめに今年はGoogle I/Oに行ってFlutterを知って6月ぐらいからFlutterを触りだし、いろいろ勉強会に行ったりFlutter温泉に行ったり、今年の後半はFlutter三昧でした。
そんな中チャットアプリを作ったので、それぞれ機能をどのように実装したかコードを交えつつ少しずつご紹介したいと思います。
開発環境は下記のとおりです。
% flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel beta, v1.0.0, on Mac OS X 10.14.1 18B75, locale en-JP) [✓] Android toolchain - develop for Android devices (Android SDK 28.0.3) [✓] iOS toolchain - develop for iOS devices (Xcode 10.1) [✓] Android Studio (version 3.2) [✓] VS Code (version 1.29.1) [✓] Connected device (2 available) まずどんな機能を作ったか?大きく分けると次のようになるかなと思います。
会員登録・ログイン チャットルーム(以下、ルーム)作成できる ルーム一覧を見ることができる ルームでチャット(テキスト、画像の送信)ができる 既存のルームにユーザーが参加できる 自分のプロフィールを見ることができる アプリ内課金で定期購読できる それぞれ見ていきます。</description></item><item><title>dep(Go dependency tool)を自作ライブラリに使ってみた</title><link>https://kwmt27.net/2020/03/26/i-tried-to-use-dep-in-my-library/</link><pubDate>Thu, 26 Mar 2020 00:20:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/i-tried-to-use-dep-in-my-library/</guid><description>はじめに1個だけの外部ライブラリに依存している(超かんたんな)自作ライブラリgithub.com/kwmt/combineを例に、depコマンドを使ってみた内容をメモしておこうと思います。
基本的な使い方インストールと初期化depのインストールは、プロジェクトルートに移動して、go getします。
$ cd $GOPATH/src/github.com/kwmt/combine $ go get -u github.com/golang/dep/... 次のコマンドで初期化します。
$ dep init でgithubログインを促されましたが、manifest.jsonとlock.jsonが作成されます。1
このとき、すでに依存ライブラリを見つけてくれていて、下記のように依存ライブラリが記述されています。2
{ &#34;dependencies&#34;: { &#34;github.com/kwmt/go-utils&#34;: { &#34;branch&#34;: &#34;master&#34; } } } { &#34;memo&#34;: &#34;&#34;, &#34;projects&#34;: [ { &#34;name&#34;: &#34;github.com/kwmt/go-utils&#34;, &#34;branch&#34;: &#34;master&#34;, &#34;revision&#34;: &#34;7431874e8437574169c0fb50e811d790fc1ed2ab&#34;, &#34;packages&#34;: [ &#34;.&#34; ] } ] } 依存ライブラリのダウンロードここまでではまだ依存ライブラリはダウンロードされてないので、
$ dep ensure -update とします。するとvendorディレクトリが作成されて、そのなかに依存ライブラリがダウンロードされます
$ ls vendor/github.com/kwmt/ go-utils 状態を確認dep statusコマンドは、プロジェクトの依存関係の状態を見ることが出来ます。
$ dep status PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED github.com/kwmt/go-utils branch master branch master 7431874 7431874 1 おまけ-vオプションで詳細なログを出力$ dep init -v dep: Finding dependencies for &#34;github.</description></item><item><title>RxJavaのサンプルを作るにあたって、Androidアプリを作ってみた。</title><link>https://kwmt27.net/2020/03/26/to-make-a-sample-of-rxjava-i-tried-to-make-an-android-app/</link><pubDate>Thu, 26 Mar 2020 00:13:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/to-make-a-sample-of-rxjava-i-tried-to-make-an-android-app/</guid><description>最近RxJavaを使い始めたら、めちゃめちゃ便利!ということを知って、使い方のサンプルを書いておこうと、書きました。サンプルとして割りきってしまえば、これはこれでありなんだと思うんですが、実際はいろんなライブラリと組み合わせて使うわけで、たとえばRetrofitと一緒に使うのはどうするんだろうとか思って書き始めていたら、何かアプリを作ってみた方が実用的になるかもと思って、Androidアプリを作ってみました。
アプリの詳細はPlay Storeの説明を見ていただきたいのですが、簡単に言うと、リストをGithubAPIから取得して表示し、そのリストの各項目をタップすると詳細がみれるという、よくあるアプリです。
このアプリは、自分の実験アプリで、自分のなかで試してみたいことを試してみてます。
いままでMVCでコード書いてたのですが、MVPにしてみよう!とか、 Retrofit使ったことなかったので使ってみようとか、 RxBinding使ってスクロールの一番下で行ったら読み込んでみよう RecyclerViewで一部のitemを異なるviewTypeにしたい Firebase使ってみよう! wercker CIを使ってみようとか、 Google Play Developer Publishing APIを使ってPlay Storeに自動アップロードしてみようとか、 Retrolambdaを使わずにラムダ式が使える(一部だけ)ので使ってみようとか。 です。
最後のラムダ式を使うに関して、Retrolambdaを使わずラムダ式を使うには、Jackを有効にしないといけなくて、Jackを有効にすると、 Instant Run is disabled when Jack compiler is used. と表示されるようにInstant runが無効になってしまいますので、短く書けるのを取るかコンパイル速度を取るか、悩みどころです。いずれJackでもInstant runができることを期待しているので、コンパイル速度は諦めてます。
レポジトリhttps://github.com/kwmt/GitHubSearch
ちなみに、自分がRxJavaを使うと便利になった思うこと ModelからViewへの通知を今までObserverパターンを自作していたが、それが不要になった 連続して複数回APIを呼ぶなどするとコールバック地獄になるので読みにくくなってしまうのを、1回のコールバックで受けれるので読みやすくなった リスト操作やAPIコールをObservable(Stream)として同じように扱える ただnew Func1とか書きたくないから、早く世の中の端末がAndroid N以降になってくれないかな。
RxJavaの課題というか悩みどころ subscription はModelで持つべきか、Viewで持ったほうがいいか悩みます。 リスト操作はfor文使わなくてよくなったけど、全部が全部RxJavaを使うかどうか再利用の関係で悩みます。ユーティリティ系のクラスは別のプロジェクトでも使いまわせたりしますが、RxJavaでリスト操作してしまうとそのユーティリティを使うなら必ずRxJavaの導入が必要になってきます。RxJavaが導入されてないプロジェクトだったりすると、そのユーティリティクラスは使えないので、for文の方がいいんじゃないかと思ってしまいます。</description></item><item><title>Go Modulesで簡単バージョン管理</title><link>https://kwmt27.net/2020/03/26/easy-version-control-with-go-modules/</link><pubDate>Thu, 26 Mar 2020 00:12:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/easy-version-control-with-go-modules/</guid><description>はじめにgo1.11からGo Modulesというのがサポートされていたので、簡単に使い方をご紹介します。
これは簡単に言うとバージョン管理ツールです。 Go 1.11時点ではexperimentalで、最終的にGo1.13で取り込まれるようです。
package main import ( &#34;fmt&#34; &#34;rsc.io/quote&#34; ) func main() { fmt.Println(quote.Hello()) } という&quot;rsc.io/quote&quot;に依存したプログラムがあるとき、go buildとすると自動的にgo getしてくれるというものです。
使い方例として、GOPATHに次のプロジェクトを作成した前提で、使い方を見ていきます。
$ mkdir -p $GOPATH/github.com/kwmt/gomod-sample $ cd $GOPATH/github.com/kwmt/gomod-sample まず、go modコマンドというのがあるのですが、そのコマンドを使うためには、GO111MODULEという環境変数をonに設定する必要があります。
export GO111MODULE=on 次にgo mod initで初期化します。
% go mod init github.com/kwmt/gomod-sample go: creating new go.mod: module github.com/kwmt/gomod-sample すると、go.modというファイルが作成されます。
% ls go.mod ちなみに、go.modファイルの中身は下記のようになっています。
module github.com/kwmt/gomod-sample Quick Startにあるように、下記のような&ldquo;rsc.io/quote&rdquo;というライブラリに依存したプログラムhello.goを作成します。
% cat &lt;&lt;EOF &gt; hello.go package main import ( &#34;fmt&#34; &#34;rsc.io/quote&#34; ) func main() { fmt.</description></item><item><title>Androidプロジェクトの新規作成からプッシュ通知受信確認まで</title><link>https://kwmt27.net/2020/03/26/from-creating-a-new-android-project-to-confirming-receipt-of-push-notifications/</link><pubDate>Thu, 26 Mar 2020 00:11:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/from-creating-a-new-android-project-to-confirming-receipt-of-push-notifications/</guid><description>はじめに1年ぐらい前にプッシュ通知を実装したときから設定方法が若干変わっていたので、この記事がいつまで有効かはわかりませんが、Androidプロジェクトの新規作成からプッシュ通知受信確認までを書いておこうと思います。
この記事を書いている時点で使用しているAndroid Studioバージョンは2.0です。
さて、最初にAndroid StudioでEmptyActivityを指定して、PushNotificationSampleという名前のNewProjectを作成しておきます。その前提で以下、話を進めていきます。
サンプルプロジェクトリポジトリ全体のプロジェクトはkwmt/PushNotificationSampleに置いています。
Configurationファイル(JSONファイル)を準備するAdd Google Services にアクセスして、Configuration fileを作成します。
作成したgoogle-services.jsonをapp/の直下に置きます。
※Flavor毎に異なったgoogle-services.jsonを使いたい場合は、 google-services:2.0.0-bata3からできそうという話があったが、実際動かないらしいので、betaとれるの待つしかなのかなぁ。 → 2.1.0-beta1で出来るようになりました。(2016/04/18追記)
※google-services-gcmを追加したあと、gradleをsyncする時にgoogle-services.jsonファイルがないと、たとえばBuild Variantをdebugに指定しているときは、下記のようなエラーが出ますのでご注意下さい。
Error:Execution failed for task &#39;:app:processDebugGoogleServices&#39;. &gt; File google-services.json is missing. The Google Services Plugin cannot function without it. Searched Location: PushNotificationSample/app/src/debug/google-services.json PushNotificationSample/app/google-services.json build.gradleを編集google-servicesを追加するプロジェクトトップのbuild.gradleを編集します。--- a/build.gradle +++ b/build.gradle @@ -5,8 +5,9 @@ buildscript { jcenter() } dependencies { - classpath &#39;com.android.tools.build:gradle:1.5.0&#39; - + classpath &#39;com.android.tools.build:gradle:2.1.0-beta1&#39; + // https://develop ers.google.com/cloud-messaging/android/client + classpath &#39;com.google.gms:google-services:2.1.0-beta1&#39; // NOTE: Do not place your application dependencies here; they belong // in the individual module build.</description></item><item><title>Support Design LibraryのBottomNavigationViewを読んだ</title><link>https://kwmt27.net/2020/03/26/read-bottomnavigationview-in-the-support-design-library/</link><pubDate>Thu, 26 Mar 2020 00:10:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/read-bottomnavigationview-in-the-support-design-library/</guid><description>はじめにsupport design libraryの特にBottomNavigationViewを読んでみました。
ガイドライン原文・日本語訳に書いてあるのが、どのようにコードで書かれているのかという視点で読みました。
ちなみに、BottomNavigationというのはこのようなものです。
BottomNavigationViewを読む[ガイドライン]最上位の移動先を3~5個表示する 6個にした場合 IllegalArgumentExceptionが出ます。
2個にした場合 Exceptionは出ずに、2個表示されます。
BottomNavigationView が BottomNavivgationMenu (MenuBuilder) に対して、app:menuで指定した app:menu=&quot;@menu/navigation&quot; navigation.xmlをinflateする際にBottomNavivgationMenuにaddします。
BottomNavigationViewのコンストラクタでapp:menu=&quot;@menu/navigation&quot;をinflateします。
if (a.hasValue(R.styleable.BottomNavigationView_menu)) { inflateMenu(a.getResourceId(R.styleable.BottomNavigationView_menu, 0)); } XMLをパースしながらBottomNavivgationMenuインスタンスに対してaddしているところがあり、
public void addItem() { itemAdded = true; setItem(menu.add(groupId, itemId, itemCategoryOrder, itemTitle)); } ※`menu`が`BottomNavivgationMenu`インスタンスとなる。 この時、実際にaddする前にMenuのサイズがMAX_ITEM_COUNT(5)個より多かったら、IllegalArgumentExceptionを出しているようです。
if (size() + 1 &gt; MAX_ITEM_COUNT) { throw new IllegalArgumentException( &#34;Maximum number of items supported by BottomNavigationView is &#34; + MAX_ITEM_COUNT + &#34;. Limit can be checked with BottomNavigationView#getMaxItemCount()&#34;); } stopDispatchingItemsChanged(); final MenuItem item = super.</description></item><item><title>LINE Simple Beaconを触ってみて、自分なりの疑問点をまとめた</title><link>https://kwmt27.net/2020/03/26/i-tried-to-use-line-simple-beacon-and-summarized-my-own-questions/</link><pubDate>Thu, 26 Mar 2020 00:06:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/i-tried-to-use-line-simple-beacon-and-summarized-my-own-questions/</guid><description>基本的にこちらの記事を参考にすれば、すぐ分かる人は分かるかと思いますが、僕自身が少しハマったことや疑問点があったので、それを忘れないうちにまとめておこうかと思います。
HWID(端末ID)はLINE@ MANAGERページの方にあるブログ記事の通り進めていくと、LINE@ MANAGERとLINE Developerのページの2つのページで確認したり設定することになります。
HWIDはこちらから発行できるのですが、LINE@ Managerで使用しているbotアカウントを選択して、左メニューのLINE Beacon -&gt; アカウント連携 にある端末IDもHWIDを示していますので、そちらでも確認できます。
HWIDとは?スマートフォンがRaspberry Piの受信圏内に出入りしたときに、Beacon EventのWebhookを投げれる状態にするもの。 ブログ記事にあるとおりにラズパイ側で設定するだけでいい。ただ、これだけでは投げる先がわかならないので、投げる先の登録は LINE Developersページで登録する必要があります。
LINE Developersページに行くには?LINE@ Managerから設定したいBotアカウントを選択して、左メニューのアカウント設定-&gt;Bot設定とたどります。 すると、下図のようなリンクがあるので、そこをクリックするといけます。
Go to LINE Developers page.png (LINE Dvelopersページに行くのに、毎回迷子になってました(汗))
WebhookのURLは何を指定したらいいの?サーバーを準備する必要があり、そのURLを指定します。 私はHeroku+Goを使用しました。Getting Started on Heroku with Goなどを参考にWebhookでBeaconEventを受け取れるようにサーバーを準備します。
ただ単に受けるだけなら、下記のような感じでいいです。
http.HandleFunc(&#34;/callback&#34;, func(w http.ResponseWriter, req *http.Request) { log.Println(req) }) http.ListenAndServe(&#34;&#34;, nil) ただ、これだけだとEventが来たときスルーさせるだけなので、Eventが来たことを知る必要があるのと、Eventが来たらどうするのか、たとえばLINEのメッセージに送るとかをしたいと思いますので、それに必要なのがこちらのline-bot-sdkです。
Channel SecretとChannel Access Tokenを指定する必要がありますが、これはLINE Developersページに記載されていますので、確認してみてください。
設定したりパースしたりする部分は省略しますが、Beacon Eventが来たことを判定にするには、下記のように書きます。
for _, event := range events { if event.Type == linebot.EventTypeBeacon { // Beacon Eventが来た。ここでLINEメッセージを送ったりする。 } } LINEメッセージを送るには、eventの中にあるreplyTokenを使用して、下記のように書くと、ここでははろーというメッセージが届くようになります。</description></item><item><title>dockerコンテナのNameを変更するには</title><link>https://kwmt27.net/2020/03/26/to-change-thename-of-a-docker-container/</link><pubDate>Thu, 26 Mar 2020 00:05:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/to-change-thename-of-a-docker-container/</guid><description>方法$ docker rename &lt;CONTAINER ID&gt; &lt;NEW NAME&gt; &lt;CONTAINER ID&gt; には、 docker ps -a で表示されるIDを指定。 &lt;NEW NAME&gt; には、変更したい名前を指定する。
例変更前% docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8618bc25dc49 ubuntu:16.10 &#34;/bin/bash&#34; 15 minutes ago Exited (0) 15 minutes ago prickly_brown 変更後% docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8618bc25dc49 ubuntu:16.10 &#34;/bin/bash&#34; 21 minutes ago Exited (0) 21 minutes ago rename_test NAMESの prickly_brown が rename_test に変わってるのがわかると思います。</description></item><item><title>werckerの独自stepの作り方</title><link>https://kwmt27.net/2020/03/26/how-to-make-a-werckers-own-step/</link><pubDate>Thu, 26 Mar 2020 00:03:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/how-to-make-a-werckers-own-step/</guid><description>はじめにwercker CIでApplicationを新規作成したときにGoのテンプレートに下記のような記述を見かけました。
steps: - setup-go-workspace これは、主にGoパッケージを作ったとき向けのセットアップっぽく、オレオレフレームワークなどには使いにくかったので、ここを変更できたらいいなと思って調べていたら、どうも このレポジトリにあるrun.shを実行してるっぽく、setup-go-workspaceはwercker-step.ymlで定義されてるっぽい。
なんとなく、wercker-step.ymlとrun.shが必要そうってことはわかったけど、どうやって使うんだろうと思ったのがきっかけです。 そしてすぐにはわからなかったのでメモしておこうと思います。
stepの作成からそのstepの使用まで独自stepの作成ということで、まずwercker-step.ymlとrun.shという名前のファイルを用意します。
% mkdir wercker-step-helloworld &amp;&amp; cd wercker-step-helloworld % echo &#39;name: helloworld\nversion: 1.0.0&#39; &gt; wercker-step.yml % echo &#39;echo &#34;hello world!&#34;&#39; &gt; run.sh ドキュメントにあるようにwercker-step.ymlには、nameとversionだけが必須です。
run.shには、hello world!と表示するだけのスクリプトを書いておきます。
GitHubにレポジトリを作ってプッシュします。 ということで、プッシュしたものがこちら。 https://github.com/kwmt/wercker-step-helloworld
Wercker directoryにデプロイ先ほど作成したものをwerckerに登録して公開する必要があります。
こちらからhttps://app.wercker.com/stepを作成します。
create-wercker-step.png このとき先ほどwercker-step.ymlとかをプッシュしたレポジトリを指定します。
これでビルドが走ると思います。
これだけではまだ使えなくて、Wercker directoryというところにDeployする必要があります。 Wercker directoryにDeployするには、deploy targetを指定する必要がありますが、新しく追加しなくても、publish-stepというDeploy targetがすでに作成されてるはずなので、それを使います。
先ほどのビルドが成功したら、ビルドの詳細画面でBuild passedと出ている右側にDeploy toというドロップダウンがあるので、そこをクリックして、publish-stepというDeploy targetを指定し、Start deployをクリックするとデプロイされます。
specify-deploy-target.png デプロイされると下記URLのような感じになります。 https://app.wercker.com/applications/585f2630d8cb9e0100c142c4/tab/details/
自作したstepをwercker.ymlで使う自作したstepを使うには、wercker.ymlに次のように記述します。
steps: - kwmt/helloworld これでwerckerを走らせると、
run-my-wercker-step.png hello world!が出力されてることがわかると思います。
おわりにwercker-box.ymlというのもあってwercker directoryにデプロイするなどは同じっぽいのでこちらはさくっとできそうですね。 今気づきましたが、werckerのgolangのboxって、今日(2016/12/25)時点で、go1.5なんですね。。 https://github.com/wercker/box-golang</description></item><item><title>UITextFieldで自動校正しないようにするには</title><link>https://kwmt27.net/2020/03/26/how-to-prevent-automatic-calibration-on-uitext-fields/</link><pubDate>Thu, 26 Mar 2020 00:01:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/how-to-prevent-automatic-calibration-on-uitext-fields/</guid><description>メールアドレス等入力中に、自動校正させたくない場合があった。 (たとえば、勝手に最初の文字を大文字にしようとしてくれて候補を表示していたのを、候補を表示しないようにしたい)
方法AutolayoutのUITextFieldのAttributeのCorrectionをNoに設定する。
参考https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/#//apple_ref/c/tdef/UITextAutocorrectionType</description></item><item><title>Android Studioを2.1に上げると、ActiveAndroidでエラーが出た場合の対処法</title><link>https://kwmt27.net/2020/03/26/what-to-do-if-you-get-an-error-in-activeandroid-when-you-increase-android-studio-to-2.1/</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/what-to-do-if-you-get-an-error-in-activeandroid-when-you-increase-android-studio-to-2.1/</guid><description>問題Android Studioを2.1にあげると、com.android.tools.build:gradleも2.1.0に上げれるのですが、上げてしまうと、以下のようなエラーがでて、Android6.0で落ちるようになってしまいました。
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method &#39;java.lang.String com.activeandroid.TableInfo.getIdName()&#39; on a null object reference at com.activeandroid.Model.&lt;init&gt;(Model.java:55) 対策調べてみるとActiveAndroidのissueに書いてあったが、AA_MODELSに com.activeandroid.Model を継承しているクラスを指定したmeta-dataを追加すると良いとのとこ。 https://github.com/pardom/ActiveAndroid/issues/461#issuecomment-207252708
こんな感じになりました。
&lt;meta-data android:name=&#34;AA_MODELS&#34; android:value=&#34;com.my.db.ModelAxx, com.my.db.ModelBxx&#34;/&gt; 原因まったく同じソースで、com.android.tools.build:gradleが2.0.0だったら問題なかったので、このバージョンアップのなにかが原因だと思うが、詳しくは調べていません。
ちなみに、 AA_MODELS とはなにかについては、 ここ に書かれてあるように、AcitveAndroidは全部のファイルの中からModelクラスを探しますが、AA_MODELSにModelクラスを明示的に指定することで処理を早くするために指定するものとのことです。</description></item><item><title>IntelliJ IdeaのCreate New ProjectでIntelliJ Platform Pluginが無い場合の出し方</title><link>https://kwmt27.net/2020/03/26/how-to-create-a-new-project-without-intellij-platform-plugin-in-create-new-project-of-intellij-ide/</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/how-to-create-a-new-project-without-intellij-platform-plugin-in-create-new-project-of-intellij-ide/</guid><description>IntelliJ IDEAのプラグインを作ろう!を参考に、プラグインを作ろうと思って、プロジェクトの作成をしようとしたら、”IntelliJ Platform Plugin&quot;がない!!!
Create New Project(IntelliJ Platform Plugin無し) ”IntelliJ Platform Plugin&quot;でググったりしてたんですが、”IntelliJ Platform Plugin&quot;の出し方を書いた記事が見つからない。
いろいろIntelliJ IdeaのPluginあたりを見ててやっと見つけました!
スクリーンショット 2014-11-18 17.03.52.png この&quot;Plugin DevKit&quot;が有効でなかったためです。 これを有効にしてOKして再起動すると Create New Project(IntelliJ Platform Plugin有り) &ldquo;IntelliJ Platform Plugin&quot;が出ました!!
あとでよくよくGetting Started with Plugin DevelopmentのPreliminary Stepsを見てみると、
Plugin DevKit Please make sure that the &ldquo;Plugin DevKit&rdquo; plugin is enabled in Settings | Plugins.
「Plugin設定で、&ldquo;Plugin DevKit&quot;プラグインが有効になっていることを確認してください」って書いてました…(汗)
あわせてよむ IntelliJ IdeaのCreate New ProjectでIntelliJ Platform Pluginを指定した時、右ペインのProject SDKを指定する方法</description></item><item><title>IntelliJ IdeaのCreate New ProjectでIntelliJ Platform Pluginを指定した時、右ペイン</title><link>https://kwmt27.net/2020/03/26/when-you-specify-the-intellij-platform-plugin-in-the-create-new-project-of-intellij-idea-the-right-pane/</link><pubDate>Thu, 26 Mar 2020 00:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/26/when-you-specify-the-intellij-platform-plugin-in-the-create-new-project-of-intellij-idea-the-right-pane/</guid><description>IntelliJ IdeaのCreate New ProjectでIntelliJ Platform Pluginが無い場合の出し方でIntelliJ Platform Pluginを表示することができました。
IntelliJ IDEAのプラグインを作ろう!を参考に、プラグインを作ろうと思って、プロジェクトの作成で、Create New Project - &gt; IntelliJ Platform Pluginを指定した時、Project SDKがで何も選択するものがない。
IntelliJ Platform PluginのProject SDKが これを選択できるようにするには、
右側にある&quot;New&quot;をクリックします。 IntelliJ Ideaのインストールディレクトリを選択します。(Newしたときにデフォルトでインストールディレクトリにいるので、そのままChooseをクリックするだけです。) スクリーンショット 2014-11-18 17.27.11.png 使用したいJava SDKバージョンを指定しOKをクリックします。 これでNoneからIDEA IU-xxx.xxx.xのように選択できるようになります。 スクリーンショット 2014-11-18 17.30.09.png これは、Getting Started with Plugin DevelopmentのConfiguring IntelliJ IDEA SDKの
Using the Select Path dialog box that opens, select the IntelliJ IDEA installation directory directory, and then click OK.
Note, that by default, this dialog box automatically selects the home directory of the currently running IntelliJ IDEA installation.</description></item><item><title>ゼロから始めるDeepLearning</title><link>https://kwmt27.net/2020/03/06/zero-deep-learning/</link><pubDate>Fri, 06 Mar 2020 12:00:00 +0900</pubDate><guid>https://kwmt27.net/2020/03/06/zero-deep-learning/</guid><description>$$\begin{eqnarray} y = \begin{cases} 0 &amp; ( w_1 x_1 + w_2 x_2 \leqq \theta ) \\ 1 &amp; ( w_1 x_1 + w_2 x_2 \gt \theta ) \end{cases} \tag{1} \end{eqnarray}$$
(1)の$\theta$を$-b$と置くと、
$$\begin{eqnarray} y = \begin{cases} 0 &amp; ( b + w_1 x_1 + w_2 x_2 \leqq 0 ) \\ 1 &amp; ( b + w_1 x_1 + w_2 x_2 \gt 0 ) \end{cases} \tag{2} \end{eqnarray}$$
となり、$b$をバイアスと命名。 重みの$w_1$や$w_2$は入力信号への重要度をコントロールするパラメータとして機能。 バイアスは、発火のしやすさ(出力信号が1を出力度合い)を調整するパラメータとして機能。
たとえば、バイアス$b$が-0.1であれば、入力信号の重み付き和が0.1を上回るだけでニューロンが発火します。しかしもしbが-20であれば、入力信号の重み付き和が20を上回らなければニューロンは発火しません。
test$$F(x) = \sum_{n=1}^{N} \frac{1}{N}$$</description></item><item><title>Android研究&発表会#3 開催レポート</title><link>https://kwmt27.net/2019/12/06/android-research-and-presentation-3/</link><pubDate>Fri, 06 Dec 2019 20:25:00 +0900</pubDate><guid>https://kwmt27.net/2019/12/06/android-research-and-presentation-3/</guid><description>はじめに2019/11/30(土)にAndroid研究&amp;発表会#3という勉強会を開催したので、レポートです。
今回は7名参加頂きました!これまで3回開催のうち一番多い人数です。 人数が多ければいいとは思ってませんが、興味を持ってくださり、一緒に勉強したい思ってくださる方が多いのはとてもうれしく思っています!ありがとうございますm(_ _)m
会場変更についてイベント公開時の会場を、3名ほど参加登録頂いたぐらいで、途中で会場を変更させていただきました。 理由としては、イベント公開後に、今回の会場をお借りしたakippa社の移転パーティーに参加させて頂いた時に、エンジニアの方が会場を使っていいとおっしゃってくださったので、お言葉に甘えてお借りすることにしたためです。 このことが影響したためかは不明ですが、当日1人の方が来られなくて、このことが原因であれば大変申し訳無いことをしたなと思いました。
勉強会の様子当日の勉強会の様子です。
まず、エントランスです。 完結でわかりやすい会場の案内を書いてくださってて、とても嬉しかったです!
おみやげの通りもんを持っていきました! 無理やり感あったかもしれませんが、ぜんぶ食べて頂きました。
Kotlin Coroutines ことはじめ14:30から10分ほど会場案内と、この勉強会についてを軽く説明したあと、早速最初の発表として「Kotlin Coroutines ことはじめ」というタイトルで約30分ほど発表頂きました。
資料はこちらを参照ください。Coroutineの基本と仕組みが、わかりやすい図と一緒に説明いただき、理解が深まりました。
会場の雰囲気はこんな感じでした。
Jetpack compose をちょっと触ってみた次に、「Jetpack compose をちょっと触ってみた」というタイトルで発表頂きました。
こちらの方は当初Motion Layoutについての予定だったので、褒めタイムのときに「Motion Layout楽しみにしてた」というご意見も頂いたりもしました。ちなみに僕も楽しみにしてましたw
Android本体の開発について申し込み時点では発表予定なかったのですが、当日の10時ぐらいから資料を作り始めたらしく、飛び込みで発表してくださいました。
Androidのコアな話が聞けて、とても勉強になりました。
ということで、飛び込みLT大歓迎です!
Retrofit2の仕組み 〜CallAdapterを理解する〜最後は僕の発表です。RetrofitというライブラリのCallAdapterについて発表しました。
懇親会今回はconnpassで懇親会参加のアンケートをとっていたため、ぼくの独断でえんやという焼き鳥屋さんを予約してました。 参加予定の方のご都合が悪くなったみたいで、人数が大幅に減りそうでしたが、なんとか懇親できました!
ただ、全員知っているという状況でしたがw
次回次回は第4回になりますが、12月末はやはり年末で参加者も少ないだろうと予想されるので、2020/01/25(土)を予定しております。 イベント(connpass)は後ほど、#arap_osakaでお知らせしたいと思います。
最後に発表頂いた後、褒めタイムというのを設けているのですが、今回もいろいろ褒めたり質問がたくさんでたので、よかったかなと思います。
今回は合計参加人数が7名で、初めて参加の方が4名、発表してくださった方が3名、過去に参加くださった方が1名という感じでした。 その中で、ほんとにはじめましての方は1名でほかは面識ありでした。 仲間うち感をできるだけ出さないようにしようとしたんですが、少し難しかったかもしれません。。
また、勉強会に関するフィードバックを頂きました。
connpassの説明では対象者がわかりにくい これは参加者だけでなく発表者からも言われたフィードバックでした。参加者はAndroid初学者の方からでしたが、全体を通して発表が難しかった(中・上級者向け)ので、実際どこをターゲットにしているかというような内容でした。 発表者からは、資料を準備する際にどのレベルでは説明すればいいか迷ったとのことでした。 これをうけて、もう少しイベント説明内容を見直そうと思います。 会場変更前の会場だったから応募したというのもある すみません、気をつけます。。 「研究」という言葉に引っかかる Wikipediaによると「研究とは、ある特定の物事について、人間の知識を集めて考察し、実験、観察、調査などを通して調べて、その物事についての事実を深く追求する一連の過程のことである。」とのことで、深く追求したいという思いがありますのでこの言葉を使いましたが、ちょっと安易に考えた言葉でもあるので、見直してもいいかもしれません。 勉強会の主催って難しいなぁと思いつつ、また続けてほしいとのお言葉もあり、楽しく続けていきたいと思います。
会場をお借りしましたakippa様ありがとうございました!</description></item><item><title>Android研究&発表会#2 開催レポート</title><link>https://kwmt27.net/2019/12/06/android-research-and-presentation-2/</link><pubDate>Fri, 06 Dec 2019 20:00:00 +0900</pubDate><guid>https://kwmt27.net/2019/12/06/android-research-and-presentation-2/</guid><description>はじめに2019/10/26(土)にAndroid研究&amp;発表会#2というAndroidの勉強会を開催したので、レポートです。
勉強会の様子今回は主催の僕1名と参加者1名の合計2名で開催しました。 で、発表者が僕だけでしたので、参加者1名の方に発表するシュールなスタイルとなりましたw
雰囲気です。 僕の発表資料はこちらです。
途中からモクモク会に変更お気づきかもしれませんが、発表がだいたい20分ぐらいで終わりましたので、もちろん時間が余ります。 そこで何したかっていうと、モクモク会に切り替えました。 事前にconnpass上から、「時間余ったらモクモク会するので、ノートPC持ってきて下さい」と連絡させていただいてて、持ってきて頂いてたのでもくもく会に変更できました。
もくもく会の進め方としては、まずどんなことをもくもくするかいいあって、時間が経ったら最後にどうだったか成果のようなものを軽く発表するという形にしました。これは以前モクモク会だけのイベントをしたときにやってたことでした。
1人の参加者がやっていたことは、Android端末からラズパイだったかな?ちょっと忘れましたが、そういった端末にBloothoothでファイル送信して、送信したら通知がでるのを検知してアプリ上でダイアログとかを出したいとのことでした。
やられてることも興味深かったのですが、通知領域にくる通知を自分のアプリでしることができるというのをしらなかったので、勉強になりました。 ついでにサンプル作ってみたので、ご興味ある方は見てみてください。
僕の方は、 Kotlin Multiplatform project(MPP)でAndroidアプリを作っていたので、その続きをしてました。 MPPはAndroidアプリにGoogleMapを表示して、サーバーにあるストアを表示する簡単なものです。 サーバーはKtorを使っています。今回はマップにストアが表示されない不具合中だったので、その改修をしていました。
最後に今回は懇親会はありませんでした。 3回目もすでに終わった状態でこのレポートをかいているので、特に次回の連絡はありませんが、参加者2人以上でいれば開催していきたいと思っていますので、勉強したい方、一緒に勉強しませんか?!</description></item><item><title>Android研究&発表会#1 開催レポート</title><link>https://kwmt27.net/2019/10/20/android-research-and-presentation-1/</link><pubDate>Sun, 20 Oct 2019 20:25:00 +0900</pubDate><guid>https://kwmt27.net/2019/10/20/android-research-and-presentation-1/</guid><description>はじめにだいぶ時間が経ってしまいましたが、Android研究&amp;発表会#1 開催レポートを書いておきたいと思います。
初の発表スタイルの勉強会を主催2019/09/28(土)にAndroid研究&amp;発表会 #1という勉強会を開催しました。
いままでモバもく会などのもくもく会という形では主催したことありますが、発表形式での勉強会を主催したのは今回が初めてです。
なぜ主催しようと思ったのかとかは、connpassに記載しているので、ここでは実際勉強会がどんな感じだったかを書きます。
参加人数としては、発表してくださる方が3人、聞きに来てくださった方が2人の合計5人です。
全体的な写真 勉強会の様子14:00に開場、14:20から会場説明の予定でしたが、14時過ぎには全員来てくださいまして、待っててもしょうがないので勉強会をスタートさせました。
画像が全体が入ってないし、荒いのですが会場案内とこの勉強会について説明しているところがこんな感じです。
毎月月末の土曜日に開催していきたいという話しをしているところあたりです。12月は28日だからめっちゃ月末やん、まぁ忘年会も一緒にやれたらいいかもですね、とかいう会話も混ざったりして、なごやかな雰囲気でした。
続いて、僕のLifecycleについて発表しました。その時の写真ですが、ぜんぜん写ってない・・・。時間的には40分話しました。
会場説明と発表が続いたので、休憩をいれました。
そのあと、パフォーマンス・チューニングの話をしてくださいました。 時間は20分ちょうどでしたね。
続いて、組み込みAndroidの話です。20分予定がだいぶオーバーして1時間喋ってましたねw
Android Thingsを持ってきて実演してくださったりもしました。
時間については短くなったりオーバーしたりしてもいいとは言ったものもの、ある程度調整は必要かと思いましたw
これでだいたい17:30ぐらいで、最初はだいぶ時間があまるんじゃないかとドキドキしていましたが、思いのほかいい感じの時間になったので、勉強会は終了して、ご飯いけるひとだけ行きました。
そのときのビールの写真ですwこれしかなかった。。。
感想という感じで、発表してくださる方もいらっしゃったし、懇親会もできて一旦成功と言っていいかなと思っています。
初回なのに僕以外の人が発表してくださるのがとても嬉しかったです。
やはり褒めるのはなかなかはずかしいのか、そんなに褒めることはなかったように思いますが、少人数だからというのもあるのでしょうが、質問がたくさん出たのはとてもよかったと思いました。
次回第2回もやります!のでぜひ遊びにきて下さい。 発表枠が余ってます!w
Android研究&amp;発表会 #2</description></item><item><title>Retrofitパースエラー一覧</title><link>https://kwmt27.net/2019/10/20/retrofit-error-list/</link><pubDate>Sun, 20 Oct 2019 20:25:00 +0900</pubDate><guid>https://kwmt27.net/2019/10/20/retrofit-error-list/</guid><description>はじめにRetrofitのエラー一覧です。
interface GitHubService { @GET(&#34;users/{user}/repos&#34;) fun listRepos(@Path(&#34;user&#34;) user: String): Call&lt;List&lt;Repo&gt;&gt; } val retrofit = Retrofit.Builder() .baseUrl(&#34;https://api.github.com/&#34;) .build() val gitHubService = retrofit.create(GitHubService::class.java) このように定義したとき、次のように呼び出すときに、内部でリフレクション使ってパースして、ちゃんとHTTPメソッドのアノテーションつけてるかとか、 ServiceMethod#parseAnnotations メソッドでやっていました。
そのパース時にいろいろチェックしていたので、そのときのエラーを一覧でまとめて起きたいと思います。
ServiceMethod#parseAnnotationsRequestFactory#parseAnnotationアノテーションチェックしていて、以下の場合IllegalArgumentExceptionをスローします。
HTTPメソッドのアノテーションを複数指定してる場合例@GET(&#34;users/{user}/repos&#34;) @POST() エラーメッセージOnly one HTTP method is allowed. Found: GET and POST.
該当コードif (this.httpMethod != null) { throw methodError(method, &#34;Only one HTTP method is allowed. Found: %s and %s.&#34;, this.httpMethod, httpMethod); } クエリパラメータに{}がある場合例@GET(&#34;users/{user}/repos?limit={limit}&#34;) エラーメッセージURL query string &ldquo;limit={limit}&rdquo; must not have replace block. For dynamic query parameters use @Query.</description></item><item><title>Android Studio3.6からの追加されたView Bindingを使ってみた</title><link>https://kwmt27.net/2019/10/11/view-binding/</link><pubDate>Fri, 11 Oct 2019 19:40:00 +0900</pubDate><guid>https://kwmt27.net/2019/10/11/view-binding/</guid><description>View BindingとはView Bindingは、Viewの参照をかんたんにアクセスできる機能です。 これを使うには、build.gradleファイルに次の設定が必要です。
android { viewBinding.enabled = true } これにより、各レイアウトクラスがコードからアクセスできるようにコンパイル時に自動生成されます。 自動生成されたファイルは下記のパスに生成されます。
build/generated/data_binding_base_class_source_out/ 自動生成されないようにするには、レイアウトに次のプロパティを設定すれば自動生成されません。
&lt;LinearLayout ... tools:viewBindingIgnore=&#34;true&#34; &gt; ... &lt;/LinearLayout&gt; 使い方activity_maps.xmlというファイル名で、内容が次のような場合、
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&#34;http://schemas.android.com/apk/res/android&#34; ...&gt; &lt;Button android:id=&#34;@+id/searchAreaButton&#34; ... /&gt; &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt; Activity側で、次のように置き換えます。
private lateinit var binding: ActivityMapsBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMapsBinding.inflate(layoutInflater) setContentView(binding.root) } すると、次のように参照できます。
binding.searchAreaButton.setOnClickListener { .... } DataBindingとの違い &lt;layout&gt;タグで囲む必要はありません。 レイアウト変数とレイアウト式がサポートされてません。</description></item><item><title>Navigation Architecture ComponentでToolbarのバックボタンを非表示にするには</title><link>https://kwmt27.net/2019/10/11/how-to-remove-back-button-of-toolbar-with-navigation-component/</link><pubDate>Fri, 11 Oct 2019 16:40:00 +0900</pubDate><guid>https://kwmt27.net/2019/10/11/how-to-remove-back-button-of-toolbar-with-navigation-component/</guid><description>こちらを参照 https://stackoverflow.com/a/57169105/2520998
トップレベルのDestinationだったら非表示になるから、非表示にしたいDestinationをトップレベルに設定すればいい、とのこと。
こちらのサンプルを例にした場合、次のようにするとよさそう。</description></item><item><title>SwiftUIでGoogleMapsを表示するには</title><link>https://kwmt27.net/2019/10/06/how-to-googlemap-on-swiftui/</link><pubDate>Sun, 06 Oct 2019 02:30:00 +0900</pubDate><guid>https://kwmt27.net/2019/10/06/how-to-googlemap-on-swiftui/</guid><description>SwiftUIでGoogleMapを表示する方法を調べたのでメモします。
GoogleMapView.swiftを作成 補足UIViewRepresentableはUIKitを表すViewです。
makeUIViewとupdateUIViewは必ず実装する必要があります。
func makeUIView(context: Self.Context) -&gt; Self.UIViewType は、表示するUIKitビューを作成します。
func updateUIView(Self.UIViewType, context: Self.Context) は、提示されたUIKitビュー(およびその座標)を最新に更新します。
これからもわかるように、makeUIViewからupdateUIViewの順で呼ばれます。
作成したGoogleMapViewを表示したい場所に挿入 これだけです。
完成 補足もちろん、Google MapsのAPIの有効化やAPIキーの設定は必要です。
GoogleMapsの設定に関してはこちらを参照 Get Started | Maps SDK for iOS | Google Developers</description></item><item><title>Android Lifecycle関連コンポーネントについて</title><link>https://kwmt27.net/2019/09/19/android-lifecycle-codelab/</link><pubDate>Thu, 19 Sep 2019 21:10:00 +0900</pubDate><guid>https://kwmt27.net/2019/09/19/android-lifecycle-codelab/</guid><description>はじめにAndroid Lifecycleのコードラボをやりつつ、ViewModelやLiveDataの仕組みを調べたのでメモしておこと思います。
https://codelabs.developers.google.com/codelabs/android-lifecycles
コードラボのコードベースでいろいろ試したソースはこちら
https://github.com/kwmt/android-lifecycles
Step1,2 ViewModelstep1はアプリが起動したらタイマーがカウントアップし、画面回転するとタイマーのカウントがクリアされてしまう、という問題にViewModelというものを使ってどう対処するのかという話です。
ViewModelとはViewModelを使えば、ActivityやFragmentのライフサイクル全体でデータを保持できます。 ActivityやFragmentは、ユーザーの操作でCreatedとDestroyedを繰り返す生存期間の短いオブジェクトです。
ViewModelクラスを作成するには、ViewModel()を継承します。(中身は空っぽですが)
class ChronoViewModel: ViewModel() { } ViewModelは、ViewModelインスタンスが破棄されるときに呼ばれるonClearedというメソッドを持っています。
ViewModelインスタンスの取得方法このViewModelインスタンスをActivityやFragmentで取得するには、
private val viewModel by viewModels&lt;ChronoViewModel&gt;() のようにKotlin property delegateを使って取得するか、
viewModel = ViewModelProvider(this).get(ChronoViewModel::class.java) このように取得することになります。
以前は、ViewModelProvider.of(activity)のように取得していましたが、lifecycleのバージョン2.2.0-alpha03からDeprecatedになっていました。 https://developer.android.com/jetpack/androidx/releases/lifecycle#2.2.0-alpha03
また、kotlin propertey Delegationを使うにはfragment-ktxの1.1.0以上を使う必要があります。
implementation &#34;androidx.fragment:fragment-ktx:1.1.0&#34; https://developer.android.com/jetpack/androidx/releases/fragment#1.1.0
ViewModelの生存期間ViewModelの生存期間はActivityやFragmentよりも長いです。 下図はActivityを起動して、画面を回転させ、バックボタンでアプリを終了したときの状態遷移です。
起動 onCreate viewModel created(正確にはLazyなのでアクセスしたタイミング) onStart onResume 回転 onPause onStop onDestroy onCreate onStart onResume バックボタンでアプリ終了 onPause onStop viewModel onCleared onDestroy 画面回転時に、ActivityはonDestroyされていますが、ViewModelはonClearedが呼ばれていません。
ViewModelの仕組みここで、
ViewModelがどのような仕組みで保持されているか 画面回転時にもonDestroyが呼ばれているにも関わらずonClearedは呼ばれず、アプリ終了時にのみonClearedが呼ばれている仕組み をみてみます。
1. ViewModelがどのような仕組みで保持されているかまず、Activityは
ChronoActivity -&gt; AppCompatActivty -&gt; FragmentActivity -&gt; ComponentActivity -&gt; Activity このような継承関係になっています。</description></item><item><title>KotlinのDelegateについて</title><link>https://kwmt27.net/2019/08/18/iosched-2019-kotlin-delegate/</link><pubDate>Sun, 18 Aug 2019 18:50:00 +0900</pubDate><guid>https://kwmt27.net/2019/08/18/iosched-2019-kotlin-delegate/</guid><description>はじめにGoogle I/O 2019のソースが公開されたのでさっそく読み始めたところ、下記のコードが気になった。 KotlinのDelegated propertyであることは知っていたが、あんまり詳しく知らなかったので、今回はDelegateについて調べてみたので、それについてのメモです。
override var onboardingCompleted by BooleanPreference(prefs, PREF_ONBOARDING, false) ちなみに、試したコードはこちらです。
https://github.com/kwmt/Kotlin-Playground/tree/master/src/main/kotlin/delegation
まずはDelegationの基本についてJavaでは処理をクラスに委譲するには次のようにやっていたと思います。(下記サンプルはJavaではないが、Javaで書くならこんな感じになる)
package delegation interface Nameble { var name: String } class JackName : Nameble { override var name: String = &#34;Jack&#34; } class Person(name: Nameble) : Nameble { override var name: String = name.name } fun main() { val person = Person(JackName()) println(person.name) } つまり、PersonクラスのnameをNamebleのnameに委譲したい場合、
override var name: String = name.name と書かないといけません。
しかし、kotlinのdelegationを使うと、次のように書けます。
package delegation interface Nameble { var name: String } class JackName : Nameble { override var name: String = &#34;Jack&#34; } class Person(name: Nameble) : Nameble by name fun main() { val person = Person(JackName()) println(person.</description></item><item><title>Pragmatic State Management in Flutter (Google I/O'19)のメモ</title><link>https://kwmt27.net/2019/05/18/googleio_flutter_state_management/</link><pubDate>Sat, 18 May 2019 11:50:00 +0900</pubDate><guid>https://kwmt27.net/2019/05/18/googleio_flutter_state_management/</guid><description>問題点ネットワークから、他のwidgetからシステムコールなどから、widgetの状態変更したい場合は多くあります。
たとえば3つのWidgetがあったとき、MySliderからMyChartの状態を変更する場合、下図のようにしたくなるかもしれませんが、これにはいくつか問題があります。
1.widgetが強参照している(strongly coupling widget)
つまりMySliderはMyChartのことを知っている→これは拡張性がなくなります。not very scalable
2.グローバルの状態を持っている
多くのチャートがある場合、同期されてしまいます。
3.外のwidgetからsetStateを呼んでいること これは最悪
どこから状態が変わったのか把握できない クラッシュする可能性がある 下図は、UI is a functional of stateです。UI=レイアウトは、現在のアプリケーションの状態がビルドメソッドを介して決まります。
つまりは、UIは他のUIから変更されません。 findViewByIdのようなものはありません。
対策これを解決するためには、両方のwidgetにアプローチ、アクセスできる何かが必要です。 これを今回はMyScheduleと呼びましょう。
これはMyHomePageにアタッチされます。なぜなら両方のwidgetをしっているから。
MySliderが直接MyChartを触る代わりにMyScheduleを通してMyChartに伝えます。
MySlider -&gt; MyScheduler -&gt; MyChartに通知notify MyChart -&gt; MySchedular -&gt; MySliderに変更したよ結果を通知
コードはどのようになるか?そのためにGoogleの状態管理アプローチの歴史を見る
Scoped model widgetのトップにモデルがあり子孫があるとき、 モデルが変更されたら、それらの子孫は通知される、。
これは使われているが、いくつかの機能が不足している
BLoC 複雑なアプリが複数あるAdwordsのためにつくられた。 Rxとstremaベース これは複雑すぎるという意見を聞いた あるいは、Flutterをやるにはnewアプローチをしないと
package:provider コミュニティベース これをGoogle内部で使っている Scopedモデルに近い Providerを使うにはまずMyScheduleを定義しましょう。
import &#39;package:flutter/widgets.dart&#39;; class MySchedule with ChangeNotifier { double _stateManagementTime = 0.5; double get stateManagementTime =&gt; _stateManagementTime; set stateManagementTime(double newValue) { _stateManagementTime = newValue; notifyListeners(); } } このMyScheduleをMyHomePageにアタッチするには、 トップにchangenotifierproviderを次のようにラップします</description></item><item><title>プライバシーポリシー</title><link>https://kwmt27.net/2019/05/12/privacy-policy/</link><pubDate>Sun, 12 May 2019 00:00:00 +0900</pubDate><guid>https://kwmt27.net/2019/05/12/privacy-policy/</guid><description/></item><item><title>Flutter for webのサンプルを動かしてみた</title><link>https://kwmt27.net/2019/05/11/flutter_for_web/</link><pubDate>Sat, 11 May 2019 18:10:00 +0900</pubDate><guid>https://kwmt27.net/2019/05/11/flutter_for_web/</guid><description/></item><item><title>Android Room with a View - KotlinというCodelabをやってみた</title><link>https://kwmt27.net/2019/05/04/android-room-with-view/</link><pubDate>Sat, 04 May 2019 10:50:00 +0900</pubDate><guid>https://kwmt27.net/2019/05/04/android-room-with-view/</guid><description/></item><item><title>Getting Started with CameraXというCodelabをやってみた</title><link>https://kwmt27.net/2019/05/02/getting-started-with-camerax/</link><pubDate>Thu, 02 May 2019 23:50:00 +0900</pubDate><guid>https://kwmt27.net/2019/05/02/getting-started-with-camerax/</guid><description/></item><item><title>Flutterプラグインのテストで正しくMethodCallが呼ばれてるかテストするには</title><link>https://kwmt27.net/2019/03/17/flutter_ismethodcall/</link><pubDate>Sun, 17 Mar 2019 00:12:00 +0900</pubDate><guid>https://kwmt27.net/2019/03/17/flutter_ismethodcall/</guid><description>下記のコードは、flutter_inapp_purchaseのdartコードの1つのメソッドで、実装はわかりやすいように1つのinvokedMethodに修正したものですが、Flutterプラグインでネイティブのメソッドを呼び出すにはMethodChannelのinvokedMethod(文字列,パラメータ)のような感じで呼び出します。
static final MethodChannel _channel = const MethodChannel(&#39;flutter_inapp&#39;); static Future&lt;List&lt;IAPItem&gt;&gt; getProducts(List&lt;String&gt; skus) async { dynamic result = await _channel.invokeMethod( &#39;getItemsByType&#39;, &lt;String, dynamic&gt;{ &#39;type&#39;: &#39;inapp&#39;, &#39;skus&#39;: skus, }, ); return extractItems(result); } invokedMethodは文字列を渡すので、例えば 'getItemsByType'が 極端ですが'get'とかになっていてもコンパイルできてしまいます。
そこで、getProductsが正しく'getItemsByType'が呼ばれている確認するには、下記のコードのようにisMethodCallを使います。
test(&#39;invokes correct method&#39;, () async { await FlutterInappPurchase.getProducts(skus); expect(log, &lt;Matcher&gt;[ isMethodCall( &#39;getItemsByType&#39;, arguments: &lt;String, dynamic&gt;{ &#39;type&#39;: &#39;inapp&#39;, &#39;skus&#39;: skus, }, ), ]); }); このようにすると、たとえば先程の例のように'getItemsByType'が getになっていた場合、テストを実行すると、期待する文字列は'getItemsByType'だけど実際はgetになっているよ、と教えてくれます。
Expected: [ &lt;has method name: &#39;getItemsByType&#39; with arguments: {&#39;type&#39;: &#39;inapp&#39;, &#39;skus&#39;: [&#39;testsku&#39;]}&gt; ] Actual: [MethodCall:MethodCall(get, {type: inapp, skus: [testsku]})] Which: does not match has method name: &#39;getItemsByType&#39; with arguments: {&#39;type&#39;: &#39;inapp&#39;, &#39;skus&#39;: [&#39;testsku&#39;]} at location [0]</description></item><item><title>Cloud Firestoreプラグインのバージョン0.9.0でビルドエラーが出たのでその対策メモ</title><link>https://kwmt27.net/2019/02/02/build-error-with-cloud-firestore-v0.9.0/</link><pubDate>Sat, 02 Feb 2019 19:55:00 +0900</pubDate><guid>https://kwmt27.net/2019/02/02/build-error-with-cloud-firestore-v0.9.0/</guid><description>はじめにFlutterのCloud Firestoreプラグインのバージョン0.9.0でBreaking changeな変更が入りました。 新規Flutterプロジェクトにバージョン0.9.0を入れてAndroidのビルドでいくつかビルドエラーになったので、そのときの対応したのをメモしておきたいと思います。
cannot find symbol import androidx.annotation.NonNull; と出た現象次のようなビルドエラーが出ました。
&lt;HOME&gt;/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.9.0/android/src/main/java/io/flutter/plugins/firebase/cloudfirestore/CloudFirestorePlugin.java:9: error: cannot find symbol import androidx.annotation.NonNull; ^ symbol: class NonNull location: package androidx.annotation 対策&lt;Flutterプロジェクトルート&gt;/android/gradle.propertiesファイルに下記を追加
android.useAndroidX=true android.enableJetifier=true 参考リンク https://github.com/flutter/flutter/issues/27156#issuecomment-457951736 Android resource linking failedと出た現象`FAILURE: Build failed with an exception. * What went wrong: Execution failed for task &#39;:app:processDebugResources&#39;. &gt; Android resource linking failed Output: &lt;プロジェクトルート&gt;/build/app/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:197: error: resource android:attr/fontVariationSettings not found. &lt;プロジェクトルート&gt;/build/app/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:198: error: resource android:attr/ttcIndex not found. error: failed linking references. Command: /Users/kwmt/.</description></item><item><title>Firebaseのセットアップ方法</title><link>https://kwmt27.net/2019/02/02/how-to-setup-cloud-firestore/</link><pubDate>Sat, 02 Feb 2019 16:00:00 +0900</pubDate><guid>https://kwmt27.net/2019/02/02/how-to-setup-cloud-firestore/</guid><description>はじめにCloud Firestoreを始めFirebaseのサービスを使えるようにするためには、Firebaseにプロジェクトを追加し設定する必要があります。 ここではFirebaseにプロジェクトを追加しFlutterプロジェクトでAndroidとiOSでFirebaseを使えるようになるまでの設定方法を見ていきたいと思います。
Firebaseにプロジェクトを追加こちらのURL(https://console.firebase.google.com/)を開き、プロジェクトを追加します。今回の場合はsd-2019-04-flutterというプロジェクトを追加しました。
AndroidでFirebaseを使えるようにするAndroidでFirebaseを使えるようにするためには、google-services.jsonというファイルをダウンロードし、Flutterプロジェクトに追加する必要があります。
google-services.jsonをダウンロードするそのためにはまず、Firebaseのプロジェクト設定からアプリをAndroidアプリを追加する必要があります。
ドロイド君のアイコンをクリックしてください。
すると、Androidパッケージの入力が求められますので、パッケージを入力します。
パッケージ名を確認するには、Flutterプロジェクトの android/app/build.gradleファイルを開き、applicationIdを探してください。その設定値がパッケージ名になります。
パッケージを入力したらgoogle-services.jsonがダウンロードできるようになりますので、ダウンロードしてください。
Flutterプロジェクト(Android)でセットアップするFlutterプロジェクトにgoogle-services.jsonを格納するFlutterプロジェクトルート/android/app以下に格納してください。
build.gradleファイルを編集するFlutterプロジェクトルート/android/ にある build.gradleファイルを開いて、google-serviceプラグインを追加します。
dependencies { classpath &#39;com.android.tools.build:gradle:3.2.1&#39; classpath &#34;org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version&#34; classpath &#39;com.google.gms:google-services:4.1.0&#39; // ←この行を追加 } 次にFlutterプロジェクトルート/android/appにある build.gradleファイルを開いて、最下行に下記を追記してください。
apply plugin: &#39;com.google.gms.google-services&#39; これでAndroidに関してはFirebaseのセットアップは終了です。
iOSでFirebaseを使えるようにするiOSでFirebaseを使えるようにするためには、GoogleService-Info.plistというファイルをダウンロードし、Flutterプロジェクトに追加する必要があります。
GoogleService-Info.plistをダウンロードするそのためにはまず、Firebaseのプロジェクト設定からアプリをAndroidアプリを追加する必要があります。
iOSと書かれたアイコンをクリックしてください。
すると、iOSのバンドルIDの入力が求められますので、バンドルIDを入力します。
バンドルIDを確認するには、XcodeでFlutterプロジェクトを開いて確認するのが簡単だと思います。
XcodeでFlutterプロジェクトを開くには、Android Studioを使っている場合、Toolsメニューから開くことができます。
dartファイル(例えばmain.dart)を開いている状態で、Tools-&gt;Flutter-&gt;Open iOS module in Xcodeをクリックしてください。
Xcodeが開いたら、左側のProject NavigatorのRunnerを選択すると右側にBundle Identifierという項目があるのでその設定値がバンドルIDになります。
バンドルIDを入力する画面に戻って、バンドルIDを入力してアプリを登録します。その後、GoogleService-Info.plistがダウンロードできるようになりますので、ダウンロードしてください。
Flutterプロジェクト(iOS)でセットアップするFlutterプロジェクトにGoogleService-Info.plistを格納する上記でも書きましたが、XcodeでFlutterプロジェクトを開いてください。
Project NavigatorでRunner/Runner以下にGoogleService-Info.plistファイルを追加してください。
これでiOSに関してFirebaseのセットアップは終了です。</description></item><item><title>Dynamic link test</title><link>https://kwmt27.net/2019/01/01/dynamic_link_test/</link><pubDate>Tue, 01 Jan 2019 00:00:00 +0900</pubDate><guid>https://kwmt27.net/2019/01/01/dynamic_link_test/</guid><description>アプリで開く(プレビュースキップ)
アプリで開く(プレビュースキップ, iflがない())
アプリで開く(プレビュースキップしない)
アプリで開く(プレビュースキップしない, iflがない())</description></item><item><title>2018振り返り</title><link>https://kwmt27.net/2018/12/31/looking-back-2018/</link><pubDate>Mon, 31 Dec 2018 14:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/12/31/looking-back-2018/</guid><description>昨年に引き続き、今年で6回目の振り返りを書いておこう。
昨年の目標達成状況 ❌ CraftBeerのサイトは満足するまで作る! 満足はしてないですが、たまに見てこれでいいかとも思っていたところもあり、ほとんど手をつけれてないです。ただ現在見直しているところで、Go Firebase Nuxtjsとかで作りなおす予定です。 ❌ → ✅ モバもく会つづける 今年は1回だけ開催しました。それ以降できなかった理由はオフィスが耐震工事で土日が使えなかったのが大きな理由です。 来年はやっていきたい。 ❌ → ✅ AnroidはAndroid Architecture Componentをさわる DroidKaigiにコントリビュートするために見たぐらいで、ガッツリさわってはいない。 来年はAACのViewModelあたりから触っていきたい ✅ ハーフマラソン時間内に完走する 高槻シティハーフマラソンを2時間12分10秒で完走した! ❌ → ✅ ストレッチする たま~にランニングする前にストレッチするぐらい ❌ 簿記やるか 本買ってから開いてない・・・ 来年はたぶんやらないと思う。 ※ ❌ → ✅ となってるところは、自分的にはできてないと思ったけれど、少しでもやれてるから○だ!と指摘されて ✅ に変えたところです。
仕事関連前半は私用も含めて東京に行く回数が多かった気がします。 新年明けてからすぐの1月は東京でクラフトビール巡るために5件回りました。このとき始めて鎌倉の大仏を見に行きました。 その翌週にも仕事の打ち合わせで東京に行き、そこでもYONA YONA BEER WORKSに行きました。
1月の始めの方は、Mアプリ(M社)のセカンドフェーズがキックオフになりました。また同じ頃Fアプリ(S社)もキックオフです。 Mアプリの方はネイティブ+WebViewのハイブリッドアプリで、Fアプリの方はWebViewです。Fアプリはネイティブ担当なのでそれほど工数はかからないのですが、Mアプリが大変でした。結局6月ぐらいまでかかりました。 これはClean Architecture+DDDで設計したのですが、ドメイン領域のクラス名をAndroid、iOS両方とも同じ名前にするは、両方開発しているとありだなと思いました。Android開発していて、iOSを触ることになったら同じクラス名なのですぐジャンプしやすく効率よいと感じました。ただ認識あわせが大変ではありますが。
2月下旬、3月は少しNアプリ(WebViewアプリ)案件が入りました。こちらもネイティブ担当です。
4月はAアプリの改修が少し1週間ぐらいの作業をやりました。ガッツリネィティブです。また今もまだやっているTアプリ案件のキックオフもこの時期です。東京に打ち合わせしに行きました。いろいろあって作業自体は6月ぐらいから着手しています。
このころもまだMアプリをやっています。Google IOに行ったときにも定例打ち合わせがあったのでIO会場から定例に参加したことが懐かしい感じです。
5月ぐらいからSアプリ案件でAndroidアプリ開発がありました。ベースは別の人が作っていて僕は途中から参加しました。 Rxだらけでしたw
Tアプリはまだ作業中なのですが、Camera2ApiやOpenCVなど今までにあまり経験がないことをやっていて、大変ですが楽しくやっています。
大きく分けると1〜6月はMアプリ6月〜12月はTアプリという感じでした。とこどころ1,2週の作業が入ったりしてましたが、お概ねそんあ感じです。あ、5,6月ぐらいにSアプリも少しあったのですが、Webの改修もありましたね。Nuxtjsをちょっと触ったり、PHP]ちょっと触ったり。
また、今年は会社で1,2週1回社内勉強会するようになりました。最初は読書会で、それが終わったらFirebase研究したり、Flutterをみんなで触ってみたり、仕事ではやらない楽しそうなことをやっていきました。これは気分転換にもなり普段みんなが考えてることなどを聞けるので、非常によいです。これは来年も続けて行きたいです。
来年は春ぐらいまではTアプリが続きそうです。
Flutterに関してQiitaにも書いたのですが、今年の後半からFlutter三昧でした。
今年は1つアプリをリリースしました。
iOSは審査中です。
勉強会 1月
モバもく会#11 【京都】LINE Bot開発者 新年会! 2月</description></item><item><title>sketchメモ</title><link>https://kwmt27.net/2018/12/24/sketch-memo/</link><pubDate>Mon, 24 Dec 2018 14:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/12/24/sketch-memo/</guid><description>はじめにSketchの使い方をググって参考になったリンクを貼るだけの記事
リンク集 アイコンの作り方
https://medium.com/sketch-app-sources/how-to-use-sketch-to-build-great-icons-9c3d982ae91d アプリアイコンの作り方
https://medium.com/sketch-app-sources/sketch-icon-tutorial-1-1-productive-1bf12a2ffb41</description></item><item><title>Flutterパッケージを作るにあたって実行の仕方がわからなかったのでメモ</title><link>https://kwmt27.net/2018/11/28/flutter-create-and-run-package/</link><pubDate>Wed, 28 Nov 2018 08:25:00 +0900</pubDate><guid>https://kwmt27.net/2018/11/28/flutter-create-and-run-package/</guid><description>作成したい名前でパッケージプロジェクトを作成する。% flutter create --org net.kwmt27 --template=plugin -i swift -a kotlin flutter_crashlytics ビルド確認するexampleまで移動し、Android,iOSともにビルドして、エラーが出ないことを確認します。
% cd flutter_crashlytics/example % flutter build apk % flutter build ios --no-codesign 実行してみる実行するには、exampleを開いて、Flutterプロジェクトを実行するだけです。
具体的には、最初に作成したパッケージプロジェクト(flutter_crashlytics)をAndroid StudioやVSCodeで開きます。
Android Studioの場合は、すでにmain.dartが指定されているはずなので、実行ボタンをおすだけ。
VSCodeの場合は、example/lib/main.dartを開いた状態で実行すれば実行できました。
パッケージ開発パッケージの開発するには、
Androidの場合は、Android Studioで example/androd/build.gradleを開いて、FlutterCrashlyticsPlugin.ktあたりを触ればよさそう。 iOSの場合は、Xcodeでexample/ios/Runner.xcworkspaceを開いて、Pods/Development Pods/flutter_crashlytics/../../example/ios/.symlinks/plugins/flutter_crashlytics/ios/Classes/SwiftFlutterCrashlyticsPlugin.swiftをさわることになりそう。(こんな長いのか??)</description></item><item><title>DartのfirstWhere</title><link>https://kwmt27.net/2018/11/27/dart-firstwhere/</link><pubDate>Tue, 27 Nov 2018 21:50:00 +0900</pubDate><guid>https://kwmt27.net/2018/11/27/dart-firstwhere/</guid><description>下記のような感じで書いていて、条件に一致しない場合は、
members.firstWhere((member) =&gt; _lastMessage.fromUserId == member.userId); Bad state: No element
と出ます。
仕様にも書いてました。
/** * Returns the first element that satisfies the given predicate [test]. * * Iterates through elements and returns the first to satisfy [test]. * * If no element satisfies [test], the result of invoking the [orElse] * function is returned. * If [orElse] is omitted, it defaults to throwing a [StateError]. */ E firstWhere(bool test(E element), {E orElse()}) { for (E element in this) { if (test(element)) return element; } if (orElse !</description></item><item><title>Dartのenumからの文字列取得について</title><link>https://kwmt27.net/2018/10/28/dart-enum/</link><pubDate>Sun, 28 Oct 2018 17:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/10/28/dart-enum/</guid><description>enum Type { Hoge, Fuga } というenumがあったとき、このenumから“Hoge”という文字列を取得したい場合、次のようにする。
Type.Hoge.toString().split(&#39;.&#39;)[1] splitしなかったら、&quot;Type.Hoge&quot;という文字列が返る。
dartpud(sample)https://dartpad.dartlang.org/a4a24c9a210cb0779e74c615d5ef25dd</description></item><item><title>FlutterのAndroid Studio3.2.1対応したらエラーが出たので修正した</title><link>https://kwmt27.net/2018/10/27/flutter-android-gradle-plugin-3.2.1/</link><pubDate>Sat, 27 Oct 2018 16:15:00 +0900</pubDate><guid>https://kwmt27.net/2018/10/27/flutter-android-gradle-plugin-3.2.1/</guid><description>現象gradleプラグイン(android/build.gradle)のバージョンを3.2.1にしたら、
&#39;Could not find lint-gradle-api.jar&#39; と出て、Androidでビルドができなくなった。。
原因直接的な原因はFlutterがAndroid Stdio3.2に対応していないから。
対策FlutterSDKにある
flutter/packages/flutter_tools/gradle/flutter.gradle を開いて次のように変更するだけでよさそう。
index 390bb2deb..1e0f35c47 100644 --- a/packages/flutter_tools/gradle/flutter.gradle +++ b/packages/flutter_tools/gradle/flutter.gradle @@ -18,10 +18,8 @@ import org.gradle.api.tasks.bundling.Jar buildscript { repositories { + google() jcenter() - maven { - url &#39;https://dl.google.com/dl/android/maven2&#39; - } } dependencies { classpath &#39;com.android.tools.build:gradle:3.1.2&#39; あるいは、flutterリポジトリのmasterブランチは修正されているので、Flutter channelをmasterにするといいかもしれいない。
参考 関節的な原因: https://developer.android.com/studio/releases/#aapt2_gmaven</description></item><item><title>Androidのアプリ内課金のテスト購入して取り消すには?</title><link>https://kwmt27.net/2018/10/15/android-cancel-billiing/</link><pubDate>Mon, 15 Oct 2018 09:45:00 +0900</pubDate><guid>https://kwmt27.net/2018/10/15/android-cancel-billiing/</guid><description>問題Androidのアプリ内課金(定期購入ではない方)をテストしていて、一度購入して、再度購入テストしようとすると、 ITEM_ALREADY_OWNED とすでに購入済みというエラーが出て購入テストができません。
ちなみにここでのテスト購入時のプロダクトIDは、たとえばandroid.test.purchased です。 これで購入しようとすると、購入したとみなしてレスポンスを返してくれます。
対策で、本題ですが、購入を取り消すには次の手順で取り消すことができました。
アプリをアンインストール % adb shell pm clear com.android.vending を実行 注意アプリをアンインストールせずに、上記2番のコマンドを叩くだけだと、うまくいかないようです。
参考https://stackoverflow.com/a/30178861</description></item><item><title>DartのMapを<String, dynamic>に変換するには?</title><link>https://kwmt27.net/2018/10/13/dart-map/</link><pubDate>Sat, 13 Oct 2018 13:20:00 +0900</pubDate><guid>https://kwmt27.net/2018/10/13/dart-map/</guid><description>// サンプルデータ Map&lt;String, bool&gt; members = Map&lt;String, bool&gt;() ..putIfAbsent(&#34;userID1&#34;, () =&gt; true) ..putIfAbsent(&#34;userID2&#34;, () =&gt; true); print(members); // output: // {userID1: true, userID2: true} var transMember = members.entries.map((member) { return &lt;String, dynamic&gt;{member.key: member.value}; }); print(transMember); // output: // ({userID1: true}, {userID2: true}) Dartpad動かして確認するにはこちら</description></item><item><title>AndroidやiOSのアプリ開発でいつも私がやっていることをFlutterでやってみた</title><link>https://kwmt27.net/2018/09/30/try-develop-like-native-development-with-flutter/</link><pubDate>Sun, 30 Sep 2018 15:45:00 +0900</pubDate><guid>https://kwmt27.net/2018/09/30/try-develop-like-native-development-with-flutter/</guid><description>はじめに2018/09/29(土)にGDG神戸さん主催のFlutter勉強会 (9/29)が開催されました。そこで「AndroidやiOSのアプリ開発でいつも私がやっていることをFlutterでやってみた」というタイトルで約30分間発表させて頂きました。
スライドはこちら
その時の発表内容を書いておきたいと思います。基本的に原稿をもとにブログ用に加筆・修正しています。また図を参照しているところは基本的にスライドを参照いただいて、必要そうなところだけブログ内に画像を貼っています。
冒頭現在Flutterでチャットアプリを作っていてリリース間近なのですが、そのアプリ開発の目的の1つとして、AndroidやiOSのアプリ開発でいつも自分がやっていることはFlutterでできるのか、できるならどうするのかというのを目的に開発していました。
いつもやっていることっていうのは、3つあります。
1つ目は、アプリの設計をクリーンアーキテクチャという設計でやっています。 2つ目は、例えばサーバーの向き先を変えるなど、開発と本番での設定を切り替えることをやっています。 3つ目は、CI/CDサービスを使って、たとえば、git pushしたらビルドやテストを実行し、masterブランチにマージされたら関係者にアプリを配信したりしています。 これらが実現できれば、仕事にも使える可能性はありそうだなという思いで開発し始めまして、結論から言うとできそうということがわかりましたので、それぞれについて紹介したいと思います。
クリーンアーキテクチャが実現できるか?について見ていきましょう。
クリーンアーキテクチャはおそらくボブおじさんという方が考えたんだと思うんですが、ソフトウェア開発の設計方針の一つです。
この図は下のURLから引用したものですが、 アプリのクラスがこの円のように何層かに分かれていて、ここの矢印の方向で、クラスの依存関係を決めましょうと言っているだけです。たとえば、UIはPresenterに依存できますが、PresenterはUIに依存してはいけません。ちなみにこの円の層は何層でも構いません。
このようにすることで、
アプリの根幹となるビジネスロジック部分がフレームワークと切り離すことができ、 ビジネスロジックをテストしやすくなったり、 UIが独立し、ビジネスロジックの変更なしにUIを変更できるようになります。 またデータベースとも独立し、たとえば、いまはFirestoreを使っているけど、AWSのdynamoDBに切り替えたりすることが容易になります。 ここまでが先程のURLにも書いてあるメリットですが、僕がもう1つ思うのは
基本的にどんなアプリやサーバーのソフトウェア開発でも採用できるので、どこに何があるかが統一出来て分かりやすい ということもメリットの一つかなとも思っています。まぁ一言で言うと、メンテナンスしやすい設計ということになります。
もうちょっと図を変えて説明しますね。
顔アイコンはアプリを使うユーザーと思ってください。 その下のScreenというのは、ユーザーがみてる画面で、何でも良いのですが、ここでは例えばチャットルーム一覧画面とします。 チャットルーム一覧のデータは、Firestoreというクラウドのデータベースに保存されているとします。 クリーンアーキテクチャは、このチャットルーム一覧画面がFirestoreからどうやって取得するかの方針になります。
チャットルーム一覧画面は、チャットルームの一覧を表示したいので、チャットルーム一覧を取得するUseCaseというクラスに依頼します。
そのUseCaseクラスはRoomに関するものを提供してくれるRepositoryというクラスに依頼すると、DataSourceというクラスを経由してチャットルーム一覧のデータをFirestoreから 取得し、Screenにチャットルーム一覧のデータを伝えるというのが全体の流れです。
青の矢印はデータ流れを表していて、赤の矢印は依存関係を表しています。 赤矢印の例でいうとたとえば、ScreenはUseCaseに依存していて、UseCaseはRepositoryに依存し、右側のData SourceはRepoistoryに依存しているという感じです。
また、この点線あたりで区切って、それぞれ左からpresentation層、domain層、infrastructure層と僕は呼んでいます。他の参考プロジェクトなんかはinfrastructure層をdata層と呼んだりしています。
先程のボブおじさんの図と重ねるとこんなイメージです。
ごちゃっとしててわかりにくいですかね、、、なんとなく関係ありそうなことがわかりますかね?
次に、この設計をどのように実現しているかを見ていきたいと思いますが、実現するためにには、
言語としてインターフェイスがあることと、 DIができること が必要になります。
まずDartにインターフェイスがあるかですが、結論から言うとあります。 interfaceというキーワードのインターフェイスではないのですが、クラスを定義すると、そのクラスの同名のインタフェースが暗黙的に定義されるという仕様です。また抽象メソッドのみをもつjavaのインターフェイスのようにするには、abstractキーワードで抽象クラスを作成して実現できます。
次にDIですが、詳しくは説明しませんが、DIとはDependency injectionの略で、一言で言うと、「必要なものを外から渡すこと」です。これはだいたいコンストラクタの引数にインスタンスを渡せればよくって、Dartは普通にそれができるので、DIができるかというよりは、依存関係を簡単に解決してくれるDIプラグインはあるか?に言いかえた方が良いかもしれません。 AndroidではDagger2やkodein、iOSではSwinjectとか使っている方が多いでしょうか。このようなプラグインをpub.dartで探しますと、 flutter_simple_dependency_injection というプラグインがあったので、それを使います。
後ほど使い方の例をお見せしますが、名前にあるように使い方はほんとにsimpleです。AndroidのDagger2のように、なぜビルドエラーになるのか悩まされることはありません。
さて、インターフェイスがあって、DIプラグインもあるので、先程の例で挙げたチャットルーム一覧画面のところを具体的に実装して行きたいと思います。
まずチャットルーム一覧を表示したいのでRoomというクラスを作り、あるユーザーのルーム一覧を取得したいのでUserというクラスを、ドメインのモデルに作っておきます。
次にルームリストを取得するというUseCaseの名前を FetchRoomListUseCase としてUseCaseを作ります。これにはexecuteメソッドをもたせ、抽象クラスとして定義します。 これを抽象クラスにしているのは、presentation層とdomain層の境界を疎結合にしたいためです。 また、executeメソッドの戻り値の型をFutureとしていますが、これはJavascriptのPromiseのようなもので、infrastructure層からpresentation層にデータを伝えるために重要な役割になるものです。
FetchRoomListUseCaseを実装するのは、FetchRoomListUseCaseImplクラスです。 FetchRoomListUseCaseImplクラスは、Repositoryからチャットルーム一覧を取得したいので、まだ作成していないですが、RoomRepositoryをもたせています。
RoomRepositoryは抽象クラスとし、 fetchRoomListという抽象メソッドを定義しておきます。 このfetchRoomListメソッドを実装するのは、ここではFirestoreからデータを取得したいのでFirestoreDatasourceというクラスを作成し、そのクラスで実装します。
具体的にFirestoreに保存してあるチャットルーム一覧を取得する処理を書きます。 この取得に成功すると、先程のFutureの仕組みでpresentation層のチャットルーム一覧画面に伝わるようになります。
これでUseCase以降のチャットルーム一覧を取得するのに必要なクラスを作成したので、あとはそれをつなぎます。
たとえば、これは先程のFirestoreDatasourceのコンストラクタの部分ですが 、FirestoreDatasouceはfirestoreがほしいと要求しているので、firestoreインスタンスを生成して、DIプラグインから取得したinjectorにfirestoreをセットします。真ん中あたりのところです。
次に一番下のあたりで、injectorにFirestoreDatasourceインスタンスを生成してセットしたいのですが、このときinjectorからFirestoreインスタンスを取得することができるようになっているので、Firestoreインスタンスを取得して、FirestoreDatasourceの引数に渡してあげます。 このようにして依存関係を解決していくだけです。
UseCaseなども同様に依存関係を解決すると、このようになります。 ここまででFetchRoomListUseCaseまでインスタンス生成できたことになります。</description></item><item><title>Intro to Flutter</title><link>https://kwmt27.net/2018/09/15/intro-to-flutter/</link><pubDate>Sat, 15 Sep 2018 16:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/09/15/intro-to-flutter/</guid><description>はじめに2018/09/15(日)にクラスメソッドさん主催のモバイルメソッド大阪第二回が開催されました。そこで「Intro to Flutter」というタイトルで発表させて頂きました。
スライドはこちら
その時の発表内容を書いておきたいと思います。基本的に原稿をもとにブログ用に加筆・修正しています。
冒頭こんばんは!新しいiPhone出ましたね! なんか新しいサイズが増えたとかなんとか。。 この資料作ってて全然キャッチアップできてないので、懇親会とかで教えて頂けたら嬉しいです。
余談でしたが、始めます。
今、僕自身がFlutterというものを使ってモバイルアプリを作成するのにハマっているので、Flutterの紹介させて頂きたと思います。
まず自己紹介でチャットアプリを作成中で下記の動画で紹介しました。
現在Flutterでチャットアプリを作成中でして、ちょっと動画あるので再生しますね。 SNSログインして、チャットルームを作成します。このときチャットルームの写真を撮っています。チャットルーム名にGopherと入れて、Gopherという名前のチャットルームができました。 そのGopherのチャットルームに入って、メッセージを送信しているという動画です。
このチャットアプリは現在Deploygateにて配信中で、インストールしてためしていただくこともできますので、もしご興味があればお声がけください。
さて、本題に入ります。
今日持って帰って頂きたいものは、Flutterというものがどういうものか知って、Fluttterを触ってみたくなることが目標です。
話さないことととしては、Flutterは時折、React NativeやXamarinと比較されることがありますが、僕自身React NativeとXamarinは触ったことがありませんので、違いについては話しません。
突然ですがここにモバイルアプリを開発できるエンジニアが一人いるとします。
このとき、たとえば
お客さんからAndroidとiOSのアプリを作ってくださいと言われたら、 個人開発でAndroidとiOS応のアプリを作りたいなぁと思ったら、 みなさんならどうしますか? お仕事の場合は、例えば日本人向けのアプリだからまずはiOSからつくったりして、 お客さんからもうちょっとこうしたいなぁ、という要望だったり このパターンでおちるんだけど、、、というクレームだったり
とかいろいろ対応していたら1ヶ月予定が2ヶ月、3ヶ月と過ぎてしまい、なかなかAndroidの開発できない・・・
個人の場合も、
例えば日本人向けのアプリだからまずはiOSからつくって、 大体できたんだけど、ここ使いにくいから、もうちょっとこうしたいなぁ。 あ、使ってみて思ったけど、あの機能絶対リリースまでにはいるやん! とか対応していたら、こちらの場合も1ヶ月予定が2ヶ月、3ヶ月過ぎてしまい、なかなかAndroidの開発できない・・・
となって、例えばiOSリリースだけで満足してしまうことってないですか?
もちろんお仕事の場合はスケジュール管理しながら進めていくと思いますのでそんなことはないと思いますが。
このようなとき、
もし、ネィティブ並みにサクサク動くアプリが1つのソースコードコードで書けるとしたら? もし、プログラミング言語がkotlinやswiftとは違うけど、そこそこいい感じの言語だったとしたら? もし、開発スピードを上げれるとしたら? iOSだけ作ってAndroidができないとか、またはリリース時期が遅くなるということはなくなりそうな気がしませんか?
これらを解決できるのがFlutterです。
FlutterとはFlutterとはAndroidと iOSアプリを1つのソースコードで開発できるtool kit です。
プログラミング言語にはDartを採用しています。
Flutterはハイパフォーマンスのレンダリングエンジンを持っていて、DartコードはネイティブARMコードにコンパイルされます。
そのため、こちらのFlutterで作成されたアプリの動画を見ていただきたいのですが、
どうですか?なかなかきれいでサクサク動いてそうなイメージ湧きませんか?
これらのUIがどのように構成されているかですが、 画像もボタンもテキストもアイコンもこれらすべてWidgetとよばれるものから構成されています。 ちょっと別の例を見てみましょう。
こんなレイアウトがあるとします。 これがどのような構成になっているか、分けてみますと、
一番上から画像、星印の行、電話とかRouteとかShareボタンの行、あとは説明の行と、縦に並んでいることが分かるかと思います。 その下の図は飛ばして、下図はボタンの行がどのようなレイアウト構成になっているかを示したものですが、
まずCALLやROUTEボタンなどが横に並んでいて、それぞれのボタンはアイコンとテキストが縦に並んでいるのがわかるかと思います。 この一つのボタンに注目して、コードではどのように書くのかを見てみたいと思います。
左の画像は、先程SHAREボタン部分を拡大したものです。 右のコードは左のボタンを表すコードになります。 FlutterではレイアウトはDartコードで書きます。AndroidのようなレイアウトxmlやiOSのようなinterface builderのようなものありません。ザッツ・オールです。
このSHAREボタンはアイコンとテキストが縦に並んでいるというレイアウトです。
まずColumnで囲った縦方向にレイアウトしますよと宣言します。このColumはWidgetです。 何を縦方向にレイアウトするかですが、ここではアイコンとテキストを入れます。 これらのアイコンとTextもWidgetです。 他の複雑なレイアウトも同じようにしていくだけです。 こうして構築したレイアウトはAndroidとiOSの両方で動きます。
Dartはそこそこ良いコードを少し見たので、次にDartがそこそこ良いということについてお話します。 少し言語仕様を紹介すると、DartはJavaやjavascriptに似た言語だと思います。</description></item><item><title>Android Studio3.1のrecentProjects.xmlファイルのパス</title><link>https://kwmt27.net/2018/09/05/android-studio-recentprojects/</link><pubDate>Wed, 05 Sep 2018 19:45:00 +0900</pubDate><guid>https://kwmt27.net/2018/09/05/android-studio-recentprojects/</guid><description>最近なぜかAndroid StudioのFileメニューのOpen Recentから開くと、Android Studioが固まってしまうという現象に陥ってしまっています。
プロセスをkillして再起動してもダメで、recentから起動するとダメだからそのあたりを消してしまおうということで探した結果、下記にありました。
~/Library/Preferences/AndroidStudio3.1/options/recentProjects.xml このファイルを下記のような感じにして保存してAndroid Studioを開き直したら動いてくれました。
&lt;application&gt; &lt;component name=&#34;RecentProjectsManager&#34;&gt; &lt;/component&gt; &lt;/application&gt;</description></item><item><title>Flutterでスクロールを検知し、ある位置までスクロールしたらWidgetを表示するには</title><link>https://kwmt27.net/2018/09/03/flutter-scroll/</link><pubDate>Mon, 03 Sep 2018 11:15:00 +0900</pubDate><guid>https://kwmt27.net/2018/09/03/flutter-scroll/</guid><description>やりたいことFlutterで、下図のように上にスクロールしてある一定の位置まで来たらWidgetを表示させ、下にスクロールしてある一定の位置まで来たら表示したWidgetを消すというのをやりたい。
どうやって? スクロールを検知するListenerをセットする そのListenerでスクロール位置を計算してWidgetの表示・非表示を切り替える。 1. スクロールを検知するListenerをセットするFlutter標準のScrollControllerクラスを使って、ScrollController _scrollController;と変数宣言し、initState()で初期化、dispose()で後処理しておきます。
ScrollController _scrollController; @override void initState() { super.initState(); _scrollController = ScrollController(); } @override void dispose() { _scrollController.dispose(); super.dispose(); } ListView.builderにScrollControllerをセットできるので、先程宣言した_scrollControllerをセットします。
Widget _buildListView() { return ListView.builder( controller: _scrollController, reverse: true, itemCount: messages != null ? messages.length : 0, itemBuilder: (BuildContext context, int position) { return _buildMessageRow(context, position); }, ); } _scrollControllerにスクロールを検知したときに処理をしたいリスナー(ここでは_scrollListener)を追加します。
@override void initState() { super.initState(); _scrollController = ScrollController(); _scrollController.addListener(_scrollListener); // ←追加 } void _scrollListener() { // スクロールを検知したときに呼ばれる } これで、スクロールを検知することができるようになりました。</description></item><item><title>Flutterでテキストフィールドが最大3行になるようにするには</title><link>https://kwmt27.net/2018/08/22/flutter-textfield/</link><pubDate>Wed, 22 Aug 2018 23:35:00 +0900</pubDate><guid>https://kwmt27.net/2018/08/22/flutter-textfield/</guid><description>やりたいことFlutterで、LINEでメッセージ入力するときのように、テキストフィールドが最大3行になるようにしたい。 つまり、下の動画のようにしたい。
コード例とポイント説明ポイントとなる部分だけのコードと説明します。
TextEditingControllerを使って、TextFieldに入力されたテキスト取得できるようにしておきます。
また、TextFieldになにか変更があったら通知されるlistenerを登録します。
_textEditingController.addListener(_textEditListener); このとき通知される関数はここでは_textEditListenerとしていて、変更があるたびに _maxLinesにセットされます。
次に、TextFormFieldのプロパティのkeyboardTypeは複数行に最適なmultilineを設定し、キーボードのエンターキーに当たる部分の改行できるように変更します。
keyboardType: TextInputType.multiline, textInputAction: TextInputAction.newline, maxLinesはnullを指定すると、どこまででも改行します。
maxLines: _maxLines これらを組み合わせて、テキストが入力されるたびに改行コードを数え、改行コードが2つ以上(全体としては3行になっている)の場合は、maxLinesを3に設定すればいいので、_textEditListener関数で次のようにしています。
void _textEditListener() { setState(() { // TextFieldに改行が2つ以上入っていたら、3行以上になるので、3行までに止める。 _maxLines = &#39;\n&#39;.allMatches(_textEditingController.text).length &gt;= 2 ? 3 : null; }); } これで最初の動画のような動きになります。</description></item><item><title>Flutterあるある</title><link>https://kwmt27.net/2018/08/16/flutter-workshop/</link><pubDate>Thu, 16 Aug 2018 19:35:00 +0900</pubDate><guid>https://kwmt27.net/2018/08/16/flutter-workshop/</guid><description>はじめに2018/08/12(日)にGDG神戸主催のFlutter勉強会が開催されました。勉強会全体に関しては こちらのブログを見ていただいて、ここでは僕が「Flutterあるある」というタイトルでLT(LT資料はこちら)したので、それについて書きたいと思います。
基本的に原稿をもとに加筆・修正しています。
Flutterあるあるまず自己紹介でチャットアプリを作成中で下記の動画で紹介しました。
このアプリを作成中にいろいろあったので、これあるあるだなぁと思ったことを3つほど共有したいと思います。
このチャットアプリはまだ公開できる状態じゃないのですが、インストールしてためしていただくこともできますので、ご興味があれば声かけてください。
公式ドキュメントに書いてるプラグインが動かないことがある本題です。まず、あるあるの1つ目は、公式ドキュメントに書いてるプラグインが動かないことがある。です。
公式ドキュメントの書いてある以上、動いてほしいよねという話なのですが、 たとえば、画像キャッシュしたいと思って、「flutter cache image」と検索すると、 cached_network_imageプラグインというのが公式ドキュメントに載っているのが見つかります。
これを使おうとして、flutter packages getすると、「cached_network_imageはuuidプラグインに依存していてバージョン0.5.3が必要です」というエラーが出てしまいました。これはuuidプラグインのバージョン1.0.0以上を使っている場合にエラーになります。
issueを見てみると、29日前にissueが上がってたり、
プルリクエストまで出ているのに、とくにメンテされる気配がなさそうでした。。。 そんなときは、pubspec.yamlは直接githubリポジトリを参照することができるので、動かないgithubリポジトリをforkして修正すれば、本家のプラグインが動かなくても大丈夫です!
ここでは、pubspec.yamlはgitリポジトリを参照できますよ、ということを言いたかっただけです。
Google製プラグインが動かないことがある2つ目はGoogle製プラグインが動かないことがありました。 firebase_messagingプラグインを使って Androidにプッシュ通知を送ったところ、送った時点でクラッシュするという致命的な現象に遭遇しました。
これはissueがあって、プルリクエストがない状況でして、たまたま原因がわかったのでプルリクエストを送りました。
プルリクエストを送ったところ、2週間弱ぐらい反応なくて、他の人が突っついたら動き始めてくれました。
このプルリクエスト自体は他のプラグインの絡みでマージされなかったのですが、修正してもらって、現在のバージョンではプッシュ通知が届いたときにクラッシュしなくなっています。
ここでは、プルリクエストは気軽にできるよ!ってことを伝えたかったです。
AndroidとiOSで動きが異なる最後は、AndroidとiOSで動きが異なるというあるあるです。これが一番あるあるかなぁなと思いますが、僕が遭遇したのはQRコードリーダーのプラグインです。
QRコードを読み取るプラグインはいくつかあって、たとえば、qr_readerというプラグインがあります。
Androidで動かすとカメラ画面が全画面になっていますが、
iOSでは全画面ではなく、中央部分のみカメラ画面があるという感じになっていました。
ほかにはbarcode_scanというプラグインがあります。
これもちょっと異なっていて、iOSは全画面表示でとくに枠とかないのですが、
Androidは全画面表示で枠があるデザインになっていました。
今回のチャットアプリに関してはこれで妥協しているのですが、必要ならプルリクエストするか、自分でプラグインを作る必要がありそうかなぁと思います。
まとめ動かなかったり、AndroidとiOSで期待する動きと異なっている場合がありますが、githubリポジトリを参照できるのでなんとかなりますし、たとえ一部でも修正できればプルリクエストを送ってみてください。なんとかなります。 ということで、まとめとしては「なんとかなる」ですw
まだまだ微妙なところがあるflutterですが、ワンソースで両OS対応できるのは魅力的なので今後も追っかけていきたいと思います。
付録と、まぁLTはここまでだったんですが、他にも2つほど考えていたけどLT時間内に入り切らなかったので泣く泣く除いたあるあるをここでご紹介。
Dart Packagesサイトとgithubの情報が違うことがあるプラグインの情報は、pub.dartlang.org(ここではDart Packagesサイトと呼ぶことにします)で探すか、ググったらだいたいここに行き着くと思います。
それで、Dart PackagesサイトのREADMEをまずは見ると思いますが、Dart Packagesサイト側のREADMEを読んでもうまく動かず、GithubのREADMEを読んだらうまくいったということがありました。
具体的には、いまは修正されてるのですが、image_pickerというプラグインで、iOSではNSMicrophoneUsageDescriptionの設定が必要なのに、Dart PackagesサイトのREADMEには書いてなく、GithubのREADMEには書かれていたという事がありました。
これはTwitterで教えて頂いたのですが、Dart PackagesサイトはpublishしたときにしかREADME更新できないようで、publishするにはバージョンを上げる必要があるみたいで、README更新するだけのためにバージョンを上げるのも、、、感があるのかもということでした。
ですので、Dart Packagesサイトを見るのもいいですが、できるだけGithubの方を見ておくと幸せになれるかもしれませんね。
masterチャンネルで動かないことがあるもう1つは、masterチャンネルで動かないのことがある、ですが、flutterには channelというgitのブランチのようなものがあって(というか実態はgitのブランチだと思いますが)、flutter channelというコマンドで自分がいまどのチャンネルにいるか確認できます。下記の例だとmasterチャンネルにいます。
$ flutter channel Flutter channels: beta dev * master この状態で開発していると、ビルドエラーにビルドエラーになることがありました。具体的には、ランチャーアイコンを生成するflutter_launcher_iconsプラグインを使って、アイコンを生成するコマンドを叩くと、下記のようにエラーが出ました。
% flutter pub pub run flutter_launcher_icons:main Failed to precompile flutter_launcher_icons:main: file:///usr/local/flutter/.</description></item><item><title>Flutterで画像を角丸にするには</title><link>https://kwmt27.net/2018/08/05/flutter-image-rounded-corner/</link><pubDate>Sun, 05 Aug 2018 21:28:00 +0900</pubDate><guid>https://kwmt27.net/2018/08/05/flutter-image-rounded-corner/</guid><description> こんな感じに画像を角丸にするには、ClipRRectを使うと良さそう。
SizedBox( height: 180.0, child: Container( child: ClipRRect( borderRadius: BorderRadius.circular(8.0), child: Image.network( message.downloadImageUrl.toString(), fit: BoxFit.cover, )), )); 参考 Rounded Corners Image in Flutter</description></item><item><title>Firebase Cloud Messaging(FCM)のトピックについて</title><link>https://kwmt27.net/2018/08/04/firebase-messaging-topic-condition/</link><pubDate>Sat, 04 Aug 2018 22:00:11 +0900</pubDate><guid>https://kwmt27.net/2018/08/04/firebase-messaging-topic-condition/</guid><description>Firebase Cloud Messaging(FCM)はTopicをSubscribeすることができて、サーバーはそのSubscribeしたTopicに対して送信することができます。
複数のTopicをSubscribeすることができるのですが、複数のTopicに対して送信するにはconditionを使うことができます。これはドキュメントに記載してあり、引用すると、
&ldquo;condition&rdquo;: &ldquo;&lsquo;dogs&rsquo; in topics || &lsquo;cats&rsquo; in topics&rdquo;,
このように、dogsトピックを購読しているかcatsトピックを購読している端末に送信することができます。
では、たとえばanimalトピックを購読している端末には送信したいんだけど、dogsトピックを購読している端末には送信したくない場合はどのようにするか。
次のようにすることができます。
&ldquo;condition&rdquo;: &ldquo;&lsquo;animal&rsquo; in topics &amp;&amp; !(&lsquo;dogs&rsquo; in topics)&rdquo;,
これはドキュメントに記載してあります。
ちょっとハマったのが変数の使い方です。結論からいうとシングルクォートが必要だったのですが、
const condition = `\&#39;${animal}\&#39; in topics` animalが変数とした場合、このようにすればOKでした。
どのTopicを購読しているかを知りたいどのtopicをsubscribeしているかを確認するには、下記のエンドポイントを使います。
https://iid.googleapis.com/iid/info/IID_TOKEN ドキュメントはこちらです。
以下はサンプルのリクエストとレスポンスです。
リクエスト curl -H &#34;Authorization: key=&lt;Server Key&gt;&#34; https://iid.googleapis.com/iid/info/&lt;registration_token&gt;?details=true レスポンス { &#34;applicationVersion&#34;: &#34;1&#34;, &#34;connectDate&#34;: &#34;2018-08-03&#34;, &#34;attestStatus&#34;: &#34;NOT_ROOTED&#34;, &#34;application&#34;: &#34;&lt;application id&gt;&#34;, &#34;scope&#34;: &#34;*&#34;, &#34;authorizedEntity&#34;: &#34;xxxxxxxxxxxx&#34;, &#34;rel&#34;: { &#34;topics&#34;: { &#34;topic1&#34;: { &#34;addDate&#34;: &#34;2018-08-02&#34; }, &#34;topic2&#34;: { &#34;addDate&#34;: &#34;2018-08-01&#34; }, &#34;topic13&#34;: { &#34;addDate&#34;: &#34;2018-08-01&#34; } } }, &#34;connectionType&#34;: &#34;WIFI&#34;, &#34;appSigner&#34;: &#34;d9xxxxxxx&#34;, &#34;platform&#34;: &#34;ANDROID&#34; }</description></item><item><title>Flutterのキーボードを閉じるには</title><link>https://kwmt27.net/2018/07/29/flutter-dismiss-keyboard/</link><pubDate>Sun, 29 Jul 2018 03:50:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/29/flutter-dismiss-keyboard/</guid><description>はじめにFlutterでLINEのようなチャットアプリを作っていて、TextFormでキーボードが表示されたら、Androidはバックキーでキーボードを閉じれるけど、iOSはバックキーないので閉じることができなかったので、キーボードを閉じる方法をメモ。
キーボードを閉じるにはGestureDetector( onTap: () =&gt; FocusScope.of(context).requestFocus(FocusNode()), child: listView, ) このようにタップイベントでキーボードのフォーカスを外すことで、キーボードを閉じるようです。 listViewだけにGestureを設定しているのは、TextFormFieldを含むWidgetに対してGestureを設定すると、キーボードが上がってる状態でTextFormFiledをタップすると、一旦閉じてまたキーボードが立ち上がってしまうため、listViewのみに設定しています。
キーボードを閉じるには 別の方法(2020/04/07追記)FocusScope.of(context).unfocus() 参考 https://github.com/flutter/flutter/issues/7247#issuecomment-406178161 https://stackoverflow.com/questions/44991968/how-can-i-dismiss-the-on-screen-keyboard#44991969</description></item><item><title>Flutterの画面遷移をモーダルにするには</title><link>https://kwmt27.net/2018/07/28/flutter-navigator-modal/</link><pubDate>Sat, 28 Jul 2018 23:43:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/28/flutter-navigator-modal/</guid><description>結論PageRouteクラスに、fullscreenDialogプロパティがあるので、trueを設定するだけ。
これで、iOSのUINavivationControllerのpushの画面遷移の仕方でなく、モーダルで立ち上がるような遷移になる。
左上のボタンも←から☓に変わってくれる。
実装例いま作ってるアプリでは、こんな感じのメソッドを自分のAppNavigatorみたいなクラスに書いてます。
Future&lt;T&gt; _showScreen&lt;T extends dynamic&gt;( BuildContext context, String routePath, Widget destinationScreenWidget, {bool modal = false}) { return Navigator.push( context, MaterialPageRoute&lt;T&gt;( settings: new RouteSettings(name: routePath), builder: (BuildContext context) { return new Theme( data: AppConfig.kTheme .copyWith(platform: Theme.of(context).platform), child: destinationScreenWidget, ); }, fullscreenDialog: modal), ); 参考 Flutter GalleryのMaterial -&gt; Dialogs -&gt; FULLSCREENで動きを確認できる Flutter Galleryのソースはこちら 最後に&ldquo;flutter modal&quot;とググっていて、全然引っかからなくて、しばらく諦めてたんですが、絶対あるはずということで根気よく調べたら、&ldquo;flutter popup screen&rdquo;で検索したら、こちらのブログを見つけて、「あー、モーダルってダイアログでしたね。。」となっているところです。。。</description></item><item><title>FlutterでFileのファイル名を取得するには</title><link>https://kwmt27.net/2018/07/25/flutter-file-name/</link><pubDate>Wed, 25 Jul 2018 01:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/25/flutter-file-name/</guid><description>pathパッケージをimportして、
import &#39;package:path/path.dart&#39;; basenameを使う。
File file = File(&#34;dir/name.png&#34;); print(basename(file.path)); /// output: /// name.png 参考 https://stackoverflow.com/a/50439988 https://pub.dartlang.org/documentation/path/1.3.6//path/path-library.html</description></item><item><title>Flutterでバックキーイベントを検知するには</title><link>https://kwmt27.net/2018/07/18/flutter-onbackpressed/</link><pubDate>Wed, 18 Jul 2018 16:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/18/flutter-onbackpressed/</guid><description>方法Flutterでバックキー(AndroidのonBackPressed)イベントを検知するには、WillPopScopeクラスを使う。
サンプル @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () { // バックキーを押すとここに来る。 // popしてあげないと、閉じてくれない。 Navigator.of(context).pop(); }, child: Scaffold( // 省略 ), ); } 参考 https://stackoverflow.com/a/50459239 https://docs.flutter.io/flutter/widgets/WillPopScope-class.html</description></item><item><title>Wifiでadb接続する</title><link>https://kwmt27.net/2018/07/10/adb-wifi/</link><pubDate>Tue, 10 Jul 2018 21:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/10/adb-wifi/</guid><description>Wifi経由でadb接続するには 端末とUSBで接続する
認識されてることを確認
% adb devices List of devices attached &lt;端末&gt; device adb tcpip PORTを叩く
% adb tcpip 5555 restarting in TCP mode port: 5555 adb serverがリスタートします。
adb connect &lt;端末のIPアドレス&gt; 端末に接続します。
% adb connect &lt;端末のIPアドレス&gt; connected to &lt;端末のIPアドレス&gt; このようにconnectedと出たら、完了です。USB外してもadb devicesで端末が表示されるはずです。
% adb devices List of devices attached &lt;端末のIPアドレス&gt;:5556 device もし adb connectできなかったらadb connectしたときに、下記のように接続できないことがありました。
% adb connect &lt;端末のIPアドレス&gt; unable to connect to &lt;端末のIPアドレス&gt;:5555: Operation timed out その場合は、PORTを変えてみてください。自分の場合はこれで繋がりました。
% adb tcpip 5556 restarting in TCP mode port: 5556 % adb connect &lt;端末のIPアドレス&gt;:5556 connected to &lt;端末のIPアドレス&gt;:5556</description></item><item><title>Flutter アイコンリスト</title><link>https://kwmt27.net/2018/07/09/flutter-icon-list/</link><pubDate>Mon, 09 Jul 2018 22:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/07/09/flutter-icon-list/</guid><description>Flutterのアイコンリストは公式ドキュメントにあるhttps://docs.flutter.io/flutter/material/Icons-class.html
以上。</description></item><item><title>Building Layouts in Flutterを読んだときのメモ</title><link>https://kwmt27.net/2018/06/24/building-layouts-in-flutter/</link><pubDate>Sun, 24 Jun 2018 16:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/24/building-layouts-in-flutter/</guid><description>はじめにBuilding Layouts in Flutterを読みながら実際にコードを書いていったときのメモです。
メモ Containerはその子供のWidgetをカスタマイズすることができる
パディング、マージン、ボーダー、背景色などを追加したいとき、Containerを使う レイアウトを基本要素に分割
RowとCoumnを見分ける レイアウトにグリッドはあるか? オーバーラップする要素はあるか? UIはタブが必要か? アライメントやパディング、ボーダーが必要なエリアに注目 プロジェクト内の画像の使うには 画像はプロジェクトルートにimagesディレクトリを作ってその中に配置し、pubspec.yamlにassets項目を追加する。
assets: - images/lake.jpg 画像を使いたいところで、たとえばImage.asset()を使う
body: new ListView( children: &lt;Widget&gt;[ new Image.asset( &#39;images/lake.jpg&#39;, width: 600.0, height: 240.0, fit: BoxFit.cover, ), fitプロパティの指定は、ドキュメントに画像付きで書かれてるいるのでわかりやすい
https://docs.flutter.io/flutter/painting/BoxFit-class.html BoxFit.coverはAndroidのImageView.ScaleTypeでいうところのCENTER_CROPかな?! Image Classのドキュメント
https://docs.flutter.io/flutter/widgets/Image-class.html 左寄せにするにはcrossAxisAlignment: CrossAxisAlignment.start, ドキュメント https://docs.flutter.io/flutter/rendering/CrossAxisAlignment-class.html#constants 余白を追加するにはContainerでラップして、paddingにEdgeInsetsを使う。
例えば、&lsquo;Oeschinen Lake Campground&rsquo;というテキストと&rsquo;Kandersteg, Switzerland&rsquo;というテキストの間に8px余白を取りたい場合は次のようになる。
child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: &lt;Widget&gt;[ new Container( padding: const EdgeInsets.only(bottom: 8.0), child: new Text(&#39;Oeschinen Lake Campground&#39;), ), new Text(&#39;Kandersteg, Switzerland&#39;) ], ) これをビルドすると、下図の赤枠の部分の余白ができる。</description></item><item><title>Dart2のコンストラクタがわからなかったのでメモ</title><link>https://kwmt27.net/2018/06/23/dartlang-class/</link><pubDate>Sat, 23 Jun 2018 15:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/23/dartlang-class/</guid><description>はじめにflutterを触りはじめて、rxあるのかな?と思って調べたら
https://github.com/ReactiveX/rxdart
ありました。どのように使うかサンプルを読んでたんですが、クラスのコンストラクタ部分が分からない・・・
サンプルでいうと下記の部分です。
class SearchBloc { final Sink&lt;String&gt; onTextChanged; final Stream&lt;SearchState&gt; state; SearchBloc._(this.onTextChanged, this.state); factory SearchBloc(GithubApi api) { final onTextChanged = new StreamController&lt;String&gt;(); final state = new Observable&lt;String&gt;(onTextChanged.stream) // If the text has not changed, do not perform a new search .distinct() // Wait for the user to stop typing for 250ms before running a search .debounce(const Duration(milliseconds: 250)) // Call the Github api with the given search term and convert it to a // State.</description></item><item><title>flutter Google SignInのexampleをやってみた</title><link>https://kwmt27.net/2018/06/22/flutter-google-signin/</link><pubDate>Fri, 22 Jun 2018 09:50:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/22/flutter-google-signin/</guid><description>はじめにflutter で google singinをやってみた
https://github.com/flutter/plugins/tree/master/packages/google_sign_in
iOS Android メモ Firebaseのプロジェクトつくったりgoogle-services.jsonやplistを作ってプロジェクトに格納したりするのは、このYoutubeがわかりやすいかも
AndroidはSHA1のフィンガープリントを追加する必要がある
デバッグ用のフィンガープリントの確認方法(パスワードはandroid) % keytool -exportcert -list -v \-alias androiddebugkey -keystore ~/.android/debug.keystore SHA256も表示されるが、そっちじゃなくてSHA1の方なので注意 iOSはInfo.plistに下記を設定(READMEに記載あり)
&lt;!-- Put me in the [my_project]/ios/Runner/Info.plist file --&gt; &lt;!-- Google Sign-in Section --&gt; &lt;key&gt;CFBundleURLTypes&lt;/key&gt; &lt;array&gt; &lt;dict&gt; &lt;key&gt;CFBundleTypeRole&lt;/key&gt; &lt;string&gt;Editor&lt;/string&gt; &lt;key&gt;CFBundleURLSchemes&lt;/key&gt; &lt;array&gt; &lt;!-- TODO Replace this value: --&gt; &lt;!-- Copied from GoogleServices-Info.plist key REVERSED_CLIENT_ID --&gt; &lt;string&gt;com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; &lt;/array&gt; &lt;!-- End of the Google Sign-in Section --&gt; google signinのexampleはPeople APIを有効にしないと403が返ってくる</description></item><item><title>flutter codelabをやってみた</title><link>https://kwmt27.net/2018/06/21/flutter-codelab/</link><pubDate>Thu, 21 Jun 2018 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/21/flutter-codelab/</guid><description>はじめにflutter codelabをやりました。
そのときのメモです。やった成果はこちら
https://github.com/kwmt/flutter-codelab
メモ Android StudioでiOS,Androidビルドできてインストールできる
⌘+sでホットリロード
反映されるのが早すぎて感動 iOS、Android両方同時にはできないのか? コード上でレイアウトを作成する(xmlとかない?)
アイコンもコードから書ける
trailing: new Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), タップイベントは、onTapで
リストのitemやcell上のタップイベントはListTileのonTapで書ける
リストにnofifyするのはsetStateになる
onTap: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, AppBarにボタンをおける
画面遷移はNavigator.pushで遷移
iOSはUINavigtaionControllerの動き AndroidはstartActivityの動きになる(が、少しぎこちない?ので対策はあるのだろうか・・・) テーマ変更が超簡単
Widget build(BuildContext context) { return new MaterialApp( title: &#39;Welcome to Flutter&#39;, + theme: new ThemeData( + primaryColor: Colors.white + ), home: new RandomWords(), ); } デフォルトテーマ 変更後</description></item><item><title>navigation-uiライブラリは、既存のアプリを置き換えることができないかもしれない</title><link>https://kwmt27.net/2018/06/09/umeda-apk/</link><pubDate>Sat, 09 Jun 2018 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/09/umeda-apk/</guid><description>はじめにumeda.apk #4でLTした内容です。
スライドはこちらです。
スライドの概要navigation-uiライブラリというのがあって、Navigation Drawerとか使うのに超便利になったんですが、startDestination以外の画面に遷移すると、ハンバーガーアイコンが戻る矢印に変わってしまうので、微妙に使えないんじゃないかという話です。
戻る矢印に変わってしまうと、ユーザーは絶対気づかないやつだと思うし、既存のNavigation Drawerを使ったアプリを置き換えることができないと思うのですが、僕だけでしょうか。。。
もしこれが問題だと思う方は、このissueにスターやコメントして、改善してもらえるような方向になると、いいかなと思いますので、ぜひよろしくお願い致します。</description></item><item><title>メルチャリを使ってみて、いくつか課題がありそうだったのでつらつら書いてみた</title><link>https://kwmt27.net/2018/06/04/merchari/</link><pubDate>Mon, 04 Jun 2018 20:30:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/04/merchari/</guid><description>はじめにメルチャリを使ってみて、いくつか課題がありそうだなぁと思ったのでつらつら書いてみます。
「〜問題」と書いてますが、語呂が良かったので使ってるだけで、大きな問題というわけではありませんが、こういうところがちょっときになったので、こうしたほうがいい(してほしい)みたいな感じで書いています。中には僕が気づいてないだけというのもあるかもしれませんが、ご容赦ください。
San FranciscoでのLimeBikeがめちゃくちゃ良い体験ができた(歩くには遠いけどUberを使うほどじゃないとか、街並みを見ながら散策したいとかできた)ので、メルチャリもよりよりサービスになることに期待を込めて書かせて頂きました。
メルチャリの中の人も、認識しているものもあるかもしれませんが、思ったことを書いてみます。
解決したらいいなと僕が思った課題たちいくらか使ってみるまでわからない問題料金についてホームページに書かれて無いので、使ってみるまでわかりませんでした。しかも15分無料チケットが6枚ほどついていて、15分超える利用をしないとわかりませんでした。
料金について、具体的な金額を明記してほしいと思いました。
・・・と思いましたが、改めてヘルプの「メルチャリについて」を見てみると、書いてましたね・・・。
気づきませんでした。。すみません。
どうやって支払いをすればいいかわからない問題ヘルプの「トラブルシューティング]」の項目に、「料金・支払い」の項目があって、「料金・支払い」はトラブルシューティング?と、少し疑問で直感的じゃない気がします。
「料金・支払い」は「トラブルシューティング」と同列においてもいいかと思います。
それはさておき、ヘルプには、
「どこのコンビニで支払えますか?」や「支払いに利用可能なクレジットカードを教えてください」という項目がるので、コンビニかクレカで支払えるんだろうなとは思うのですが、クレカで支払う場合は、クレカをアプリに登録してるわけでもないので、どうやってクレカで支払うのかわからないですし、コンビニの場合は、請求書が送られてるくるのか?送られてるくるにしても、住所登録してないし、、ということで、ちょっとどうやって支払ったらいいかわからないです。
メルカリアプリと連携しているのだとしても、それがわかるような動線があるといいかなと思いました。 まぁ、メルカリアプリでもクレカとか住所とか登録してなんですが、どうやって支払いすればいいのか・・・
Lime BikeやUberはまずクレジットカードを登録しないと使えなかったので、そのぐらいしたほうがわかりやすいかもしれません。
ポートが空いてなかったらどうしよう問題2回使ってみたのですが、2回とも、特定のポートに止めよう!と思ってメルチャリを借りました。 ポートが空いてるかどうかは、たとえば利用可能台数が0/3とかで表示されてるので、借りる時点ではポートが空いてることがわかります。
しかし、予約とかができないため、チャリで走っている間にそのポートが埋まってしまう可能性があり、その場合は別のポートに移動しなければならず、ポートが遠かい場合は、なかなかつらいものがあります。
今回2回とも、ポートが埋まってることはなかったのですが、気になったの書きました。
ポート空いてるか表示上分かりにくい問題上記のことがあるので、ポート空いてるかドキドキしながら、移動してました。 そういえばポート空いてるのかな?とアプリを見ると、地図上は0となっているから大丈夫だろうという判断を1回目乗ったときはしてました。 しかし、ポートの詳細画面に、3台空いてます(表記わすれました)のような文言が緑で書いてましたが、少し小さいかなぁと思ったのと、チャリで移動中には詳細はあまり見ず、どのようにそのポートに行けばいいかという地図をみるので、地図側に空き状況が○△☓などの記号で表示されているのはいいのですが、あと何台停めることができるか、具体的な数字が書かれてると、残り3台停めれたりすると、ちょっとゆっくり行って誰かに取られても余裕だなと思うし、残り1台なら、ちょっと急がないとなって思って急ぐかなぁと思いました。
ポート以外に停めたら何か罰則があるかわからない問題目的のポートが空いてなくて、空いてるポートが近くになくて、めっちゃ急いでる場合、ポート以外のそのへんの路上に停めたくなりそうなのですが(そんなことしないですが)、その変に停めたらなにか罰則があるのか分かりにくいかなぁと思いました。
どこかに書いてるのかもしれませんが見つけることができず、わかりやすい場所に書いてもらえると嬉しいです。
実際に鍵が空いてるかどうかとアプリが同期していない問題これはアプリ上から簡単に報告したのですが、3回目借りようと思って、鍵を開けるためにQRコードを読み取ったのですが、鍵が開いた音はしたのですが、実際には鍵が開いてなくて、しかもアプリはライド中になって時間が進んでしまっていました。
鍵が開いてないとわかって、すぐにライド終了したのですが、実際の鍵の開閉状況とアプリが同期していないんだなぁと理解しました。
いまは無料チケットがあるので無料でしたが、チケットがない場合はちょっと損した気分になりそうかなと思いますので、同期できるようになるといいですね。
ライド開始後、すぐにライド終了して、再度鍵を開けようとしたら、使えませんと表示された問題上記の鍵が開いた音はしたが、実際には鍵が開いてなく、すぐライド終了したにつながるのですが、ライド終了したあと、もう一回鍵を開けようしたら、アプリ上でエラーが出て(エラー文言は忘れましたが)、使えませんでした。
ライド終了後、すぐには鍵開けれないんですかね?
鍵が故障してそうなので、そのメルチャリは使えなかったのかもしれませんが。
ナビは別アプリ問題ある特定のポートに行きたいので、そこのポートからGoogleMapなどでナビゲーションしてくれるような動線はありますが、Googleマップを見ていると、ポートの空き状況をメルチャリアプリに切り替えて見ないといけないので、メルチャリアプリ内で、ナビも見れるし空き状況もみれるようになると最高です!
ポートがガラス張りの入口前問題ちょっと気持ち的な問題ですが、自転車を停める場所が、レンタカーの店舗のガラス張りの入口のすぐ前(ガラス張りの壁に向かって停めるイメージ)で、中から店員さんに見られる状態の中、停めたんですが、「ほんとにここ停めていいとかいな?」(博多弁)とちょっと不安になりました。という話だけです。
スペースがなかったんかもしれませんが、安心できるような何か工夫があると、よかったかなと思いました。
カゴの網目が大きすぎ問題カゴが付いているのは超便利だったのですが、自分のカバンがちょっと大きく、斜めにしないと入らなくて、走ってる途中の段差で、中のものが一部地面に落ちてしまいました。
僕のカバンの入れ方が悪かったってのもあるのですが、ものが落ちるような網のカゴは落下物の危険があるかなぁと思いました。いまの網のカゴはかわいいし、おしゃれなのですが。。。
番外編上記のような問題を対応中に不審者と間違われそう問題上で書いたのですが、鍵が開いた音はしたが、実際には鍵が開いてなく、すぐライド終了して、再度開けようとした、につながるのですが、このようなことをおそらく5分ぐらい、暗くて人通りのないポートでガチャガチャやってたら、不審者に間違われそうかなと一瞬思いました(笑)
蚊に噛まれた問題上記のようなことを同じ場所でやっていたら蚊に噛まれました(笑)
現地の人はメルチャリを知らなかった問題福岡の友達にメルチャリのこと聞いたら、知らなかったというだけです。 とくにその人は自転車通勤なので、使うことはないかもと言っていました。
現地の人にどのように周知するかが課題かも?時間の問題かもですが。
※ホテルやレンタカーにポートが設置されている印象だったので、もしかしたら現地の人はターゲットではないのかもしれません。
最後にとても良い体験ができました。久しぶりに実家に帰って、歩くにはちょっとしんどいけど、公共交通機関にのるほどでもないとか、公共交通期間ではちょっとだけ不便な場所に行きたい場合に利用できました。
地域によって課題は違ってくるかもしれませんが、一ユーザーとしての参考にしていただけたら幸いです。
あと、大阪や京都も比較的坂道少ないと思いますので、ぜひ大阪・京都にも作ってください!</description></item><item><title>Navigation Architecture Component</title><link>https://kwmt27.net/2018/06/02/android-jetpack-navigation/</link><pubDate>Sat, 02 Jun 2018 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/06/02/android-jetpack-navigation/</guid><description>はじめにこれは、Navigation Codelabをやりながら、Implement navigation with the Navigation Architecture Componentも読みつつ、わからないことだったり、気づいたことをメモしていってる内容です。
Navigationとは?Navigation Architecture Component はアプリのナビゲーションの実装をシンプルにします。 行き先はアプリ内の特定の画面です。デフォルトでは、Navigation Architecture Componentは遷移先としてSupport FragmentとActivityを含みますが、
setup// Navigation implementation &#39;android.arch.navigation:navigation-fragment:&#39; + rootProject.navigationVersion implementation &#39;android.arch.navigation:navigation-ui:&#39; + rootProject.navigationVersion DestinationsDestinationは、ユーザーが遷移可能な場所です。 プログラム的に、そして、オススメの方法に従えば、Destinationは通常はfragmentです。Activityもdestinationにできます。Navigationはfragmentとactivityの両方をサポートしていますが、必要ならカスタムdestination typeを作ることもできます。
Navigation graphNavigation Graphは、Destinationから別のDestinationに遷移するのを視覚的に表現するものです。 Navigation graphは新しいリソースの種類で、ユーザーが取りうる全てのパスを定義します。 Android StudioはNavigation Editorを使ってビジュアル的に表示してくれます。
Navigation Editorを使うには、resディレクトリにnavigationディレクトリを作成し、その中に、適当なファイル名で、リソースタイプをNavigationにしたリソースファイルを作成します。
上図のようにDesignタブがあるので、Designタブに切り替えるとNavigation Editorが使えます。
ちなみに、GradleのSyncに失敗すると、表示されませんので、ご注意ください。
Navigation Editorを詳しく見てみるNavigation Codelabのコードだと、下図のようになっています。
Destinationをクリックすると、そのプロパティを確認することができます。
action(矢印部分)をクリックすると、actionのプロパティを確認することができます。
NavigationのXMLを詳しく見てみるNavigation Editorで行った全ての変更は、もとになるXMLを変更します。 それは、レイアウトエディタを使ってレイアウトXMLを変更するのと同じです。
ちなみに、Destinationを移動すると、`.idea/navEditor.xmlが変更されます。
iff --git a/.idea/navEditor.xml b/.idea/navEditor.xml index a96811f..e2dfca8 100644 --- a/.idea/navEditor.xml +++ b/.idea/navEditor.xml @@ -46,8 +46,8 @@ &lt;LayoutPositions&gt; &lt;option name=&#34;myPosition&#34;&gt; &lt;Point&gt; - &lt;option name=&#34;x&#34; value=&#34;610&#34; /&gt; - &lt;option name=&#34;y&#34; value=&#34;-47&#34; /&gt; + &lt;option name=&#34;x&#34; value=&#34;640&#34; /&gt; + &lt;option name=&#34;y&#34; value=&#34;-55&#34; /&gt; &lt;/Point&gt; &lt;/option&gt; &lt;option name=&#34;myPositions&#34;&gt; Navigation GraphのXMLは次のようになっています。</description></item><item><title>Google I/O 2018 に初めて行ってきた。(2018/05/04pst日本からSan Franciscoへ)</title><link>https://kwmt27.net/2018/05/27/googleio-trip-1-20180504/</link><pubDate>Sun, 27 May 2018 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/05/27/googleio-trip-1-20180504/</guid><description>はじめにGoogle I/O 2018に参加するため、ちょっと早めにSanFransicoに行きました。 この記事は、2018/05/04行きの記録です。
飛行機情報格安航空券予約サイトスカイチケットという旅行会社で、SanFransico往復のチケットを購入しました。値段は全部で、92,820円。航空会社は中国東方航空という航空会社でした。一旦上海でトランジットがある便になります。
フライトスケジュール※時間はすべて現地時間となります。
【行程 1】 中国東方航空 MU730便 Bクラス 2018-05-04 0930 [大阪]関西国際空港発 2018-05-04 1045 [上海]上海浦東国際空港着 中国東方航空 MU589便 Sクラス 2018-05-04 1300 [上海]上海浦東国際空港発 2018-05-04 0930 [サンフランシスコ]サンフランシスコ国際空港着 【行程 2】 中国東方航空 MU590便 Vクラス 2018-05-12 1200 [サンフランシスコ]サンフランシスコ国際空港発 2018-05-13 1630 [上海]上海浦東国際空港着 中国東方航空 MU729便 Bクラス 2018-05-13 1815 [上海]上海浦東国際空港発 2018-05-13 2130 [大阪]関西国際空港着 旅行記チェックインまでチェックイン時間がスカイチケットのメールには書いてなかったので、調べたところ、「国際線では予定出発時刻の2時間前から45分前まで」とあるので、今回の場合だと、8時15分までにチェックインできればよかったです。
http://ck.ceair.com/muovc/main/ja_JP/Static_pages/TripPreparation.html
なんばOCATから7時20分発のバスに乗って、8時過ぎに空港ついて、チェックイン。DeployGate USオフィスにお邪魔するため、大阪っぽいお土産を買ったあと、荷物を預ける。結構ギリギリだった。
関空から上海へ関空から上海10:30ぐらいに関空から上海の機内食でした。普通に焼きそばの味でおいしかったです。あんまり唐揚げが乗ることはないと思うけど(笑)
機内で日本語を話すことが出来るのはCAさんは、2名とのこと。ちょっと安心。
機内食が配られた時は、英語で飲み物はどれがいいか聞かれて、 機内食は1種類だけだったので、とくにどっちがいいかみたいなことはきかれなかった。
2時間15分のフライトのあと、現地時間10:50ぐらいに上海に到着。
上海からSanFransicoへ上海で乗り換えです。 中国人に間違えられることが多かったですねw欧米の人には英語で、いってらっしゃいみたいなこと言ってるが、自分が降りるとき、中国語で言われました。
Transferの向きに従って行きます。
ここで、ちょっと写真がぶれてますが、右側が自分でトランジット手続きをする場所、左側が人が手続きをしてくれる場所になり、僕は右側の自動のレーンに案内されましたが、いざ自動をやってみると、エラーになり、左側の人が手続きする方に並び直されました。やることはパスポートスキャンして、チケットスキャンして、顔写真とるぐらいだったのですが。
そのあと、セキュリティゲートで荷物検査です。 ベルトもはずせと言われました。 ペットボトルがあったら、ゲート前に捨てる必要がありそうでした。
ゲート通過したら、搭乗口を確認して時間まで待ちます。
そろそろ時間かなと思ったころに、列が二列になっていて、なんの列か聞いたらSFO行きの列だったので慌てて並びましたが、無事乗ることができました。
上海からSFOへ3,4,3列の大きな飛行機で、僕は4列の左通路側でした。
USBの接続口がありました。携帯の充電ができました。
モニタ周り全体はこんな感じ。
さて、寝る準備です。完全に不審者ですねw
食事は3食出ました。時間はたぶん4時間後ずつぐらいだと思いますが、はっきりと分かりません。
飛行機の中のwifiについてですが、中国東方航空はフリーwifiはあるにはありました。 座席番号と、パスポートの下4桁(ID と書かれていて、一瞬なんの番号かわからなかった。)を入力すれば、ネットに繋がるのは繋がりますが、めちゃくちゃ遅いし、それに中国なのでグレートファイアウォールの影響で、google やLINEが使えなかった。。ので、ネットは期待しない方がいい。</description></item><item><title>Principles of Navigationの翻訳</title><link>https://kwmt27.net/2018/05/23/android-principles-of-navigation/</link><pubDate>Wed, 23 May 2018 10:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/05/23/android-principles-of-navigation/</guid><description>はじめにPrinciples of Navigation(Navigationの原則)を一度読んでみたほうが良さそうと思って読んでみた時のメモというか翻訳です。
Principles of Navigation(Navigationの原則)アプリ内ナビゲーションの目標は、ユーザーに一貫した予測可能なエクスペリエンスを提供することです。この目標を達成するために、ナビゲーションアーキテクチャコンポーネントは、以下の各ナビゲーション原則に準拠したアプリを構築するのに役立ちます。
アプリは決まった最初の遷移先があるアプリにはユーザーがランチャーからアプリを起動したときに見る決まった遷移先の画面があります。この遷移先は、戻るボタンを押した後、ランチャーに戻るときの最後に表示される画面になるはずです。
注意: アプリに1回限りの設定や一連のログイン画面がある可能性があります。これらの条件付き画面は、アプリの最初の遷移先とみなすべきではありません。
スタックは、アプリの「ナビゲーション状態」を表すために使用アプリのナビゲーション状態は、LIFO(後入れ先出し構造)で表される必要があります。 この「ナビゲーションスタック」は、スタックの一番下にアプリの最初の遷移先があり、スタックの一番上に現在の遷移先があるはずです。
ナビゲーションスタックを変更する操作は、新しい遷移先をスタックの先頭に「プッシュ」するか、最上部の遷移先をスタックから「ポップ」することによって、常にナビゲーションスタックの一番上で操作する必要があります。
Upボタンはアプリを終了させないユーザーが最初の遷移先にいる場合は、Upボタンを表示すべきではありません。他のアプリのタスク上でディープリンクを使用してアプリを起動すると、Upボタンは階層的に親の遷移先に戻り、他のアプリに戻るべきではありません。
UpボタンとBackボタンはアプリのタスク内で同等自分のアプリのタスク上にいて最初の遷移先にいないときのような、システムのバックボタンがアプリを終了しない場合、Upボタンはシステムのバックボタンと同等に機能すべきです。
ディープリンクで遷移する場合や通所の遷移で同じ同じ遷移先への遷移する場合、同じスタック状態となるべきユーザーは最初の遷移先でアプリに入って、別の遷移先に遷移します。また同じ遷移先に遷移するために、可能ならディープリンクも使います。 両方のケースで、ナビゲーションスタックは遷移先が同じスタック状態になるべきです。 特に、ユーザーは、どのように遷移先に到達したかにかかわらず、バックボタンやUpボタンを使って、最初の遷移先まで戻れるべきです。 既存のナビゲーションスタックは削除され、ディープリンクのナビゲーションスタックに置き換えられます。
翻訳について Destination 遷移先 ※DestinationはNavigationにおいて、画面の意味があるので、遷移先の画面としてしまおうかと思ったり、Destinationのままにしようかと悩みましたが、遷移先に統一しました。 start destination 最初の遷移先 ※Navigationにおいて、アプリ起動時の画面を意味しています。また開始先のような訳も考えましたが、上記Destinationを遷移先としたので、最初の遷移先としました。 navigation stack ナビゲーションスタック</description></item><item><title>GitHub PagesのカスタムドメインがHTTPSをサポートしたのでメモ</title><link>https://kwmt27.net/2018/05/20/github-pages-custome-domain-https/</link><pubDate>Sun, 20 May 2018 10:45:00 +0900</pubDate><guid>https://kwmt27.net/2018/05/20/github-pages-custome-domain-https/</guid><description>GitHub PagesのカスタムドメインがHTTPSをサポートしたので、その設定の忘却録です
GitHub Pagesのレポジトリの設定をみると、
Unavailable for your site because your domain is not properly configured to support HTTPS
といわれて、Enforce HTTPSにチェックできなかった。 それを対策するには、下記のHELPページに書かれているが、メモしておく。
https://help.github.com/articles/setting-up-an-apex-domain/
1.お名前.comのDNS設定に行き、AレコードのIPアドレスを追加または変更する。
185.199.108.153 185.199.109.153 185.199.110.153 185.199.111.153 2.反映確認
% dig +noall +answer kwmt27.net kwmt27.net. 300 IN A 185.199.108.153 kwmt27.net. 300 IN A 185.199.109.153 kwmt27.net. 300 IN A 185.199.110.153 kwmt27.net. 300 IN A 185.199.111.153 3.Custom domainを一旦削除して再度登録しなおす。
Add your custom domain to your GitHub Pages site. If you&rsquo;re updating the IP address of an existing A record, first remove and then re-add your custom domain to the repository you’re using to publish your Pages site to trigger the process of enabling HTTPS.</description></item><item><title>Google I/O 2018 報告会 関西 in 京都で発表した</title><link>https://kwmt27.net/2018/05/19/google_io_2018_report/</link><pubDate>Sat, 19 May 2018 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/05/19/google_io_2018_report/</guid><description>Google I/O 2018 報告会 関西 in 京都で発表しました。
スライドはこちら https://www.slideshare.net/yasi_life/2018-0519-googleio2018report-97614348
原稿こんにちは!
いままでのセッションとはだいぶ趣きが違う感じするとおもいますが、このタイトルで始めさせて頂きます。10分間よろしくお願いします。
簡単に自己紹介させてください。 名前は河本といいます。 Githubやtwitterはkwmtとかでやっています。 所属は、大阪の中央区本町にありますtechveinという5名の会社で僕はAndroid・iOSアプリを開発しています GoogleIOは初で、アメリカ自体も初という人です。
なぜGooglerでもGDEでもGDGスタッフでもない僕がここにいるかですが、Google+のIOコミュニティでGDG京都オーガナイザーの藏野さんが、関西でIOに参加する方はいらっしゃいますか?と発信していて、それに行きますと回答したら、この場で発表することになりました。(笑)
セッションはあとから見れるので、現地でしか経験できないことを重視したので、セッションに関してはそれほど話せることがないのですが、ぼくが気になったセッションを1つだけご紹介したあと、セッション以外のIO会場の展示の様子などを写真や動画でご紹介したいと思っています。
ご紹介するセッションは、AndroidでいうとJetpackやAppBundleなどに比べると地味かもしれませんが、What’s new Android Accessibilityというセッションをご紹介したいと思います。
今回のIOではaccessibilityにも力を入れてるのかなぁと個人的に感じました。 たとえば、この画像はGoogleさんのTwitterの動画からお借りしたものですが、この車椅子のマークやアクセシビリティと書かれたシールが至るところに貼られていたり、発表者の話した言葉がリアルタイムに文字起こしされてたりしたためです。ちなみに、この車椅子のマークの正式名称は、「障がい者のための国際シンボルマーク」というそうです。
これはWhat’s new Android Accessibilityの会場風景ですが、日本ではアクセシビリティの対応はそれほど重要視されてないような気がしていたのですが、聞きに来ている人は少なかったので、もしかしたら世界的に見てもあまり重要視されてないかもしれません(笑)まぁこのセッションと同じ時間帯にWhat’s new Androidのセッションがあったのでそちらに行ってる人が多かっただけだとは思いますが。
セッション全体としては、大きく4つありました。 まず、アクセシビリティの全体的な話しで、世界中に10億人以上の障害者がいて、それらの1億5千万人は、コップに入った水を持つことや、薄暗い光の中でなにかを探したりする基本的なタスクを行うことが難しく、技術はそういう障害をもつ人々に力を与えてくれるという話しがありました。 次に、Android Pの新機能の話しがあり、その後、視覚障害のあるユーザーに、周囲の関連する視覚情報を教えてくれるLookoutというアプリを開発しているという話し、最後に、UX調査に関する話がありました。 今回はAndroid Pの新機能だけを見ていきたいと思います。
新機能については大きく5つありました。 それぞれ簡単に見ていきましょう。
Sound Amplifierは、たとえば、環境音がうるさく聞くことが困難な場合、環境音を下げることが出来る機能です。セッションの中では、どのような仕組みで環境音を下げるかも簡単に説明がありました。
2つ目は、Accessibility Menuです。電源オフ、ロック画面、スクリーンショット、音量調整などのハードウェアショートカットの機能を片手で簡単に呼び出すことができる機能です。 わかりにくいですが、端末右下に人のアイコンがあって、それを押すと表示されるようです。
どこかでみたことあります。
3つ目は、Select to Speak with OCRです。 一年前にSelect to Speakという、選択したテキストを読み上げるサービスを出していましたが、今回はOCR機能を追加して、カメラを向けて、テキストを選択するとそのテキスト読みあげる機能です。実際にデモがありました。 Real time resultを使ってるのかな?
4つ目は、よりaccessibleにするためのAPIとして、Viewに3つ新しいAPIが追加されました。ここは試せていませんので、説明を省略させてください。
最後は、設定画面のアクセシビリティの項目に、バイブレーションの調整が出来る機能とアニメーションが削除できる機能が追加され、Volume KeyでAccesibility へのショートカットができる機能に追加と変更がありました。色補正と色反転をON/OFFできる新しい設定が追加され、Volume Keyを3秒押す必要があったのが、1秒に短縮されました。
参考にしたリンクを貼って、以上簡単ですが、What’s new Android Accessibilityの紹介を終わります。
次にIO会場の様子を、一部ご紹介したいと思います。
こちらは、オフィスアワーの写真です。 山口さんの発表でもありましが、左がオフィスアワー会場の建物になっていて、右側はその中の様子です。 オフィスアワーは、Googlerになんでも質問できる夢のような場所でした。
僕は2つほどしか質問できなかったのですが、その質問を紹介すると、
GCMが2019年4月に廃止になりますが、延長することはありませんか?という質問したところ、Neverと言われました。なぜなら、FCMへの移行にかかる時間は1日だからとのことでした。。 もう一つは、camraviewというカメラのライブラリがあって、更新が1年前で止まっていいますが、メンテナンス予定はありますか?と聞いたところ、 このcameraviewはside projectだから更新されないかもとのことだったので、 他に使いやすいライブラリを知っていますか?と聞いたところ、Android フレームワークのソースを紹介頂きました。</description></item><item><title>Android Oreoのプッシュ通知対応でハマった3つのこと</title><link>https://kwmt27.net/2018/04/21/push-notification-for-android-oreo/</link><pubDate>Sat, 21 Apr 2018 14:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/04/21/push-notification-for-android-oreo/</guid><description>はじめに In the second half of 2018, Play will require that new apps and app updates target a recent Android API level.
引用元: https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html
日本語訳: https://developers-jp.googleblog.com/2017/12/improving-app-security-and-performance.html
突然ですが、PlayStoreでアプリを公開するにあたり、ターゲットSDKバージョンを最新に指定することが義務化されることはご存知でしょうか。 新規アプリの公開で、2018年8月から、既存アプリのアップデートで2018年11月からAPIレベル26以降つまりAndroid 8.0オレオ以降の対応が必須になります。
今年の11月というと半年後ぐらいですので、オレオ対応はそろそろ開始し始めないと遅いかもしれません。
ということでオレオ対応をしていたのですが、そのときに僕がハマったことを3つのこと共有させていただきたいと思います。
話さないこととしては、
プッシュ通知の仕組みや実装の仕方 プッシュ通知の大切さ これらについては話しません。 プッシュ通知の大切さにつきましては、 去年9月のiOSDCで、「頼むからプッシュ通知の使い方をおろそかにしないでくれ!」(YouTube, スライド )というタイトルで発表されていて、とてもよい発表でしたのでぜひそちらを見て頂きたいです。
ハマった3つのことハマったこととは次の3つになります。
通知が来ない! 通知アイコンが真っ白になった! 通知をオフにしても通知が来る! ひとつひとつ詳しく見ていきましょう。
そもそも通知が来ない!MarshmallowやNougatでは通知が来ていたのですが、targetSdkVersionをたとえば26にすると通知が来なくなりました。
どういうことかと言いますと、targetSdkVersionを26に設定すると、そのアプリはちゃんとOreo対応していますよ、と宣言したことになります。 通知をOreo対応するために必ず必要なことがあります。それは
all notifications must be assigned to a channel.
引用元: https://developer.android.com/training/notify-user/channels.html
すべての通知はチャンネルに割り当てなければなりません。
チャンネルというのは、例えばGoogle Play Musicアプリを参考しますと、下図の赤枠で囲んだ部分になります。
チャンネルごとに通知をON/OFFすることができたり、カラーやサウンドもチャンネルごとに設定できます。 同じアプリ内で、通知が来て欲しいチャンネルは通知をONにし、通知が不快だなと思うチャンネルだけを通知が来ないようにOFFできるという機能です。
これらのチャンネルは、targetSdkVersionを上げただけでは作成されません。 つまり、通知が来ない原因は、開発者がチャンネルを明示的に作成する必要があったのですが、ただバージョンを上げただけなので、チャンネルは作成されず通知が来なかったというわけです。
通知アイコンが真っ白になった!次にAndroid Oreoで通知アイコンが真っ白になるという現象に遭遇しました。下図の矢印のところです。
これをみたとき最初は、Lolipopから、アイコン画像の透過でない部分は白くレンダリングされるため、アイコン画像自体が対応していないのなかな?と思ったんですが、手元にあったMarshmallow端末で確認した所、ちゃんと表示されていたので、それは違いました。
いろいろ調べた所、Firebase SDK version11.</description></item><item><title>Kotlin List</title><link>https://kwmt27.net/2018/04/12/kotlin-list/</link><pubDate>Thu, 12 Apr 2018 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/04/12/kotlin-list/</guid><description>2つのリストの要素を比較し、Mapのkeyをその要素にし、valueを一致していたらtrue,不一致ならfalseとするMapを作るには?/** * 2つのリストA,Bがあって、BはAの一部のリストとする。 * Aの要素とBの要素が一致する場合(今回の場合、idが一致)、 * その要素をKeyとしてValueをtrueとするMapを作りたい。(今回の場合は、Map&lt;Element, Boolean&gt;) */ fun main(args: Array&lt;String&gt;) { // データ val listA = arrayListOf(Element(1, &#34;a&#34;), Element(2, &#34;b&#34;) , Element(3, &#34;c&#34;), Element(4, &#34;d&#34;)) // マスタデータ val listB = arrayListOf(Element(2, &#34;a&#34;), Element(4, &#34;d&#34;)) // ユーザーがマスタデータのどれかを選択したというイメージ // Bのidのみのリスト(List&lt;Int&gt;) val ids = listB.map { it.id } println(ids) // [2, 4] // Aを変換(map)します。このときAのidがBのidに含まれていたら、true 、含まれていなければfalseとするMapに変換します。 val result = listA.map { it to ids.contains(it.id) }.toMap() println(result) // output // {Element(id=1, name=a)=false, Element(id=2, name=b)=true, Element(id=3, name=c)=false, Element(id=4, name=d)=true} } data class Element( val id: Int, val name : String ) リストが別のリストに含まれているか調べるには?fun main(args: Array&lt;String&gt;) { val caches = arrayListOf(16, 8) val target = arrayListOf(16, 3) val result = target.</description></item><item><title>Kotlin When</title><link>https://kwmt27.net/2018/04/07/kotlin-when/</link><pubDate>Sat, 07 Apr 2018 11:00:00 +0900</pubDate><guid>https://kwmt27.net/2018/04/07/kotlin-when/</guid><description>kotlin whenfun main(args: Array&lt;String&gt;) { val x = 11 when (x) { in 1..10 -&gt; print(&#34;x is in the range&#34;) !in 10..20 -&gt; print(&#34;x is outside the range&#34;) else -&gt; print(&#34;none of the above&#34;) } } // output // x=1の時`x is in the range` // x=11の時 `none of the above` // x=21の時 `x is outside the range`</description></item><item><title>コマンドからエミュレータ閉じるには?</title><link>https://kwmt27.net/2018/03/29/kill-emulator-on-temrminal/</link><pubDate>Thu, 29 Mar 2018 16:20:00 +0900</pubDate><guid>https://kwmt27.net/2018/03/29/kill-emulator-on-temrminal/</guid><description>問題エミュレータを複数起動している途中でMacが落ちて再起動してしまった。 再起動後いろいろソフトが立上がるが、エミュレータは立ち上がらない(少なくとも見えない)現象になってしまった。
% adb devices List of devices attached emulator-5558 device emulator-5556 device emulator-5554 device adb devicesとするとこのように見えるのだが、実際はエミュレータは見えない。
対策コマンドからエミュレータを閉じるにはどうしたらいいか調べたところ、
adb -s emulator-5554 emu kill とすると
% adb devices List of devices attached と閉じてくれた。
以上。
参考 https://stackoverflow.com/a/20155436</description></item><item><title>Kotlin Enum</title><link>https://kwmt27.net/2018/03/08/kotlin-enum/</link><pubDate>Thu, 08 Mar 2018 22:56:51 +0900</pubDate><guid>https://kwmt27.net/2018/03/08/kotlin-enum/</guid><description>定義されたEnum名そのままの文字列がほしいenum class Type { Hoge, fugA } このようなEnumがあったとして、HogeならHoge、fugAならfugAというそのままの文字列がほしいとき、nameを使います。
println(Type.Hoge.name) println(Type.fugA.name) // output: // Hoge // fugA StringからEnumにしたいenum class Type { Hoge } このようなEnumがあったとして、String &quot;Hoge&quot;から、Enum(Type)型の Hoge にしたい。
val type = Type.valueOf(&#34;Hoge&#34;) println(type is Type.Hoge) // output: // true ちなみに、下記のように、&quot;hoge&quot;などとType.Hogeとは違う文字列でvalueOfをしようとすると、
val type = Type.valueOf(&#34;hoge&#34;) IllegalArgumentExceptionがスローされます。
Exception in thread &#34;main&#34; java.lang.IllegalArgumentException: No enum constant Type.hoge at java.lang.Enum.valueOf(Enum.java:238) 小文字からEnum型にしたいenum class Type { Hoge } このようなEnumがあるとき、小文字の&quot;hoge&quot;からEnumに変換したいときがあります。 たとえば、スキームなどをEnumで定義するも、Enumは大文字始まりで定義すべきと警告がでるので、大文字で定義しますが、スキーマが小文字始まりだった場合などです。
この場合、次のようにtypeOfメソッドを用意すると良さそうです。
enum class Type() { Hoge; companion object { fun typeOf(lowerString: String): Type { return values().</description></item><item><title>2017振り返り</title><link>https://kwmt27.net/2017/12/31/looking-back-2017/</link><pubDate>Sun, 31 Dec 2017 18:30:00 +0900</pubDate><guid>https://kwmt27.net/2017/12/31/looking-back-2017/</guid><description>昨年に引き続き、今年で5回目の振り返りを書いておこう。
仕事関連1月の始めの方は、AndroidのGoogleMapの不具合に悩まされました。Mapをグリグリ動かすと、アプリが落ちるのです。。 issue に挙がっていたので、ライブラリの不具合だろうと思われます。まだ解決していないのは気になりますね。これの詳細は、Githubに書いてます。
1月中旬ぐらいからMアプリの改修案件です。2016年に引き続きご依頼頂けるのはやはり嬉しいものです。 2月終わりぐらいまではMアプリをメインに、Aアプリ(A社)とAアプリ(I社)の改修案件が少しずつありました。
3月は、IoT案件でした。温度湿度をAndroid TV(Nexus Player)で表示するというシンプルな仕様でしたが、めちゃめちゃ楽しかったです。 電子パーツを買いに大阪日本橋に行きまくりました。DroidKaigiがあって東京に行ったのですが、そのときも秋葉原にパーツを求めに行きました。仕事とは関係ですが、秋葉原に行ったときにお昼を食べた丸五というとんかつやさんは美味しかったです。並びましたが。 IoT案件は4月中旬ぐらいまで続いたようです。
4月始めの頃よりMaBeeeアプリを担当させて頂きました。会社としてはAndroid,iOSを担当し、僕はAndroidを担当しました。 アプリはこちらです。 なかなかアプリっぽくないUIだったので、UI作成は苦労しましたね。。他にこのようなUIを開発している会社さんにノウハウ聞いてみたいです。 5月下旬までやってました。
5月中旬ぐらいから、Aアプリ(A社)のiOS開発を担当しました。3人で開発。その内2人が新規画面作成のUIのみ担当するという体制でした。iOSをUIのみ担当といってもUITableViewなんかはdelegateを実装しなくちゃならので、結局Storyboard+ViewControllerまで担当しました。 こちらは6月初旬まで。
6月中旬ぐらいからポケットアブストラクト というiOSアプリの新規開発を担当しました。こちらは1人で担当しました。 一からiOSを担当するのは初めてでしたが、MVVMのような設計にしたり、チャレンジさせてもらった案件でした。 待ちもあったりして8月ぐらいまで続きました。
6月ぐらいから社内でアプリを作ろうぜという話があって、アイデア出しからちょっとずつ動いていたのですが、7月8月はこのネイティブ側も触ってました。WebViewなのでそれほどやることは無いのですが、Androidのカメラまわりが大変でした。。
9月からはマイナンバーカードを使ったAndroidアプリの作成を担当しました。マイナンバーカードが必要なので、申し込んで半月ほどで届きました。だいたい9月一杯で終わりました。
10月はMアプリや社内アプリ、Kアプリ(R社)をやりました。Kアプリは既存の改修でしたね。 またMアプリの新規開発案件で、Clean Architectureを採用して設計することになり、Clean Architectureについていろいろ調べたりソース読んだりしました。AndroidはKotlinです。僕自身は初めてのKotlinでした。 基本的な設計は完了したのですが、第二弾として1月からがっつり担当することになる予定です。
11月と12月はMアプリとAアプリ(A社)でした。 Aアプリは2年前から担当させて頂いてるのですが、改修する度に思います。一から作りたい、と。
今年は、特に設計の年でしたね。 2月ごろからDroidKaigiの公式アプリにContributeしたりしていたら、MVVMに興味を持ち始め、今年担当したアプリはほとんどMVVMになってます。Clean Architecture(+MVVM)にもガッツリ触れたのでどこかでまとめたいですね。
勉強会 1月 オオサカンEXPO 展示しました。とくにIoTのやつは皆さんに興味を持って見ていただけていたと思います。 2月 [関ジャバ] フロントエンド初心者勉強会 in 大阪 少し趣味でWebアプリを作成していたので、気になって参加しました。この時作っていたものは中断しちゃいましたが、別のWebアプリケーションを作成中です。 3月 DroidKaigi 2017 2月ぐらいから公式アプリのContributeしてたから、この日だけじゃなくて、2月ぐらいから自分の中ではDroidKaigiに参加していた感じでした。今年は公式アプリの実装を参考にしまくりました。 4月 umeda.go Goほとんど使ってないので、近況を聞きに来た感じ クラスメソッドの開発を知る!全7回勉強会 〜第3回 Swiftのアツさを語る!〜 設計の話は面白かったですね。MVPでした。 そうだ Go、京都。 当日申し込んで当日LT資料作って、ひさびさLTしました。 5月 AndroidWear2.0 ハンズオン ハンズオンしたリポジトリ 6月 umeda.apk #3 - Report from Google I/O 2017 Google I/Oのことを聞きに。 7月 GDG神戸 VR Labs こちらは会場提供です。初めて会場提供しました。 モバもく会#1 僕主催のもくもく会です。 モバもく会#2 8月 モバもく会#3 【大阪開催】マテリアルデザインガイドライン輪読会 #4 9月 モバもく会#4 iODS 2017 朝までiOSDCのやつはしんどかったな。。。あれは行くのやめよう。 モバもく会#5 10月 【大阪開催】マテリアルデザインガイドライン輪読会 #4 モバもく会#6 関西Javaエンジニアの会(関ジャバ) &lsquo;17 10月度 DDDに関する勉強会でした。ScalaのEither型が参考になりました。 「正しいものを正しくつくる」とは何か(大阪開催) 11月 モバもく会#8 12月 モバもく会#9 Mobile Act OSAKA #2 香川から発表しに来られた方と話し込んでたら終電逃して、梅田から難波まで歩きました。。 モバもく会#10 モバもく会について1回だけ台風で中止しましたが、大体2,3週間間隔で10回続けることができたのはよかったかなぁと。 他の勉強会に行っても結構モバもく会知ってもらえてるようで、「知ってますよ」とか「行きたいんですけどねぇ」とか言われますw</description></item><item><title>Android Lint</title><link>https://kwmt27.net/2017/12/09/android-studio-lint-for-kotlin/</link><pubDate>Sat, 09 Dec 2017 16:25:00 +0900</pubDate><guid>https://kwmt27.net/2017/12/09/android-studio-lint-for-kotlin/</guid><description>コマンドラインからlintを実行するにはproject root で下記を実行します
./gradlew lint 特定のビルド バリアントに対してのみ lint タスクを実行するには
(例)
./gradlew lintDevelopDebug 設定IDリストを表示するには?% $ANDROID_HOME/tools/bin/lint --list Valid issue categories: Correctness Correctness:Messages Correctness:Chrome OS Security Performance Usability:Typography Usability:Icons Usability Accessibility Internationalization Internationalization:Bidirectional Text Valid issue id&#39;s: &#34;ContentDescription&#34;: Image without contentDescription &#34;AddJavascriptInterface&#34;: addJavascriptInterface Called &#34;ShortAlarm&#34;: Short or Frequent Alarm &#34;AllCaps&#34;: Combining textAllCaps and markup &#34;AllowAllHostnameVerifier&#34;: Insecure HostnameVerifier &#34;AlwaysShowAction&#34;: Usage of showAsAction=always &#34;InvalidUsesTagAttribute&#34;: Invalid name attribute for uses element. &#34;MissingIntentFilterForMediaSearch&#34;: Missing intent-filter with action android.</description></item><item><title>Kotlin Style Guideメモ</title><link>https://kwmt27.net/2017/12/02/kotlin-style-guide/</link><pubDate>Sat, 02 Dec 2017 22:17:00 +0900</pubDate><guid>https://kwmt27.net/2017/12/02/kotlin-style-guide/</guid><description>https://android.github.io/kotlin-guides/style.html</description></item><item><title>モバもく会#8 を開催</title><link>https://kwmt27.net/2017/12/01/mobile-mockmock-8/</link><pubDate>Fri, 01 Dec 2017 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/12/01/mobile-mockmock-8/</guid><description>2017/11/12(日)にモバもく会#8という、だいたい2,3週間に1回やっているモバイルに関連したもくもく会を開催しました。
今回は3人でした。毎回ありがとうございます!自分が毎回勉強させてもらっています(感謝)
今回みなさんがやったことは次のとおりです。
Devfestの参加レポートを書いた 参加レポートはこちらです Instant Appsについての調査 newyork times、crosswordがインスタントアップ対応しているとのこと 僕は、Kotlin ConfのソースのAndroidを読みました。 読んだ内容は、別記事にしました.
こちらはモバもく会のイメージです。GoogleHomeの素晴らしさについて語っています。</description></item><item><title>Kotlin Conf Android Codeを読んだときのメモ</title><link>https://kwmt27.net/2017/12/01/read-kotlin-conf-android-app/</link><pubDate>Fri, 01 Dec 2017 14:30:00 +0900</pubDate><guid>https://kwmt27.net/2017/12/01/read-kotlin-conf-android-app/</guid><description># はじめに
Kotlin ConfのソースのAndroidを読みました。4時間ぐらいで読めた所までですが。
コードをおいやすくするために、Android Studio 3.0でプロジェクトを開きます。
kotlinconf-app/android/build.gradleを見るmaven { url &#34;http://dl.bintray.com/kotlin/kotlin-eap-1.2&#34; } まず、これが気になり調べたところ、Kotlinのアーリーアクセスプログラムのmavenリポジトリのようです。
bintrayには、
Builds of Kotlin released under the Early Access Program
このように書いてありました。
kotlinconf-app/android/app/build.gradleを見るappモジュールのbuild.gradleのdependeciesを見ると、全体がだいたいどんな感じのアプリか分かるかもなので、みてみます。
dependencies { compile fileTree(dir: &#39;libs&#39;, include: [&#39;*.jar&#39;]) compile &#39;com.android.support:appcompat-v7:26.1.0&#39; compile &#39;com.android.support:recyclerview-v7:26.1.0&#39; compile &#39;com.android.support.constraint:constraint-layout:1.0.2&#39; testCompile &#39;junit:junit:4.12&#39; androidTestCompile(&#39;com.android.support.test.espresso:espresso-core:3.0.1&#39;, { exclude group: &#39;com.android.support&#39;, module: &#39;support-annotations&#39; }) compile &#39;com.android.support:design:26.1.0&#39; compile&#34;org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version&#34; compile &#34;android.arch.lifecycle:runtime:1.0.0&#34; compile &#34;android.arch.lifecycle:extensions:1.0.0-alpha9-1&#34; kapt &#34;android.arch.lifecycle:compiler:1.0.0-alpha9-1&#34; compile &#34;org.jetbrains.anko:anko-sdk25:$anko_version&#34; compile &#34;org.jetbrains.anko:anko-appcompat-v7:$anko_version&#34; compile &#34;org.jetbrains.anko:anko-recyclerview-v7:$anko_version&#34; compile &#34;org.jetbrains.anko:anko-commons:$anko_version&#34; compile &#34;org.jetbrains.anko:anko-design:$anko_version&#34; compile &#34;org.jetbrains.anko:anko-coroutines:$anko_version&#34; compile &#39;com.</description></item><item><title>Amazon S3でWebサイトホスティングのメモ</title><link>https://kwmt27.net/2017/11/26/s3-web-hosting/</link><pubDate>Sun, 26 Nov 2017 00:02:00 +0900</pubDate><guid>https://kwmt27.net/2017/11/26/s3-web-hosting/</guid><description>参考 Amazon S3による静的Webサイトホスティング 独自ドメインの設定が超絶参考になった。 ウェブサイトのホスティングの有効化 以下が必要なのに気づくのに時間かかってしまった。 バケット選択 プロパティ Static website hostingで有効化 SSL化https://qiita.com/jasbulilit/items/73d70a01a5d3b520450f</description></item><item><title>Android Studio 2.3.3 から3.0にしたときのメモ</title><link>https://kwmt27.net/2017/11/02/migrate-android-studio2.0-to-3.0/</link><pubDate>Thu, 02 Nov 2017 00:07:00 +0900</pubDate><guid>https://kwmt27.net/2017/11/02/migrate-android-studio2.0-to-3.0/</guid><description>はじめに dependencies { - classpath &#39;com.android.tools.build:gradle:2.3.3&#39; + classpath &#39;com.android.tools.build:gradle:3.0.0&#39; classpath &#34;org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version&#34; と3.0.0にverupしたさいにエラーが出たのでその原因と対策をメモ
All flavors must now belong to a named flavor dimension.エラー内容app/build.gradle Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
原因 The plugin now requires that all flavors belong to a named flavor dimension—even if you intend to use only a single dimension.
すべてのフレーバーに
対策 To resolve this error, you need to first declare one or more dimensions using the flavorDimensions property.</description></item><item><title>KotlinでMockito2を使ってfinal classをモック化するには</title><link>https://kwmt27.net/2017/10/30/mock-kotlin-class-with-mockito2/</link><pubDate>Mon, 30 Oct 2017 11:20:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/30/mock-kotlin-class-with-mockito2/</guid><description>環境Android Studio: 2.3.3 Kotlin: 1.1.51 Mokito: 2.11.0
build.gradleにはmockito-coreを指定
testCompile &#34;org.mockito:mockito-core:2.11.0&#34; 問題kotlinで普通にクラスを作成すると、final classです。
class EventsDataSourceManager @Inject constructor(private val eventsRemoteDataSource: EventsRemoteDataSource) { fun eventEntities(user:String, page:Int): Single&lt;List&lt;EventEntity&gt;&gt; { // リモートかキャッシュを使うかの判断をココでやるとよさそう return eventsRemoteDataSource.eventEntities(user, page) } } その状態でmockitoを使って、モック化しようとすると、「Mockitoはfinal classはモック化できない」とエラーにになります。
org.mockito.exceptions.base.MockitoException: Cannot mock/spy class net.kwmt27.codesearch.infrastructure.repository.datesource.EventsDataSourceManager Mockito cannot mock/spy because : - final class 対策これを可能にするには、
test/resources/mockito-extensions フォルダを作成し、mockito-extensionsフォルダに、org.mockito.plugins.MockMakerファイルを作成します。 org.mockito.plugins.MockMakerファイルには、下記のテキストを入力しておきます。
mock-maker-inline この状態でもう一度テストを実行します。 すると、テストが実行されます。
参考 How to mock final classes on Kotlin using Mockito 2 (KAD 23) Mock the unmockable: opt-in mocking of final classes/methods(公式wiki)</description></item><item><title>Kotlinプロジェクトで「Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon」というエラーが出たときの対処法</title><link>https://kwmt27.net/2017/10/24/webview-error-with-kotlin/</link><pubDate>Tue, 24 Oct 2017 23:20:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/24/webview-error-with-kotlin/</guid><description>現象Kotlin+DatabindingでViewModel側でwebview.loadURLをしてロードしようとしたら上記のエラーが出た。
E/AndroidRuntime: FATAL EXCEPTION: main Process: &lt;package&gt;, PID: 29932 java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon at &lt;package&gt;.HomeViewModel$setupWebView$webViewClient$1.onPageStarted(HomeViewModel.kt:0)at com.android.webview.chromium.WebViewContentsClientAdapter.onPageStarted(WebViewContentsClientAdapter.java:190) at org.chromium.android_webview.AwContentsClientCallbackHelper$MyHandler.handleMessage(AwContentsClientCallbackHelper.java:20) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 原因WebViewClientのonPageStartedメソッドの引数のBitmapのところが、favicon:Bitmap と、non-nullが指定されていたことだった。
対策override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { Bitmap?をnull許容にしてあげればいい。
最後にある別プロジェクトからjavaソースをコピペして、Android Studioの自動変換機能にまかせてたので、大丈夫だろうと思っていたことで、気づくのに時間をとってしまった。。 よくエラー内容を見るとparameter faviconと書いてはいるんだけど、コピペしているからフレームワークの内部のことかと思ってしまって見過ごしていた。
Android Studioのkotlinへの自動変換を信じすぎないようにしよう。</description></item><item><title>Dagger2でProvidesアノテーションつけてないのに、なぜフィールド注入されるのか</title><link>https://kwmt27.net/2017/10/21/dagger2-subcomponent/</link><pubDate>Sat, 21 Oct 2017 21:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/21/dagger2-subcomponent/</guid><description>Dagger2について分かってなかったことclass MainActivity : DaggerAppCompatActivity() { @Inject lateinit var viewModel: MainViewModel } MainActivityにviewModelを保持させてくて、@Injectアノテーションを付けてあげれば、インスタンスを注入してくれてる。
インスタンス注入するには、以下のような準備は必要です。
下記のようにActivityModuleとAppComonentを定義し、ActivityModuleをAppComponentの@Component(modules=ActivityModule::class)に指定します。
@Singleton @Component(modules = arrayOf( AndroidSupportInjectionModule::class, AppModule::class, ActivityModule::class ) ) interface AppComponent : AndroidInjector&lt;App&gt; { @Component.Builder interface Builder { @BindsInstance fun application(application: App): Builder fun build():AppComponent } } @Module abstract class ActivityModule { @ActivityScope @ContributesAndroidInjector internal abstract fun contributeMainActivity(): MainActivity } ActivityScopeも定義が必要だし、
@Scope @Retention(AnnotationRetention.RUNTIME) @MustBeDocumented annotation class ActivityScope AndroidManifest.xmlにAppを指定する必要がありますし、
&lt;application android:name=&#34;.App&#34; そもそもAppは、Applicationを継承したクラスで、
open class App : DaggerApplication() { override fun applicationInjector(): AndroidInjector&lt;out DaggerApplication&gt; { return DaggerAppComponent.</description></item><item><title>Kotlin Enum</title><link>https://kwmt27.net/2017/10/19/kotlin-enum/</link><pubDate>Thu, 19 Oct 2017 22:36:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/19/kotlin-enum/</guid><description>はじめにKotlinでEnumを定義して、IntからEnumに変換したいときどうしたらいいのかをメモ。
Javaの場合ItemTypeというのをこんな感じで定義して、staticなvalueOfメソッドで、ItemTypeのintが見つかればItemTypeを返していた。
public enum ItemType { Normal(0), Progress(1), Ad(2); private int typeId; ItemType(int typeId) { this.typeId = typeId; } public int getTypeId() { return typeId; } public static ItemType valueOf(int id) { for (ItemType itemType : values()) { if (itemType.getTypeId() == id) { return itemType; } } throw new IllegalArgumentException(&#34;no such enum object for the id: &#34; + id); } } KotlinKotlinでも同様にしてやればよい。
enum class ItemType(val typeId:Int) { Normal(0), Progress(1), Ad(2); companion object { fun valueOf(typeId:Int) :ItemType { val filtered = ItemType.</description></item><item><title>Dagger2 + Android + ViewModel(with databinding)</title><link>https://kwmt27.net/2017/10/17/dagger2-android-viewmodel/</link><pubDate>Tue, 17 Oct 2017 10:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/17/dagger2-android-viewmodel/</guid><description>はじめにdaggerバージョンが2.10になったときに、dagger.androidがリリースされたようで、いままでと少し書き方が変わっていたので、メモを書きました。
基本的に下記ページを参考にしています。
https://google.github.io/dagger/android.html
またサンプルコードは、Dagger 2.12 時点によるものです。
dagger.androidMainActivityが依存しているインスタンスを注入できるようにしてみます。
AndroidInjectionModule(あるいは、Support componentを使う場合は AndroidSupportInjectionModule)をアプリケーションコンポーネントに指定してください。
@Singleton @Component(modules = arrayOf( AndroidSupportInjectionModule::class ) ) interface AppComponent : AndroidInjector&lt;App&gt; { @Component.Builder interface Builder { @BindsInstance fun application(application: App): Builder fun build():AppComponent } } AndroidInjector.Builder&lt;YourActivity&gt;を継承している@Subcomponent.Builderを持つ AndroidInjector&lt;YourActivity&gt; を実装する@Subcomponent を作成します。
@Subcomponent interface MainActivitySubComponent:AndroidInjector&lt;MainActivity&gt; { @Subcomponent.Builder abstract class Builder : AndroidInjector.Builder&lt;MainActivity&gt;() } subcomponentを定義したら、Subcomponent.Builderをバインドするモジュールを定義(ここではMainActivityModule)し、
@Module(subcomponents = arrayOf(MainActivityModule.MainActivitySubComponent::class)) abstract class MainActivityModule { @Binds @IntoMap @ActivityKey(MainActivity::class) internal abstract fun bindAndroidInjectorFactory( builder: MainActivityModule.MainActivitySubComponent.Builder): AndroidInjector.Factory&lt;out Activity&gt; } そのモジュール(MainActivityModule)をアプリケーションコンポーネント(ここではAppComponent)に追加します。</description></item><item><title>モバもく会#6 を開催</title><link>https://kwmt27.net/2017/10/16/mobile-mockmock-6/</link><pubDate>Mon, 16 Oct 2017 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/16/mobile-mockmock-6/</guid><description>2017/10/15(日)にモバもく会#6という、だいたい2,3週間に1回やっているモバイルに関連したもくもく会を開催しました。
今回は3人でした。毎回ありがとうございます!自分が毎回勉強させてもらっています(感謝)
今回みなさんがやったことは次のとおりです。
CircleCI2.0についての調査 COSMOのAndroid SDKを使ってみる 聞いた話ですが、FIDOというものがあるらしいですね。
僕はクリーンアーキテクチャのサンプル を参考に自分なりに実装しようとしました。
参考:Architecting Android&hellip;The clean way? しようと思ったのですが、DIを実現するためにdaggerを使っているといろいろハマってしまって、それに時間取られてしまいました。。。
結論:公式ドキュメントをちゃんと読め!ということでした。
Daggerについては、別記事に書きました。
以上です。</description></item><item><title>Kotlin kapt error</title><link>https://kwmt27.net/2017/10/15/kotlin-error/</link><pubDate>Sun, 15 Oct 2017 21:18:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/15/kotlin-error/</guid><description>困ったことKotlin + Dagger2を使って、下記のようなエラーが出た。
See log for more details
とあるけど、どこ見たらいいのでしょうか。。。
対策Android Studioからは見れないので、ターミナルでassembleDevelopDebugを実行してみましょう。
% ./gradlew assembleDevelopDebug すると下記のような感じで詳細なエラーログを見ることができます。
:app:kaptDevelopDebugKotlin e: app/build/tmp/kapt3/stubs/developDebug/net/kwmt27/codesearch/presentation/internal/di/components/AppComponent.java:6: エラー: [dagger.android.AndroidInjector.inject(T)] java.util.Map&lt;java.lang.Class&lt;? extends android.support.v4.app.Fragment&gt;,javax.inject.Provider&lt;dagger.android.AndroidInjector.Factory&lt;? extends android.support.v4.app.Fragment&gt;&gt;&gt; cannot be provided without an @Provides-annotated method. e: e: public abstract interface AppComponent extends dagger.android.AndroidInjector&lt;net.kwmt27.codesearch.presentation.App&gt; { e: ^ e: java.util.Map&lt;java.lang.Class&lt;? extends android.support.v4.app.Fragment&gt;,javax.inject.Provider&lt;dagger.android.AndroidInjector.Factory&lt;? extends android.support.v4.app.Fragment&gt;&gt;&gt; is injected at e: dagger.android.DispatchingAndroidInjector.&lt;init&gt;(injectorFactories) e: dagger.android.DispatchingAndroidInjector&lt;android.support.v4.app.Fragment&gt; is injected at e: dagger.android.support.DaggerAppCompatActivity.supportFragmentInjector e: net.kwmt27.codesearch.presentation.view.MainActivity is injected at e: dagger.android.AndroidInjector.inject(arg0) e: java.lang.IllegalStateException: failed to analyze: org.</description></item><item><title>モバもく会#5 を開催</title><link>https://kwmt27.net/2017/10/10/mobile-mockmock-5/</link><pubDate>Tue, 10 Oct 2017 21:10:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/10/mobile-mockmock-5/</guid><description>10月になってしまいましたが、2017/09/24(日)にモバもく会#5という、だいたい2,3週間に1回やっているモバイルに関連したもくもく会を開催しました。
今回は5人でした。毎回ありがとうございます!自分が毎回勉強させてもらっています(感謝)
今回みなさんがやったことは次のとおりです。
Enumのメモリ消費についての調査 Spark(分散処理)の事始め iOSのUITableViewのHeightが異なるときに対応方法についての調査&実装 以前に開催されたAndroid Thingsハッカソンの続き 僕は、support design libraryのBottomSheetのサンプル を読んで実際に試してみました。
実装コードまで読めてないのですが、軽くマテリアルデザインガイドラインを軽く呼んでみて、DeepLinkについて気になったので実装を試してみました。
主に参考にしたブログは、Bottom sheet everythingを参考にしました。
DeepLinkは、「こんな簡単な実装で、こんなことができるんですよ」といいたかったんですが、実際はバックの黒透明の背景(ダイアログの背景のみ)が出るだけで、内容がでるところまで出来ませんでした。。。(この日はちょっといろいろありまして。。。←言い訳^^;)</description></item><item><title>iPhone Xの操作方法</title><link>https://kwmt27.net/2017/10/05/iphone-x-operations/</link><pubDate>Thu, 05 Oct 2017 16:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/10/05/iphone-x-operations/</guid><description>アプリ起動中にホーム画面を表示するにはいままでホームボタンをタップ
iPhone X端末下部から上にスワイプ
コントロールセンターを表示するにはいままで端末下部から上にスワイプしていた
iPhone X右上のWifiとか充電マークがあるところから下にスワイプする
マルチタスク画面を表示するにはいままでホームボタンをダブルタップしていた。
iPhone X端末下部から軽く上にスワイプする
アプリを強制終了するには今までは、ホームボタンをダブルタップして、マルチタスク画面が表示されるので、強制終了したいアプリを上にスワイプして終了させていた。
iPhone X 端末下部から軽く上にスワイプしてマルチタスク画面を表示します. どれでもいいのでアプリを長押しすると、アプリの左上に削除アイコンが表示されるのでそのアイコンをタップするか、上にスワイプで削除できます。 片手で持ったとき、画面の上部を指が届く範囲に下げるにはいままでホームボタンをダブルタップ
iPhone X画面下部を下にスワイプ
ただし、設定で簡易アクセスがONになっている必要があります。
簡易アクセスをONにするには設定アプリ起動 → 一般 → アクセシビリティ → 簡易アクセスのスイッチで切り替える</description></item><item><title>モバもく会 #4 を開催</title><link>https://kwmt27.net/2017/09/19/mobile-mockmock-4/</link><pubDate>Tue, 19 Sep 2017 15:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/09/19/mobile-mockmock-4/</guid><description>2017/09/03(日)にモバもく会#4という、モバイルに関連したもくもく会を開催しました。
今回は5人でした。今回みなさんがやったことは次のとおりです。
一人はVR(前回の続き) 個人でAndroidアプリ(ゲーム)を作る 個人でiOSアプリを作っているが、終盤に入っていろいろ不具合を発見したので、その修正 Androidのインストール広告についての技術調査 僕は、個人的にiOSアプリを作っていて、AWSのDynamoDB・Lambda・API GatewayつかってCRUDを構築するところやっていきました。
自分的には、アプリを作るのもいいけど、ちょこちょこ時間とってできるので、こういうまとまった時間をってやるもくもく会では、やっぱり気になるソースコードとかを読んだりした方がいい気がしてきました。(参加者のみなさんが、アプリを作ったらいけないとかいう話じゃないです。念のため)
あと、もくもく会するとだいたいお腹すく時間なので、ご飯いける方いきましょーと終わる頃に聞いていて、なんか行かないと悪いなという雰囲気にさせちゃってるかもなので申し訳ないんですが、ぜんぜん必須じゃないですよー
今回は簡単ですが、以上です。</description></item><item><title>モバもく会 #3 を開催して、Support Design LibraryのBottomNavigationViewを読んだ</title><link>https://kwmt27.net/2017/08/13/mobile-mockmock-3/</link><pubDate>Sun, 13 Aug 2017 20:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/08/13/mobile-mockmock-3/</guid><description>はじめにモバもく会#3という、モバイルに関連したもくもく会を開催しました。
今回は2人でした。
一人はVR(前回の続き) 僕は、support design libraryの特にBottomNavigationViewを読んでみました。
ガイドライン原文日本語訳 に書いてあるのがどのようにコードで書かれているのかという視点で見てみました。
ちなみに、BottomNavigationというのはこのようなものです。
まとめた内容まとめた内容は長くなったので別記事にしました。
終わりに いままであんまり深く知らなかったことを見ることが出来たので、とても勉強になりました。 Support Design Librayのコードは、そんなに複雑なコードじゃなかったので、読みやすいかなと思いました。</description></item><item><title>モバもく会 #2 を開催して、Github Trending(java)を軽く読んでみた</title><link>https://kwmt27.net/2017/07/30/mobile-mockmock-2/</link><pubDate>Sun, 30 Jul 2017 18:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/07/30/mobile-mockmock-2/</guid><description>はじめにモバもく会 #2という、モバイルに関連したもくもく会を開催しました。
一人は前回来ていただいた方の話を聞いて行ってみようと思って来てくださったり、 東京中心に活動されてる方がたまたま大阪に来ていて、大阪の宿泊している場所ではやりにくいので、参加してくださったり、 家にいるとスプラトゥーンをやってしまうから、こういうもくもく会はありがたいというお声を頂き、嬉しい限りです。
モバもく会としては、途中で帰られる方がいらっしゃったのでせっかく足を運んで来てくださってるので、帰られる方の話も聞きたいし、その方に対しても何かしら持ち帰ってほしかったので、途中で発表し合うようにしました。
今回みなさんがやったことは次のとおりです。
一人は次の勉強会のための資料作成(マテリアルデザイン) 一人も次の勉強会のための資料作成(Notificationに関すること) 一人はVR 一人はお仕事でMonakcaについての調査 僕は、前回に引き続き、2017/07/30の時点のGithub Trending(java)の中から2つレポジトリを見てみました。
下記は除外しています。
SmartRefreshLayoutは前回よんだので除外 android-interview-questions spring-boot StormPlanehttps://github.com/HurTeng/StormPlane
飛行機のゲームです。apkをAndroid端末にインストールして遊んだだけですw 飛行機を動かすのに、飛行機をタッチしないといけないのですが、指が邪魔で飛行機が全然見えなくて、ちょっとやりにくかったです。
コードとしては、SurfaceViewを使ってゴリゴリ書いてるだけなので、僕にとって特にこれと言って新しいことはありませんでした。
あと、Readmeとかが中国語なのでGoogle翻訳に頼りました。
PLDroidShortVideohttps://github.com/pili-engineering/PLDroidShortVideo
snowアプリみたいなことができるライブラリのようです。
起動してスタンプを選択して、顔にカメラを向けると、
このようになり、保存できます。
あと動画も撮れるようですが、スタンプを入れたまま動画の作成は出来ませんでした。
これも中国語でした。
まとめ中国語のレポジトリがトレンドに入ってる来てるので、中国語も勉強しないといけないと思いましたが、よくよく考えると中国製のライブラリを実運用で使うことは無さそうなので、次からは中国製のライブラリはやめてみようかと思います。</description></item><item><title>モバもく会を開催して、Github Trendingを軽く読んでみた</title><link>https://kwmt27.net/2017/07/20/mobile-mockmock/</link><pubDate>Thu, 20 Jul 2017 22:00:00 +0900</pubDate><guid>https://kwmt27.net/2017/07/20/mobile-mockmock/</guid><description>はじめにモバもく会という、モバイルに関連したもくもく会を開催しました。 一人はOpenSourceにプルリクを投げたり、一人は読書をしていました。
僕は、2017/07/17の時点のTrending in open sourceのAndroidに関係ある上位3つのサンプルをうごかしてみたのですが、そのときのまとめです。(※android-interview-questionsは除外しています)
https://github.com/trending/java?since=weekly
SmartRefreshLayouthttps://github.com/scwang90/SmartRefreshLayout
Pull to refreshのいい感じのライブラリです。 動きはReadmeに書かれてるので見てみてください。
基本的にはRecyclerViewをSmartRefreshLayoutで包めばよいだけのようです。
&lt;android.support.v7.widget.Toolbar style=&#34;@style/AppTheme.Toolbar&#34; android:id=&#34;@+id/toolbar&#34; app:title=&#34;@string/fragment_refresh_styles&#34;/&gt; &lt;com.scwang.smartrefresh.layout.SmartRefreshLayout android:id=&#34;@+id/refreshLayout&#34; android:layout_width=&#34;match_parent&#34; android:layout_height=&#34;match_parent&#34; app:srlEnableLoadmore=&#34;false&#34; app:srlEnableHeaderTranslationContent=&#34;true&#34;&gt; &lt;android.support.v7.widget.RecyclerView android:id=&#34;@+id/recyclerView&#34; android:layout_width=&#34;match_parent&#34; android:layout_height=&#34;match_parent&#34; android:background=&#34;@android:color/white&#34; tools:listitem=&#34;@android:layout/simple_list_item_2&#34;/&gt; &lt;/com.scwang.smartrefresh.layout.SmartRefreshLayout&gt; サンプル動かしてみました。
「下拉可以刷新」などの中国語で書かれてるところを変更したいなぁと思ってソースを見てみました。
こちらを見る限り、おそらくmHeaderTextにセットすればいいのかなぁと思ってみてたら、mHeaderTextに外から自由にセットできるメソッドがないっぽい。。
public static String REFRESH_HEADER_PULLDOWN = &#34;下拉可以刷新&#34;; とpublic static Stringでfinalではなかったので、直接書き換えてみたところ、
index 2b056cd..fbdf4a7 100644 --- a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshStylesFragment.java +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshStylesFragment.java @@ -85,6 +85,7 @@ public class RefreshStylesFragment extends Fragment implements AdapterView.OnIte @Override public void onViewCreated(View root, @Nullable Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); + ClassicsHeader.</description></item><item><title>HerokuでGoアプリケーションを動かしたい</title><link>https://kwmt27.net/2017/03/23/how-to-deploy-go-application-on-heroku/</link><pubDate>Thu, 23 Mar 2017 12:17:50 +0900</pubDate><guid>https://kwmt27.net/2017/03/23/how-to-deploy-go-application-on-heroku/</guid><description>はじめにGoで作ったWebアプリケーションをHerokuにデプロイする手順を書いておこうと思います。最初はDockerを使わずにデプロイし、あとでDocker化してみようと思います。
セットアップHerokuのコマンドラインツールのインストールHerokuのコマンドラインツールをインストールしましょう
こちらから各環境のコマンドラインツールをインストールできます。
そしてツールをインストールしたら、
% heroku login でログインしておきます。
Heroku側にnew appを作成HerokuにデプロイするためにHerokuに新規アプリを作成しましょう
% heroku apps:create heroku-with-go --buildpack heroku/go --buildpackはHeroku上でビルドするのに必要ですのでGo用のbuildpackを設定しておきます。オープンソースですので、こちらで見ることが出来ます。
新規アプリが作成されたかブラウザで確認してみます。
% heroku open --app heroku-with-go Goアプリケーション作成してからHerokuデプロイまでGoアプリケーションを準備するのですが、Getting Started on Heroku with Goには、Githubからサンプルをクローンしてきて、デプロイしてみようみたな感じですが、ここではこのサンプルは使わず、1から自分で作ってみようと思います。
プロジェクト(ディレクトリ)作成$GOPATH にWebアプリケーションプロジェクトを作成しましょう。 今回はheroku-with-goディレクトリを作成しました。
$ mkdir $GOPATH/src/github.com/kwmt/heroku-with-go heroku-with-go にWebアプリを書いて行きましょう。
main.go作成とりあえず、簡単のためにURLのPathを表示するだけのアプリを書いてみます。(環境変数PORTを取得できるようにする必要があります)
package main import ( &#34;fmt&#34; &#34;log&#34; &#34;net/http&#34; &#34;os&#34; ) func main() { port := os.Getenv(&#34;PORT&#34;) if port == &#34;&#34; { log.Fatal(&#34;$PORT must be set&#34;) } http.HandleFunc(&#34;/&#34;, handler) http.ListenAndServe(&#34;:&#34;+port, nil) } func handler(w http.</description></item><item><title>CSSで横スクロールしたい + Riot.js</title><link>https://kwmt27.net/2017/01/19/i-want-to-side-scroll-by-css/</link><pubDate>Thu, 19 Jan 2017 00:32:48 +0900</pubDate><guid>https://kwmt27.net/2017/01/19/i-want-to-side-scroll-by-css/</guid><description>横スクロールしたい &lt;ul&gt; &lt;li&gt;要素1&lt;/li&gt; &lt;li&gt;要素2&lt;/li&gt; &lt;li&gt;要素3&lt;/li&gt; &lt;li&gt;要素4&lt;/li&gt; &lt;/ul&gt; とHTMLがなっているとき
/*画像リストを横スクロール*/ ul { overflow-x: scroll; white-space: nowrap; } li { display: inline-block; padding-right: 5px; } とする。 liはブロック要素なのでdisplay: inline-block;でインラインブロック化して横な並びになります。white-space: nowrap;で改行も半角スペースにすると横のサイズからはみ出て、それをoverflow-x: scroll;でスクロールさせます。
サンプルhttps://embed.plnkr.co/awNm98DSBsyTar0sLnY3/</description></item><item><title>3本タップでウィンドウを動かしたい</title><link>https://kwmt27.net/2017/01/05/i-want-to-move-window-with-three-fingers/</link><pubDate>Thu, 05 Jan 2017 17:52:06 +0900</pubDate><guid>https://kwmt27.net/2017/01/05/i-want-to-move-window-with-three-fingers/</guid><description>困ったこといままで3本指でウィンドウを動かしていたので、クリーンインストール後も3本指で動かしたいと思ったが、システム環境設定のトラックパッドでどうしても見つからない。
ので、しらべて見つけたのでメモ。
対処法下記の記事通り。 https://support.apple.com/ja-jp/HT204609
システム環境設定→アクセシビリティ に行き、左側の「マウス/トラックパッド」を選択後、「トラックパッドオプション」をクリックする。
「ドラッグを有効にする」にチェックが入っていないのでチェックを入れ、右側のリストで「3本指のドラッグ」を選択してOKを押せば3本指でウィンドウの移動が可能になる。
以上</description></item><item><title>macのコマンド+F1(⌘+F1)でウィンドウ切り替えができないときの対処法</title><link>https://kwmt27.net/2017/01/05/command-f1-dont-switch-window/</link><pubDate>Thu, 05 Jan 2017 15:18:39 +0900</pubDate><guid>https://kwmt27.net/2017/01/05/command-f1-dont-switch-window/</guid><description>困ったことEl Capitanをクリーンインストールしたのですが、⌘+F1キーでウィンドウの切り替えができない!
設定方法がすぐにはわからなかったのでメモ。
対処法システム環境設定→「キーボード」→「キーボード」タブに行くと下図のような画面がでます。 そこで、「F1、F2などのすべてのキーを標準のファンクションキーとして使用」にチェックが入ってないと思いますので、そこにチェックを入れるだけで⌘+F1でウィンドウの切り替えができるようになります。</description></item><item><title>SublimeText3の設定たち</title><link>https://kwmt27.net/2017/01/05/sublimetext-settings/</link><pubDate>Thu, 05 Jan 2017 14:47:25 +0900</pubDate><guid>https://kwmt27.net/2017/01/05/sublimetext-settings/</guid><description>はじめにmacをクリーンインストールして、Sublime Text3を入れ直したはいいが、シンタックスハイライトされてないのがあったので設定する方法をメモ
事前準備パッケージコントロールが入っていなかったらインストールします。
こちらに書いているとおり、下記のimport~をコピーして、View &gt; Show Consoleを開いて、そこに貼り付けてエンターキーを押します。 https://packagecontrol.io/installation
コマンドパレットを呼び出すにはCommand+Shift+Pを押す(Tools→Command Pallet…でもOK)
下図のようなもの 基本的なインストール方法例えば、 Dockerfile syntax Highlightingを設定したい場合は下記手順のようになります。
コマンドパレットを呼び出します。 「Package Control: Install Package」を選択 「Dockerfile Syntax Highlighting」を選択 パッケージDockerfileのシンタックスハイライトを設定するDockerfile syntax Highlighting
こんな感じになって快適!
シェルスクリプトのシンタックスハイライト設定ShellScriptImproved
Markdownのシンタックスハイライト設定Monokai Extended Markdown Extended
Monokai Extendedを入れたら、SublimeText→Preferences→Color Scheme→Monokai Extended→変更したいカラーテーマを選ぶ</description></item><item><title>2016振り返り</title><link>https://kwmt27.net/2016/12/31/looking-back-2016/</link><pubDate>Sat, 31 Dec 2016 23:55:03 +0900</pubDate><guid>https://kwmt27.net/2016/12/31/looking-back-2016/</guid><description>昨年に引き続き、今年で4回目の振り返りを書いておこう。
仕事2015年12月後半からGoでAPI開発を担当していて、2016年の3月近くまで引き続き担当させていただきました。この経験からオレオレフレームワークgozenを公開しています。焼肉御膳だったりまだまだgozenでやりたいことだったり、Goのアンチパターンもあったりしますが、緊張感を高めるために公開しています。
1月の途中からはAアプリの次期バージョンも始まりましたね。おかげさまで会社としてはAndroid,iOS,APIを担当させてもらっているのですが、僕はAndroidを主に担当させてもらっています。
さらにCアプリも始まりました。WebViewのガワアプリだったのでそこまで大変ではなかったのですが、複数案件重なるとちょっとスケジュールをしっかりたてないとダメですね。とくに遅れたとかは無いのですが。
4月ごろから会社としてkotlinを使わせて頂く案件を会社としてやらせていただきました。というか、会社としてkotlinをやりたいと言って、やらせてもらった形でしたね。快く引き受けて頂いた取引先の方々には感謝です。ぼくはほとんど関わって無いのですが、kotlinは良さげですね。
ただこの頃、RxJavaに興味を持ちはじめてkotlinよりもRxJavaのほうに興味を持ってしまいました。
6月始めからめちゃめちゃユーザーがいるMアプリの改修を担当させてもらいました。もともとバグだらけだったのと、昔の作り方だったりして、改修難しかったです。しかし、WebViewとネイティブのいいところをうまく活かしたアプリですっごく勉強になりました。
Aアプリのマイナーバージョンアップをちょくちょくいただいていましたね。ほんとにありがたいです。
10月もWebVeiewアプリで、Aアプリ(I社さん)をやらせて頂きました。10月から新しくデザイナの方が入社し、彼がデザインを担当しています。
11月はGCPの勉強会に参加させて頂きました。3日間連続で。この勉強会に関してはご縁さまさまです。GAEをやってるの覚えて頂いた方から個別にご連絡があり、大阪でGCP広めたくて勉強会するけどどうみたいな内容で、会社がOKだったので即OKで会社全員(3人)で参加しました。
そういえば、IoT絡みでArduinoを少し触りました。WifiモジュールのESP-WROOM-02を触ってみましたが、少し難しくてネットにつながらず断念。ラズパイ3を買ってそれで、光センサでランプのON/OFFを検知してSlackに投げるというのを作りました。Slackに投げるのはGoのライブラリを作り、それで投げています。
最後もやっぱりAアプリのバージョンアップでした。こちらは少し見積もりが甘くて、意外と大変でした。。。(汗) あとCordovaも見積もりだけやりました。Cordovaも案件に依ってはありかもですね。
勉強会 1月 golang 勉強会 3月 ABC スタッフとして参加 4月 kotlin 勉強会 gocon 7月 kotlin 勉強会 8月 umeda.apk 勉強会 10月 larabel 勉強会 11月 GCP 第5回 八子クラウド座談会in関西 「関西まるっとIoTでやったらんかい♬」 Devfest Kansai2016 スタッフとして参加 12月 Goモク会開催 来年の目標今年はGoやっぱり面白いなと思った年なのとAndroidも奥が深いなと思いました。 でもiOSもやりたいので、来年はiOSもやりつつ、いま個人的にWebサービスをGoで作ってるので、これも完成させたいです。
まとめ今年もお世話になったみなさまありがとうございました。来年も引き続きよろしくお願いします。(ってこのまとめ、去年のまとめといっしょやんw)というのがいっしょかw</description></item><item><title>werckerの独自stepの作り方</title><link>https://kwmt27.net/2016/12/25/how-to-create-wercker-step/</link><pubDate>Sun, 25 Dec 2016 14:08:59 +0900</pubDate><guid>https://kwmt27.net/2016/12/25/how-to-create-wercker-step/</guid><description>はじめにwercker CIでApplicationを新規作成したときにGoのテンプレートに下記のような記述を見かけました。
steps: - setup-go-workspace これは、主にGoパッケージを作ったとき向けのセットアップっぽく、オレオレフレームワークなどには使いにくかったので、ここを変更できたらいいなと思って調べていたら、どうも このレポジトリにあるrun.shを実行してるっぽく、setup-go-workspaceはwercker-step.ymlで定義されてるっぽい。
なんとなく、wercker-step.ymlとrun.shが必要そうってことはわかったけど、どうやって使うんだろうと思ったのがきっかけです。 そしてすぐにはわからなかったのでメモしておこうと思います。
stepの作成からそのstepの使用まで独自stepの作成ということで、まずwercker-step.ymlとrun.shという名前のファイルを用意します。
% mkdir wercker-step-helloworld &amp;&amp; cd wercker-step-helloworld % echo &#39;name: helloworld\nversion: 1.0.0&#39; &gt; wercker-step.yml % echo &#39;echo &#34;hello world!&#34;&#39; &gt; run.sh ドキュメントにあるようにwercker-step.ymlには、nameとversionだけが必須です。
run.shには、hello world!と表示するだけのスクリプトを書いておきます。
GitHubにレポジトリを作ってプッシュします。 ということで、プッシュしたものがこちら。 https://github.com/kwmt/wercker-step-helloworld
Wercker directoryにデプロイ先ほど作成したものをwerckerに登録して公開する必要があります。
こちらからhttps://app.wercker.com/stepを作成します。 このとき先ほどwercker-step.ymlとかをプッシュしたレポジトリを指定します。
これでビルドが走ると思います。
これだけではまだ使えなくて、Wercker directoryというところにDeployする必要があります。 Wercker directoryにDeployするには、deploy targetを指定する必要がありますが、新しく追加しなくても、publish-stepというDeploy targetがすでに作成されてるはずなので、それを使います。
先ほどのビルドが成功したら、ビルドの詳細画面でBuild passedと出ている右側にDeploy toというドロップダウンがあるので、そこをクリックして、publish-stepというDeploy targetを指定し、Start deployをクリックするとデプロイされます。
デプロイされると下記URLのような感じになります。 https://app.wercker.com/applications/585f2630d8cb9e0100c142c4/tab/details/
自作したstepをwercker.ymlで使う自作したstepを使うには、wercker.ymlに次のように記述します。
steps: - kwmt/helloworld これでwerckerを走らせると、
hello world!が出力されてることがわかると思います。
おわりにwercker-box.ymlというのもあってwercker directoryにデプロイするなどは同じっぽいのでこちらはさくっとできそう。 今気づきましたが、werckerのgolangのboxって、今日(2016/12/25)時点で、go1.5なんですね。。 https://github.com/wercker/box-golang</description></item><item><title>ginを軽く読んでみる</title><link>https://kwmt27.net/2016/12/11/reading-gin-gonic/</link><pubDate>Sun, 11 Dec 2016 20:49:46 +0900</pubDate><guid>https://kwmt27.net/2016/12/11/reading-gin-gonic/</guid><description>はじめに[大阪]Goモク会を開催しました。 https://connpass.com/event/13696/ gomobileを使ってアニメーションさせたりレコメンドシステムを作ったりしてる人がいる中、僕はginのコードリーディングをしました。
読んでみるReadmeに書いてるサンプル
package main import &#34;gopkg.in/gin-gonic/gin.v1&#34; func main() { r := gin.Default() r.GET(&#34;/ping&#34;, func(c *gin.Context) { c.JSON(200, gin.H{ &#34;message&#34;: &#34;pong&#34;, }) }) r.Run() // listen and serve on 0.0.0.0:8080 } gin.Default()gin.Default() から見ていきます
// Default returns an Engine instance with the Logger and Recovery middleware already attached. func Default() *Engine { engine := New() engine.Use(Logger(), Recovery()) return engine } まずは、New() ですね。 コメントにありますが、Logger と Recovery ミドルウェア付き Engineインスタンスを作成します。
// New returns a new blank Engine instance without any middleware attached.</description></item><item><title>Cloud Vision API & Tensorflow勉強会</title><link>https://kwmt27.net/2016/04/30/cloudvisionapi_and_tensorflow/</link><pubDate>Sat, 30 Apr 2016 12:10:44 +0900</pubDate><guid>https://kwmt27.net/2016/04/30/cloudvisionapi_and_tensorflow/</guid><description>佐藤さん ニューラルネットワーク Neural Network : a function than can learn
いままでは定石をいれといて、それを使っていたが、 alphaGoは人間が予想がつかない
分類 身長と体重が分かっていた場合、男か女かを判別したい例 身長と体重をいい感じの組み合わせ方をコンピューターが計算
ニューロン?
データはなんでもいい。 例:画像・音声・センサーのデータ・広告のプロファイル しかし、ニューラルネットワークに当てはまる・ハマらないがあるかもだが。
学習のデータを与えるだけで、いい感じに分類してくれる
ボトルネック 計算量:時間かかる データ:学習用データ
事例 一般の事例 ISETANさん:動線分析 あまり事例がない Googleはたくさん使ってる
人間がタグ付けしてないのに、勝手にタグづけしてくれる
注意 Google Cloud Vision APIの人識別は、個人の識別はやっていない Google フォトはやっている。
Cloud Spech API Limited Preview
QA VisionAPIにアップロードした画像は、学習に使うことはない なぜなら、クレームがくるから。 調査のために使うことはある。
右回れ、左回れは、意味を理解しているのか? していない。if文で右・左書いてるだけ。 ただ、言葉の意味を理解するAPIも近々でる予定</description></item><item><title>関西モバイルアプリ研究会 #13に行ってきた</title><link>https://kwmt27.net/2016/04/27/kanmoba/</link><pubDate>Wed, 27 Apr 2016 13:01:45 +0900</pubDate><guid>https://kwmt27.net/2016/04/27/kanmoba/</guid><description>4/26(火)は、 関西モバイルアプリ研究会 #13 に参加しました。
きになったところhttp://wantedly.connpass.com/event/29039/の資料を見てみると面白そう。
RxSwiftは4/24に知ったけど、ReactiveCocoaというのもあるのね。。
RxSwiftとの違い
エラーの型付け UIBindingが豊富なRxSwiftに流れていたが、Rexというのがあります。そしてこれをReactiveCocoaのリポジトリへ移そうとしています。Rex込でReactiveCocoaを検討していただけると良い選択肢だと思います。 「エンジニアさんでもデザインできちゃう Adobe Xd のススメ」 https://blogs.adobe.com/creativestation/web-how-to-play-with-adobe-xd ちょっと使ってみたい!</description></item><item><title>Google Developers Summit Tokyo 2016 | Android に行ってきた</title><link>https://kwmt27.net/2016/04/27/google-developers-summit/</link><pubDate>Wed, 27 Apr 2016 12:23:03 +0900</pubDate><guid>https://kwmt27.net/2016/04/27/google-developers-summit/</guid><description>はじめに4/25(月)は、Google Developers Summit Tokyo 2016に行ってきました。
まとめようかと思ったけど、この方の記事が超まとまってて、書くことが何もないので、こちらのリンクだけはらせて頂きます。まとめありがとうございます! http://yuki312.blogspot.jp/2016/04/google-developers-summit-tokyo-2016.html?m=1
だけど、ぜんぶではないが自分もメモとってたので、わかりにくいけどメモをペタッと。
メモ7月から9月(第三四半期)に最終版 本日はPreview2のステージ
www.google.com/android/beta より登録 対象:Nexus6以降 http://www.sli.do/ 1656
江川さん複数バージョンの共存 applicationのファイル名を変更すればよいだけ。 なるべくtoolバージョンをあげて、targetSDKはあとであげることが可能 AS2.1 JDK8のインストール必須 Jack and Jill Jack and Jill Androidno新しいツールチェイン Jack:コンパイラ Jill:リンカ 特徴 classにする工程がない Android NはJackでコンパイルされている 問題 Preview時に実行 AS2.1 に関するフィードバッグ http://b.android.com &quot;Android Studio Bug&quot;, &quot;Jack bug report&quot;を選択して投稿 Android Studio BugだとAndroid Studio担当者にアサインされる。featureだとAS担当者にアサインされない可能性がある DEXについて dexInProcess デフォルトでtrue ひとつのVM メモリ不足対策 gradle.propertiesにorg.grdle jv シュリンク機能 不要メソッドを消去したい 接続中に特化したtパッケージの生成 例:複数端末接続していた場合、xxhdpiがいらない端末であれば、そのリソースを含まないようにデプロイする(Android Studio経由) Instant Run 下記のような場合、パフォーマンスが落ちる問題が起きる multiDexEnabled trueかつminSdkVersion 20の場合 Dexに含まれるメソッド数が本来の数より増える Jackと併用負荷 Android Emulator2 App Indexing支援 荒木さんAndroid N Preview4まではAPIが変わる可能性がある Preview4は24に変わる予定 過去の端末もプレビューできるようになる予定 マルチウィンドウ Picture in Picture(TV) TV限定フローティングウィンドウのようにぽこっと出る 二分割 自由形式 OEMのボードによる リサイズ問題 新しいAPIはない。これまで通り。best practiceに従っている限り綺麗に表示されるハズ リサイズ ライフサイクル これまで通り リサイズはこれまでの画面回転と一緒。 active ON onResumeが呼ばれている active OFF onPauseが呼ばれてとまってる 動画上で、twitterが下した場合 onPauseで動画を止めてはだめ。onStopで止める。 既存のアプリはマルチウィンドウを許可されている状態になっている。 ただし、縦固定しているとマルチウィンドウにはならない。 マルチウィンドの判定のAPI追加 マルチウィンドウ切り替え 分割、自由形式は アプリから制御できない。右側の□ボタンを長押することだけしかできない 通知 直接返信 通知から直接返信できる グループ化 カスタムビュー setContentはdeprecated Java8 Android向けのJava8はJackでないとコンパイルできない ``` android{ jackOptions { enabled true } } ``` ラムダ button.</description></item><item><title>集まれSwift好き!Swift愛好会 #6に行ってきた</title><link>https://kwmt27.net/2016/04/27/love-swift-6/</link><pubDate>Wed, 27 Apr 2016 11:02:08 +0900</pubDate><guid>https://kwmt27.net/2016/04/27/love-swift-6/</guid><description>はじめに4/24(日)は集まれSwift好き!Swift愛好会 #6に参加させて頂きました。
結論から言うと、朝10:30から23:30までずっと飲みっぱなしの勉強会でしたw
toggeter
勉強会の概要と感想午前中はモクモクしてました。swift1.2ぐらいのプロジェクトがあり、それを2.2対応して2.2の文法などを見なおしていていました。
午後からも少しもくもくしてからの談義(プレゼン)が行われました。
Reproの奥澤さんと川上さんはプロトコルについて発表されて、ひさしぶりswift触る自分としては、プロトコルについて思い出せてよかったです。 継承よりプロトコル使ったほうがなんでいいのかもすごい分かりやすかったです。
熊谷さんの 「Swift 標準プロトコルを旅して Swift と楽しく会話してみよう」の話はLTといいつつ40分の超対策でとてもおもしろかったです。 CollectionTypeなどのプロトコルの中身(コード)を見ていったのですが、どのように考えながら見て行ったらより理解が深まるかを教えて頂きました。 プロトコルを眺めていったん想像してみることが大事だと思いました。
さかいさんのUIPageViewControllerとContainerViewの話もすごい丁寧な発表で勉強になりましたね。 https://twitter.com/fumisac/status/724155827003613184
ひろせさんの自作ライブラリ(下記)の紹介でした。SegueAddtionはクロージャでprepareForSegureを書けて、コードが離れないのがいいなと思いました。 ResourceKitは文字列として扱うのではなくて、定数として使えて補完も効くようになるのがいいなと思いましたが、導入がちょっとめんどくさい?という印象でした。
https://github.com/bannzai/SegueAddition https://github.com/bannzai/ResourceKit Reproの七島さんから RxSwift触ってみたという発表がありました。 RxSwiftしらなかったですが、超いいかんじにかけるじゃんって思いました。
ほか懇親会などでお聞きした情報をメモ。サーバーサイドSwiftはIBMの Kituraしか知らなかったんですが他にも Vaporというのがあると聞きました。まだバージョンアップしてるらしく、古い情報だと動かないらしいので、最新(公式)の情報をみるといいのかなと思いました。
また、swift2.2から Swift Package Managerなるものが導入されてると聞いてCocoa Podsが要らなくなる日がくるのかなと。こちらは早めに試してみたいところです。
写真</description></item><item><title>GoCon 2016 springに行ってきた</title><link>https://kwmt27.net/2016/04/27/gocon-2016-spring/</link><pubDate>Wed, 27 Apr 2016 10:09:38 +0900</pubDate><guid>https://kwmt27.net/2016/04/27/gocon-2016-spring/</guid><description>4/23(土)は、GoCon2016 Springに行ってきました。
イワタプロが資料一覧をまとめてくださってましたので、乗っかります
資料一覧
toggeterはこちら
概要だけ書いておこう。
Daveさん:エラーの話 Makiさん:APIサーバーを書きたくない話 motemenさん:Goコードを読む話 shibukawaさん:GUIの話 hirataさん:elastic beatの話 kazegusuriさん:gRPC導入 鶴岡さん:GoとGAEのweb app開発の話 vvakameさん:webフレームワーク(ucon)作成した話 stanakaさん:コントリビュートしたときの話 yoshiki nakagawaさん:Goサーバーのプロダクション環境の話 kaneshinさん:Cloud Vision APIをGoでやってみた話 methaneさん:パフォーマンスチューニングの話 あとLTも盛り沢山 ストリートファイター4をGoをつかって操作の話はもりあがりましたね。 https://github.com/cero-t/cero-macro.go https://twitter.com/cero_t/status/724267524963991553</description></item><item><title>第3回 関西golang勉強会メモ</title><link>https://kwmt27.net/2016/04/17/study-golang-in-kug2/</link><pubDate>Sun, 17 Apr 2016 13:32:22 +0900</pubDate><guid>https://kwmt27.net/2016/04/17/study-golang-in-kug2/</guid><description>第3回 関西golang勉強会 に行ってきたメモです。
テレビ連動プラットフォームでのGo @ingtk at HROID* GoMock https://github.com/golang/mock * go-errors/erros スタックトレースエラー表示できる https://github.com/go-errors/errors * コードバレッジ gocov * デバッガ delve https://github.com/derekparker/delve ターミナルでブレイクポイントはってステップ実行できる プロセス動いてるものをアタッチして実行できるので本番で動いているものをデバッグできるので便利 *プロファイル pprof listコマンドで関数内に入ることができる go破壊(gohakai) hattori hideo at KLab* Go破壊とは httpサーバー用の負荷テストツール https://github.com/KLab/gohakai fan-out マスターオブreflectパッケージ2 @tenntennhttp://www.slideshare.net/takuyaueda967/reflect-ii goでp2pしよう! @nobonobohttp://golang.rdy.jp/go-p2p/#/ 俺と生活とgolang @みゅうみゅう</description></item><item><title>機械学習勉強会メモ</title><link>https://kwmt27.net/2016/02/28/study-machine-learning/</link><pubDate>Sun, 28 Feb 2016 12:50:27 +0900</pubDate><guid>https://kwmt27.net/2016/02/28/study-machine-learning/</guid><description>2/27に近畿大学で行われた機械学習勉強会に行ってきました。
波部先生 @habhit slideshareに上がる
機械学習とは「データの集合からその法則性を学ぶ」 写像で表せるf:x-&gt;y
x:特徴抽出(特徴ベクトル) y:識別0,1,2,回帰:実数値、異常検知:0,1 人工知能 人間の知能 と同等なものを目指したシステム全体 機会学習 ∈ 人工知能 パターン認識 音声・画像からスタート 機会学習はそれらとは関係無く記号的な世界からスタート 現在ではあまり差はない
問題設定
教師あり フェリーか飛行機がわかってる 教師なし フェリーか飛行機がわからない 半教師 一部はフェリーか飛行機がわかってるが他は不明 学習結果の評価 やったことがどんだけいいのか 汎化性能 限られたデータを使って汎用的な識別規則を学習できるか? 学習データにはいっていないものが識別できるか 過学習 わかってるデータ Q.過学習してるんじゃないの? A.交差検証法してますから 主な学習
線形回帰の基本 入力と出力の差の2乗の和が最小になるように係数を決める
リッジ回帰 予測誤差だけでは過学習が起こる
ロジスティック回帰 「あるクラスに属する確率」 確信度
まとめ
基本はf:x-&gt;y