- 投稿日:2019-03-24T23:48:16+09:00
NavigationViewの区切り線の高さを変える
はじめに
Design Support Libraryの
NavigationViewを使ってナビゲーションドロワーを実装しており、各グループ毎に表示される区切り線(separator)の高さを調整したいという要望がありました。StyleやAttributeで簡単に実現できるだろうと思っていたのですが、ちょっとハマったのでメモします。
実装
NavigationViewの基本的な実装は 公式のドキュメント を参考に進めます。独自のレイアウトを使いたい場合はactivity_main.xml<DrawerLayout> <FrameLayout /> <NavigationView> <include layout="@layout/navigation_view"> </NavigationView> </DrawerLayout>みたいな感じでよしなにやってくれればいいかと。XMLで設定できる内容を 公式ドキュメント で確認します。
XML attributes 内容 itemBackground メニュー項目の背景を指定したリソースに設定する。 itemIconTint メニュー項目のアイコンに適用される色を設定する。 itemTextAppearance メニュー項目のテキストの外見を指定したリソースに設定する。 itemTextColor メニュー項目のテキストの色を設定する。 と、区切り線に関する設定は表記されていませんでした。次にDesign Support Libraryで
NavigationViewがどのように実装されているのかAndroid Studioを使ってソースコードを追ってみました。ヘッダー、メニュー項目、サブタイトル、などのレイアウト(ViewHolder)の読み込みは
NavigationMenuPresenterで行われていました。区切り線(separator)の部分はNavigationMenuPresenter.javaprivate static class SeparatorViewHolder extends NavigationMenuPresenter.ViewHolder { public SeparatorViewHolder(LayoutInflater inflater, ViewGroup parent) { super(inflater.inflate(layout.design_navigation_item_separator, parent, false)); } }という実装でした。この読み込んでいる
design_navigation_item_separator.xmlを上書きしてしまえば、ワンチャンいけるのでは
before after いけました。具体的にはDesign Support Libraryと同名のレイアウトを作成するだけです。
design_navigation_item_separator.xml<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <View android:layout_width="match_parent" android:layout_height="8dp" android:background="?android:attr/listDivider" /> </FrameLayout>
まとめ
本来であれば
RecyclerViewを配置してゴニョゴニョするのがセオリーだと思うのですが(Stack Overflowでもそのように回答されてました)、手を抜きたいなるべシンプルな実装を目指した結果こうなりました。なお、あくまでも個人の解決方法であり、これが正しい実装とは限りませんのでご了承ください。また、Design Support Libraryのバージョンを更新した場合、リソースの名称が変更される可能性があるので、都度確認する必要がありそうです。サンプルを GitHub にアップしておきます。
どうでもいい話
ナビゲーションドロワーは『ハンバーガーメニュー』とも呼ばれます。由来としては、メニューの横3本線で構成されたアイコンがハンバーガーに見えるかららしいです。
参考文献
- 投稿日:2019-03-24T23:13:49+09:00
Flutterウィークリー #51
Flutterウィークリーとは?
FlutterファンによるFlutterファンのためのニュースレター
https://flutterweekly.net/この記事は#51の日本語訳です
https://mailchi.mp/flutterweekly/flutter-weekly-51※Google翻訳を使って自動翻訳を行っています。翻訳に問題がある箇所を発見しましたら編集リクエストを送っていただければ幸いです。
読み物&チュートリアル
デスクトップFlutterアプリ
https://blog.usejournal.com/desktop-flutter-apps-8602dac54f68
Stefan Matthias AustがFlutterデスクトップアプリケーションの作成に関する文書を作成しましたFlutter使って次のiOSおよびAndroidアプリを構築しましょう
FlutterについてのGoogleブログのMartin Aguinisによる記事と、なぜそれが大好きなのか。Flutter単体テスト:httpリクエスト
https://medium.com/@danaya/unit-testing-in-flutter-http-requests-bca215569656
David AnayaがテストでHTTPリクエストをモックする方法を教えてくれますFlutter - BackdropFilter
https://medium.com/@aseemwangoo/flutter-backdropfilter-8f3d6958f635
Aseem WangooがFlutter画像をぼかす方法を紹介します。Flutter Todosチュートリアル "flutter_bloc"
https://medium.com/flutter-community/flutter-todos-tutorial-with-flutter-bloc-d9dd833f9df3
BLoCを使用してTodoアプリを作成する方法に関するFelix AngelovによるチュートリアルReact NativeまたはFlutter :どちらを選ぶべきですか? (パート2)
Rap Payneによる記事の第2部で、 FlutterとReact Native比較しています。フラッタでのモバイルデータベースの移行(sqlite)
https://medium.com/@efthymis/migrating-a-mobile-database-in-flutter-sqlite-44ac618e4897
データベースの移行は常に頭痛の種です、Efthymis Sarmpanisは従うべきステップとそれをどう扱うかを分析します。複雑なFlutterウィジェットのためのAPIデザインのヒント
Amir Hardonは、ウィジェットを作成するときの2つのアプローチについて説明します。Flareを使ったFlutterより良いアニメーション - 実験
https://medium.com/filledstacks/better-animations-in-flutter-using-flare-an-experiment-ddcb35ab0650
Dane MackierはFlareアニメーションを実験していて、それがどのようになったのかを教えてくれます。Flutterドライバを使用したFlutter UIのテスト
https://medium.com/flutter-community/testing-flutter-ui-with-flutter-driver-c1583681e337
Darshan Kawarが、 Flutter機器テストの実行方法を順を追って説明します。Flutter :ウィジェット間のコミュニケーション
https://medium.com/flutter-community/flutter-communication-between-widgets-f5590230df1e
Diego Velasquezが、いくつかのウィジェット間で情報を送信するためのさまざまなアプローチについて説明します。Flutter firebase crashlyticsに公式サポートを追加
https://medium.com/@guitcastro/flutter-add-official-support-to-firebase-crashlytics-198e9deeae1d
Flutter用Firebase crashlyticsプラグインがついに登場しました!Flutter Deep Dive、パート2:「RenderFlexの子供たちはゼロ以外のフレックスを持っています…」
Scott Stollが、 Flutter最も厄介なエラーメッセージについて説明し、それを詳細に説明します。DartをUIのためのより良い言語にする
https://medium.com/dartlang/making-dart-a-better-language-for-ui-f1ccaf9f546c
DartチームのBob Nystromが、 Dart 2.3で見つけたDart新機能について説明します。ツールボックス - Flutterチャート
https://fluttersensei.com/posts/the-toobox-charts-for-flutter/
Flutter Senseiが、プロジェクトでchart_flutterライブラリを使用する方法を紹介します。ビデオ&メディア
Flutterチュートリアル - Flutter FutureBuilder(とJSONData)
https://www.youtube.com/watch?v=DaeYeAiF3UU
このビデオでは、FutureおよびFutureBuilderウィジェットを使用して、フラッタアプリケーションでJSONデータを処理する方法を説明します。Flutter - スクロール効果
https://www.youtube.com/watch?v=2RPl7rwYjnQ&feature=youtu.be
Raja Yoganが、あなたのアプリの見栄えを良くするためのスクロール効果について説明します。却下可能(今週のFlutterウィジェット)
https://www.youtube.com/watch?v=iEMgjrfuc58&list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG&t=0s&index=29
Dismissibleウィジェットを使用すると、左または右にスワイプしてリスト項目を消去できます。Hacker Newsアプリを暗黙のうちにアニメーション化する(The Boring Flutter Development Show、Ep。18)
今週のボーリングショーで、AndrewとFilipが、暗黙のアニメーションと明示的なアニメーションの違いについて説明します。Flutter + Firebaseを使った、反射的なアニメーションのスライドショー
https://www.youtube.com/watch?v=8PfiY0U_PBI&feature=youtu.be&app=desktop
PageViewウィジェットを使用してFlutterアニメーションスライドショーを作成し、それをCloud Firestoreでフィルタリングできるようにします。Flutter - Layout Builderを使用してモバイルおよびタブレット用のレスポンシブレイアウトを作成する方法
https://www.youtube.com/watch?v=cDxSMJBzRVI&feature=youtu.be
このチュートリアルでは、 Flutter Layout Builderウィジェットを使用してレスポンシブレイアウトを作成する方法を説明します。#ProjectCampus - 最初からFlutterソーシャルネットワークアプリケーションを構築する
https://www.youtube.com/watch?v=edZm8b_vvXw
私たちはFlutterソーシャルネットワークを構築しています。一から。カメラの前でライブ。 Flutter用の独自のアプリを作成する方法を学ぶべきだと私たちは考えています。FlutterでFlutterを使用する - Flutter In Focus
Emily FortunaがWebViewウィジェットの使い方を紹介します。FirebaseのCloud Firestoreを使用したFlutterページネーション
https://www.youtube.com/watch?v=coR4Y-DkrLc
このビデオでは、 Flutter無限スクロールリストを実装する方法を学びます。ライブラリ&コード
ピンイン/フラグメント
https://github.com/pinyin/fragment
StatefulWidgetとそのサブツリーで不要なbuild()呼び出しを簡単に防ぐことができます。
synw / sqlcool
https://github.com/synw/sqlcool
Sqflite用のデータベースヘルパーライブラリ
itzmeanjan / astroZ
https://github.com/itzmeanjan/astroZ
Androidアプリは、 Flutterを使用して構築された今日の天文写真を表示しています:)
- 投稿日:2019-03-24T22:53:27+09:00
[Flutter] AnimatedCrossFade 試す。
参考:https://docs.flutter.io/flutter/widgets/AnimatedCrossFade-class.html
例。
実際に作ってみた。
main.dartAnimatedCrossFade( firstChild: Text( desc, maxLines: 2, style: TextStyle( color: Colors.white, fontSize: screenAwareSize(10, context), fontFamily: 'Montserrat'), ), secondChild: Text( desc, style: TextStyle( color: Colors.white, fontSize: screenAwareSize(10, context), fontFamily: 'Montserrat'), ), crossFadeState: isExpanded ? CrossFadeState.showSecond : CrossFadeState.showFirst, duration: kThemeAnimationDuration, ), ),main.dartGestureDetector( onTap: _expand, child: Text( isExpanded ? "less" : "More...", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700), ), ),MoreをタッチするとAnimatedCrossFade中のsecondChildがみえます。
- 投稿日:2019-03-24T22:27:22+09:00
はじめまして。このような場を借りて恐縮ですが助けていただけたら幸いです。ひま部という学生限定アプリがあるのですが、だれでも通話という機能があります。
それは通話(音声のみ)とビデオタイプ(カメラオン)の2種類のタイプがあるのですが、ツイッターみたいな感じで時間順、人気順で投稿されます。しかし通話タイプとビデオタイプを区別する機能がなく、ビデオのみを見たい人にとっては探すのが面倒くさいです。そこで、アプリでもwebでもいいので区別して、そこから通話に参加するものをつくることはできるでしょうか?よろしくお願いいたします。
- 投稿日:2019-03-24T20:47:42+09:00
Vuzix Bladeで開発してみた(QRコード読取編)
はじめに
初めましてApv(@apv23973)です。Qiitaに始めて投稿します。
Androidの開発は色々やった事があるのですが、
この度、スマートグラスに興味があってこのVuzix Blade開発にチャレンジしようと思いました。まずSmartGlassと言えば数年前にGoogleが発売したGoogle Glassではないでしょうか?
あまり万人受けしなかった気もしますが、ここ数年、商業用を中心に盛り上がりを見せ始めている産業かと思います。そんな中、私が大変興味を持ったのがVuzix社が出したVuzixBlade SmartGlassです。
出来る限り情報を更新していければと思います。Vuzix Bladeのはじめかた
初めに、VuzixBladeに関して大変参考にさせて頂いたのが
drama(@1901drama)さんが書いたこの記事になります。
なので私の記事はこのはじめかたが終了したと仮定して書きます。Vuzix Blade(ARスマートグラス)のはじめかた
Vuzix Blade(ARスマートグラス)のはじめかた その2QRコード読取について
私が前に開発していたのはEclipseだったのでAndroid Stdioになってこんなに楽なったのかと実感してしまいました。
世間でQRコードの読取が有名なのは、Google が開発して公開している、様々な一次元や二次元のバーコードの生成/操作ができるオープンソースライブラリのZxingだと思います。
なので今回もこのZxingで実装していきます。実装
1. Zxingライブラリーの追加
build.gradledependencies { implementation 'com.vuzix:hud-actionmenu:1.1' implementation 'com.vuzix:hud-resources:1.1' implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' implementation 'com.google.zxing:core:3.2.1' }こんな感じになります。
2. カメラ起動用にpermissionを追加
AndoridManifest.xml<uses-permission android:name="android.permission.CAMERA" />これをapplicationタグ外に宣言します。
3.画面の作成
activity_main.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/hud_transparent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:gravity="bottom"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="読み取り開始" android:textColor="@color/hud_transparent" /> </LinearLayout> </LinearLayout>今回はシンプルに読取開始のボタンを1つ追加しただけになります。
4.MainActivityの編集
MainActivity.xml@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ボタン割り当て Button btn = findViewById(R.id.button); Listener listener = new Listener(); btn.setOnClickListener(listener); }onCreateはシンプルにボタンリスナーを追加しているだけです。
MainActivity.xmlprivate class Listener implements View.OnClickListener { @Override public void onClick(View view) { // カメラ起動 scanBarcode(view); } } public void scanBarcode(View view) { IntentIntegrator integrator = new IntentIntegrator(this); integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE); integrator.setPrompt("QRコードを読取って下さい。"); integrator.setTimeout(10000); integrator.setCameraId(0); // Use a specific camera of the device integrator.initiateScan(); }読み取り開始ボタンを押した時にカメラを起動して読取を開始します。
integrator.setTimeout(10000);
はカメラのタイムアウトを指定します。
10000msなので10秒で自動的にキャンセル扱いになります。integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
の設定によって何を読取るのか指定ができます。
中身を見ると1次元コード/2次元コードが指定できます。
指定した方が読取がよくなると聞いたことがあります。IntentIntegrator.java// Product Codes public static final String UPC_A = "UPC_A"; public static final String UPC_E = "UPC_E"; public static final String EAN_8 = "EAN_8"; public static final String EAN_13 = "EAN_13"; public static final String RSS_14 = "RSS_14"; // Other 1D public static final String CODE_39 = "CODE_39"; public static final String CODE_93 = "CODE_93"; public static final String CODE_128 = "CODE_128"; public static final String ITF = "ITF"; public static final String RSS_EXPANDED = "RSS_EXPANDED"; // 2D public static final String QR_CODE = "QR_CODE"; public static final String DATA_MATRIX = "DATA_MATRIX"; public static final String PDF_417 = "PDF_417";読取った後の処理
MainActivity.xml@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if(result != null) { if(result.getContents() == null) { // 読取キャンセル Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show(); } else { // 読取成功 Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show(); } } else { super.onActivityResult(requestCode, resultCode, data); } }実装はここまでです。
5.実行
画面のエビデンスを張り付けていますが、
背景色の黒は全て透明化になっています。(グラスつけてるからね・・・)
6.おわりに
Vuzix Bladeでも基本的に通常のAndroidと同じなんだなと言う事がわかりました。
ただ、Buttonのイメージとかが想像よりちょっと違ったかも…載せてはいませんが、ボタンを2つ配置した時はどちらが選択されているのかホント分かりません。
公式サイトにもちょこっと書いてありましたが、UIを決めるのは大事かもしれません。次回は通信関係に手を出してみようかな・・・
ここまで読んで頂きありがとうございました。
- 投稿日:2019-03-24T20:41:42+09:00
iOSとAndroidの定期購読の期間の伸び方の謎
〇概要
iOSとAndroidはともにサブスクリプション(定期購読)の機能が実装されており、購入時に決められた期限が与えられ、有効期限が切迫すると課金継続中なら有効期限が決められた期間分追加されます。
しかし、期限の伸び方の詳細はドキュメントに公開されておらず、よくわからない伸び方をするケースがあるので、実体験からわかった謎ルールをいくつか書いてみます。
謎はあまり解明されてないので、こういうケースもあるのかということで読んでください。
よくわからないことを書いているので、報告や指摘は大歓迎です。
サービスによっては起きたり起きなかったりするかもしれません。今回は期間を一ヶ月に設定して、特に問題が起きやすい2/28,3/1当たりに注目しています。)
〇iOS
・新規購入時の延長
購入日時 + その月の日数 - (0時間 or 1時間)
その月の日数とは1/15に購入すれば1月が31日まであるので31日が延長される。
しかしロサンゼルスとの時差17時間が影響を与えていると思われ、考慮しなければならない。
そのため3/1の16:59までは2月という考え方になり、
例えば日本で3/1の16時に購入すると、2月判定になり28日が足され、3/29日の15時までの期限となるのでユーザーからのクレーム案件になるかもしれないので注意。
(サマータイム外はロサンゼルスと16時間の時差ですが、年中17時間で固定のようです)- (0時間 or 1時間)については日によって全ユーザーがついたり、つかなかったり。その規則性はよくわからず。
ちなみに1/28 - 1/31に購入したものは3/1の有効期限になる。
・自動更新の延長
前回日時 + その月の日数 +- (2時間)
たまに+-2時間が付くが原因不明。
購入した日付を基準に戻ろうとする作用が起こる。
(28日に購入した例)2019-01-28 21:00:00 → 2019-02-28 21:00:00 → 2019-03-28 20:00:00
(31日に購入した例)2019-01-31 21:00:00 → 2019-02-28 21:00:00 → 2019-03-31 20:00:00〇Android
・新規購入時
購入日時 + 31日 + 2時間
3/1の購入は何時でも4/1とわかりやすい。(他社ブログでは時差が影響して3/29になるとの報告もあり)
+ 2時間は多少前後することもある。・自動更新時
前回日時 + その月の日数
その月の日数は11時ぐらいを基準に前日と判断されることもある。時差の影響かもしれない。
iOSと違い、29,30,31日に購入すると、更新時に28日に丸められてしまうので、更新数がその日に偏るので注意。
またユーザーとしては損をするケースとなる。(28日に購入した例)2019-01-28 15:00:00 2019-02-28 15:00:00 2019-03-28 15:00:00
(31日に購入した例)2019-01-31 15:00:00 2019-02-28 15:00:00 2019-03-28 15:00:00そして
2019-01-31 15:00:00 → 2019-03-01 15:00:00 → 2019-03-29 15:00:00となるケースも多くみられ、ひと月に二回決済が行われるため、集計やユーザー対応に困ることもあり。
〇総評
iOSは17時間の時差を考慮しないといけないので悩みもの。
それ以外は大分素直。Androidは謎ルールやバグが多く、期間が伸びたり縮んだりが頻繁に起きたりして、昔から悩まされている。(最近は大分マシになったけど・・・)
1月に2回支払いが行われるのは、運営、ユーザー共に月報や家計簿にズレがでるなど困るケースが出てくるので直してほしい。。。
- 投稿日:2019-03-24T15:57:42+09:00
DialogのYes/Noをそれぞれbooleanで返す方法を探しています・・・
現在AndroidStudioにてJavaを使いアプリ開発の勉強を行っており、
Dialogの部分で躓いております。機能としては例を挙げると下記の様に動かしたいと考えております。
A画面にて登録ボタン押下
↓
Dialog:
登録してよろしいでしょうか
はい/いいえ
↓ ↓
はい押下 いいえを押下
↓ ↓
A画面へTrueを返す 画面へFalseを押下
↓
A画面にてTrue又はFalseを受け取り以降の処理を継続調べてみたのですが調べ方が悪いのか、
booleanをreturnするようなDialogのサンプルを見つけることが出来ませんでした。皆様のお力をお借りできませんでしょうか?
以上、よろしくお願いいたします。
- 投稿日:2019-03-24T14:55:30+09:00
Android開発にてインターネットに繋がらない場合
- 投稿日:2019-03-24T00:40:24+09:00
Roomのcolumn追加方法
はじめに
覚書程度なので注意。
わかりづらいと思う。
後これがあってるかどうかもわかんない…。変更箇所
- DBのVersion管理してるところ(AppDataBase)
- DBの呼び出し箇所(Activity,Fragment)
- DBの中身書いてるところ(Interface)
AppDatabase
DBのVersionをあげる(今回の場合は1→2)
AppdataBase.kt@Database(entities = [DBのテーブル(クラス)::class], version = 2) //この部分を2へ abstract class AppDataBase : RoomDatabase() { //DAOとか書いてあるけども今回は省略 }Activity,Fragment
呼び出し部分の前に変更させるSQL文を記述
Migration.ktval MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { //カラム追加 database.execSQL("ALTER TABLE [テーブル名] ADD [追加したいカラム名] [追加するカラムの型]") } }呼び出し部分でMigrationを行う
Main.ktval dataBase = Room.databaseBuilder(activity.applicationContext, AppDataBase::class.java, "データベース名") .addMigrations(MIGRATION_1_2) //Migration .build()Interface
追加したカラムのcolumnInfoを作る
InterFace.kt@Entity class Database { @PrimaryKey(autoGenerate = true) var userId: Int = 0 //// 追加部分 @ColumnInfo(name = "追加したカラム名") var 変数名: [型]? = "" }終わりに
DBを壊さずにこれで一応カラム追加とかできる。
- 投稿日:2019-03-24T00:36:15+09:00
MacでAndroid-x86 8.1を動かしてみる
Androidを急遽触りたくなったが端末が手元に見当たらず・・・
なのでAndroid-x86使ってMax上でAndroidを動かしてみました。Android-x86は、Qemu,Parallels Desktop,VirtualBoxとかで動かせそうですが、お手軽に試せそうなVirtualBox上で動かします。
VirtualBoxインストール
https://www.virtualbox.org
から最新版ダウンロードしてきて、インストールします。ISOイメージの入手
http://www.android-x86.org/download
64bitかつ最新のandroid-x86_64-8.1-r1.isoを選びました。Android-x86の起動
VirtualBox開いて、新規ボタンを押します。
タイプはLinux,バージョンはLinux 2.6 / 3.x / 4.x.(64-bit)を選びます。
続いて、メモリーサイズは2GB以上にするのが良さそうなので念のため4GB取っておきます。Android上で動かしたいアプリによっては多めがいいと思います。
ディスプレイのアクセラレーションの3Dアクセラレーションを有効化を選択します。必要に応じてプロセッサー数を変更しておきます。
いよいよ、Androidの起動です。
先ほど入手したISOイメージを指定し、Startします。
今回は取り急ぎ試したいので、Live CDから起動させます。
お、なんか出てきました。
しばらくすると初期セットアップ画面が出てきました。
セットアップ進めて、ちゃんと動いていそうです。YouTubeもちゃんと見れました^^
所感
お手軽に試せたのでよかったです。
ただ、いくつかアプリ入れてみましたが、動かないアプリもありました・・・
マシンのリソースが足りないのかアプリの問題か不明ですが。。簡単にできるので怪しいアプリ試すのに利用したりするのがいいと思いましたw
また、今回はVirtualBoxを用いましたが、Qemuでも動かせるので暇な時やってみようと思います。おまけ
Live CD Bootでなくインストールして起動も試しましたが、再起動したらまたインストーラーが起動してしまいました。
対策としては、起動順序入れ替えるか、ISOデバイス削除したら良さそうでした。
参考












































