- 投稿日:2019-05-27T15:25:04+09:00
React Native製 Android アプリの64bit対応
2019/8/1から64bit対応していないAndroidアプリのストアへのアップロードができなくなります。
これにあたってReact Nativeアプリの64bit対応を行ったので方法をメモしておきます。
作業前にAndroidネイティブアプリの64bit対応についてのドキュメントを読んでおくと作業がスムーズにすすむと思います。RN0.59
React Nativeのバージョンを0.59系にあげます
build.gradle
build.gradleを修正し64bitバイナリを含めるようにします
gradle|app/build.gradledefaultConfig { applicationId 'jp.co.runners.mimizuku' minSdkVersion "${rootProject.ext.minSdkVersion}" targetSdkVersion "${rootProject.ext.targetSdkVersion}" versionCode 33 versionName "2.0.7" // ↓このブロックがあったら削除 //ndk { // abiFilters "armeabi-v7a", "x86" //} } splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK //include "armeabi-v7a", "x86" // ↑これを↓こうする include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } } // applicationVariants are e.g. debug, release applicationVariants.all { variant -> variant.outputs.each { output -> def versionCodes = ["armeabi-v7a":1, "x86":2] // ↑これを↓こうする def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86_64": 4] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = versionCodes.get(abi) * 1048576 + defaultConfig.versionCode } } }参考
https://github.com/facebook/react-native/commit/4b996daapk確認
Android Studioの Build -> Analyze APK で lib以下の*.soファイルが各アーキテクチャに過不足なく存在するか確認します。
私の場合はlibrealmreact.soの64bit版が存在していませんでした。
ちょうど数日前に64bit対応されたバージョン2.28.0がリリースされていたので使用するrealmのバージョンも上げる必要がありました。
このようにネイティブバイナリを使っているライブラリの場合はこのような問題があるので、soファイルの存在チェックはアプリを動かす前にしたほうがよさそうです。動作確認
64bit対応しているデバイスで動作確認します。
アプリのインストールはabiオプションを指定して次のようにすることで、64bitライブラリのみ使用するアプリがインストールできます。adb install --abi arm64-v8a YOUR_APK_FILE.apkデバイスが64bit対応しているか調べる方法は こちらの記事を参照してください。
- 投稿日:2019-05-27T13:05:22+09:00
Flutterウィークリー #60
Flutterウィークリーとは?
FlutterファンによるFlutterファンのためのニュースレター
https://flutterweekly.net/この記事は#60の日本語訳です
https://mailchi.mp/flutterweekly/flutter-weekly-60※Google翻訳を使って自動翻訳を行っています。翻訳に問題がある箇所を発見しましたら編集リクエストを送っていただければ幸いです。
読み物&チュートリアル
PeanutであなたのFlutter / Dart Webアプリを披露する
https://medium.com/@kevmoo/show-off-your-flutter-dart-web-app-with-peanut-c0307f2b733c
Kevin Mooreが、自分のWebプロジェクトをghページに簡単に公開するために作成したCLIユーティリティ、Peanutの使い方を説明します。ペディスティックDart
https://medium.com/dartlang/pedantic-dart-1c7d365510de
David Morganが、Pedantic、Googleの内部で使用されている糸くずの構成、およびそれを構築するために行った決定について話します。CodemagicでFlutter Webアプリケーションを構築してホストする
https://blog.codemagic.io/build-and-host-your-flutter-web-apps-on-codemagic/
Codemagicの人々は、新機能、静的ページをリリースし、Codemagic CIからFlutter Webビルドをデプロイする方法を説明します。CircularRevealAnimationをFlutterライブラリとして実装し、その途中でpub.devに公開する方法
Alexander Zhdanovが、Circularの啓示を作成し、それをpub.devのライブラリとして公開する方法を説明しています。初心者のためのFlutterでFuturesを使うためのガイド
https://medium.com/flutter-community/a-guide-to-using-futures-in-flutter-for-beginners-ebeddfbfb967
あなたがそれらを初めて使うとき、Futuresは少し気が遠くなるかもしれません。 Dane Mackierによるこの記事で、あなたは短時間でプロのようにそれらを使用するでしょう。Widget-Async-Bloc-Service: Flutterアプリのための実用的なアーキテクチャ
Andrea BizzottoがBLoCアーキテクチャに新たな工夫を加え、彼が行った微調整を実用的なパターンにすることを説明します。マテリアルスタイルのセグメント化コントロール
https://medium.com/@sebbenkra/a-material-styled-segmented-control-1e92310c3a67
Sebastian KraatzはFlutterでセグメント化されたコントロールを必要としていたので、彼はそれを作り、自分でそれを行う方法を説明しました。Flutterクリッピング
https://medium.com/flutter-community/clipping-in-flutter-e9eaa6b1721a
Raouf Rahicheによるこの記事で、クリッピングの力を解き放ってください。Flutter PageViewのスクロールとウィジェットアニメーションの同期
AntonelloGalipòによる、アニメーションとPageViewスクロールとの接続方法に関するチュートリアル。Flutterテキストリーダーアニメーション
https://medium.com/aubergine-solutions/text-reader-animation-in-flutter-12f81a47ec7f
Pinkesh Darjiは、Google I / Oに表示されるアニメーションを再現して、AIがテキストを読み取る方法をシミュレートします。FlutterレスポンシブUIを構築する
https://medium.com/flutter-community/build-responsive-uis-in-flutter-fd450bd59158
モバイル、Web、デスクトップ用のFlutterアプリを作成するには、レスポンシブUIを作成する必要があります。 Raouf Rahicheがあなたに基本とFlutterからそれを処理する方法を示します。なぜFlutterようなツールが成功する必要があるのか
https://medium.com/flutter-community/why-tools-like-flutter-need-to-succeed-965a9408e8dc
Ryan Edgeによる開発作業と、なぜFlutter (およびその他のフレームワーク)が存在すべきかについての興味深い考察。実行時にテーマを変更する
https://medium.com/@bimsina/changing-theme-at-run-time-flutter-d634c307de8a
ダークモードはMaterialスペックの中の1つですので、Bibek Timsinaが実行時にアプリのテーマを変更する方法を説明します。Flutterウィジェットパーフェクトステート管理出来ますか?
州の管理を容易かつ効果的にするためのMellati Meftahによる努力。Flutter - バウンスボタンアニメーション
https://medium.com/flutter-community/flutter-bouncing-button-animation-ece660e19c91
アニメーションボタンの作成に関するDaniele Cambiによるチュートリアル。Shimmerパッケージを使ったFlutter簡単なスケルトンビュー
情報をロードしている間にスケルトンを表示することは最近かなり流行しています。 Dane MackierがFlutterそれを行う方法を説明します。ビデオ&メディア
MediaQuery(今週のFlutterウィジェット)
https://www.youtube.com/watch?v=A3WrA4zAaPw
MediaQueryを使用して、さまざまな画面サイズに基づいてアプリのUIレイアウトを調整します。Flutter UI - クリーンデザイン - レンタルサービス
https://www.youtube.com/watch?v=y_hX5AAFEB8&feature=youtu.be
もう一つのUIチャレンジ。今回は、レンタルサービスのアプリです。Flutter :LinearGradientの背景
https://www.youtube.com/watch?v=FZiw9MWLlys
LinearGradientデコレーションを使用してウィジェット内に興味深い背景を作成する方法についてのビデオ。ソース生成とあなた自身のパッケージの書き方(The Boring Flutter Development Show、Ep。23)
ボーリングショーのこのエピソードでは、FilipはSwavとDiegoの2人のゲストが参加します。 Swavを使って、カスタムウィジェットを自動的に作るためのソース生成の使い方を紹介します。 Diegoでは、彼らはDiegoのパーセントインジケーターFlutterパッケージでCustomPainter関連の機能要求に取り組んでいます。Flutter Web:GithubページにFlutter UIKitをデプロイするピーナッツチュートリアル
https://www.youtube.com/watch?v=TJDSQBm51cI&feature=youtu.be
Flutter UI Kit WebアプリケーションをGitHubページまたはgithub.ioにデプロイする方法に関するチュートリアルFlutter Web:レスポンシブポートフォリオアプリケーションを作成するパート1
https://www.youtube.com/watch?v=QAHqlsAky_4&feature=youtu.be
Flutter For Webを使用してレスポンシブポートフォリオアプリを作成する方法プロバイダと接続性を使用したFlutterネットワークセンシティブUI
https://www.youtube.com/watch?v=u9O8NOnQi_A&feature=youtu.be
接続しているネットワークの種類に基づいてUIを更新するNetworkSensitiveウィジェットの作成方法を学びましょう。フラッタルートを使用したグローバル通知
https://www.youtube.com/watch?v=FRCvqkyeCzQ
より分離されたコードのためのルートミドルウェアと通知ミドルウェアを持つredux付きの本物のアプリ。ライブラリ&コード
appspector / flutter-plugin
https://github.com/appspector/flutter-plugin
AppSpectorをあなたのFlutterプロジェクトに統合するプラグイン。
pinkeshdarji / SuperHeroInteraction:スーパーヒーローインタラクション
https://github.com/pinkeshdarji/SuperHeroInteraction
Flutter開発したスーパーヒーローインタラクション
lesnitsky / network_state
https://github.com/lesnitsky/network_state
サービスアウェアネットワーク状態プラグイン
ayush221b / wallio
https://github.com/ayush221b/wallio
Android、iOS、Web、およびデスクトップ用のJSON解析およびアニメーションを実装する単純なフラッターアプリケーション。TakeoffAndroid /フラッター・サンプル
https://github.com/TakeoffAndroid/flutter-examples
キュレーションデザインの究極のチートブック
Ethiel97 / nice_button
https://github.com/Ethiel97/nice_button
あなたのアプリに手間をかけずに素敵なボタンをデザインするためのAndroidとIOS用のFlutterパッケージ。
kalismeras61 / flutter_web_dashboard
https://github.com/kalismeras61/flutter_web_dashboard
Flutterブートストラップスタイル管理UI
MeshackMusundi /国
https://github.com/MeshackMusundi/Countries
Countries GraphQL APIを使用して国のリストを表示するFlutterアプリ
andrewackerman / bloc_lite
https://github.com/andrewackerman/bloc_lite
合理化されたBLoC実装ライブラリ
evant / streamqflite
https://github.com/evant/streamqflite
sqlbriteに触発されたsqfliteの周りのFlutter反応型ストリームラッパー
メゾニ/マーシャリング
https://github.com/mezoni/marshalling
整列化ライブラリを使用すると、オブジェクトの整列化と非整列化(シリアル化/逆シリアル化も可能)を行うことができます(たとえば、json互換型への変換)。
roughike / streaming_shared_preferences
https://github.com/roughike/streaming_shared_preferences
Flutterプロジェクト用の反応型Key-Valueストア。 shared_preferencesと似ていますが、Streamsを使用します。
ayush221b / hack19ハンドブック
- 投稿日:2019-05-27T11:32:46+09:00
【Android】Databinding × レイアウトファイル(XML)で文字列を結合しつつ表示させる
databindingを使って、更に文字列を結合してtextViewに表示したかっただけなんだ...
既知かもしれんけど、結構ハマったので忘備録。。。はじめに書いてたレイアウトファイル
activity_sample.xmlandroid:text="@{sampleViewModel.birthdayYear + '年' + sampleViewModel.birthdayMonth + '月' + sampleViewModel.birthdayDate + '日'}"めっちゃエラー出た。スタックトレースは割愛ちゃん。
「構文エラー:期待してた入力じゃないです(意訳)」って言われるe: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors. ****/ data binding error ****msg:Syntax error: extraneous input '?' expecting {'(', '+', '-', '~', '!', 'boolean', 'char', 'byte', 'short', 'int', 'long', 'float', 'double', VoidLiteral, IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, SingleQuoteString, DoubleQuoteString, 'null', Identifier, ResourceReference} file:/Android/Sample/app/src/main/res/layout/activity_sample.xml loc:158:40 - 158:187 ****\ data binding error ****正解だったレイアウトファイル
activity_sample.xmlandroid:text='@{sampleViewModel.birthdayYear + @string/common_year + sampleViewModel.birthdayMonth + @string/common_month + sampleViewModel..birthdayDate + @string/common_day}'いつもお世話になってるstackoverflowからこの記事を発見。
databindingのバグじゃない?って書いてあるけどほんとかなー。AndroidStudioの補完くん優秀だからだいたい
@string
の候補出してくれるけど、
この箇所に限っては補完候補全然出てこないので不安になる。タイポ注意ネ
- 投稿日:2019-05-27T08:33:12+09:00
NativeBaseでタブ表示やリスト表示を試して雰囲気を掴む
NativeBaseとは?
ReactNative用のUIライブラリ
環境構築
yarnを使ってライブラリをインストール
$ yarn add native-base
実装
試しに、リスト表示+クリックした箇所をログ表示するまでをやってみます。
リスト表示
App.tsximport { Platform } from "react-native"; import { createAppContainer, createStackNavigator, NavigationContainer } from "react-navigation"; import Home from "./screens/home"; const headerNavigationOptions = { headerStyle: { backgroundColor: "gray", marginTop: Platform.OS === "android" ? 24 : 0 }, headerTitleStyle: { color: "white" }, headerTintColor: "white" }; const AppNavigator: NavigationContainer = createStackNavigator({ Home: { screen: Home, navigationOptions: { ...headerNavigationOptions, headerTitle: "サンプル" } } }); export default createAppContainer(AppNavigator);Home.tsximport { Container, Content, List, ListItem, Text, Body, Right, Icon } from "native-base"; import React from "react"; // tslint:disable-next-line: no-empty-interface interface IProps {} export default class Home extends React.Component<IProps> { public render() { // 表示するデータ const items: string[] = ["itemA", "itemB", "itemC"]; return ( <Container> <Content> <List dataArray={items} renderRow={item => ( <ListItem button={true} onPress={() => console.log(`onPress ${item}`)} > <Body> <Text>{item}</Text> </Body> <Right> <Icon name="arrow-forward" /> </Right> </ListItem> )} /> </Content> </Container> ); } }実行してiPhoneシュミレータで確認すると、以下の様な感じになりました
アイテムをクリックするとコンソールログに出力されます
クリップボードに長押ししたテキストを保存する
clipboard操作に関しては以下のモジュールを使用します。
ライブラリをインストール
$ yarn add @react-native-community/react-native-clipboard
clips.tsx... <Container> <Content> <List dataArray={items} renderRow={item => ( <ListItem button={true} onPress={() => console.log(`onPress ${item}`)} onLongPress={() => this.onLongClick(item)} > ... )} /> </Content> </Container> ... private onLongClick(item: string) { Clipboard.setString(item); Alert.alert("information", `「${item}」をクリップボードにコピーしました。`); } }これで長押しするとクリップボードに選択した文字列が設定されるようになりました
タブバーを下部に設置する
Footer Tabsを使用する
- まずはサンプル通りに実装
export default class Home extends React.Component<IProps> { public render() { return ( <Container> <Content /> <Footer> <FooterTab> <Button vertical={true}> <Icon name="clipboard" /> <Text>タブ1</Text> </Button> <Button vertical={true}> <Icon name="settings" /> <Text>タブ2</Text> </Button> </FooterTab> </Footer> </Container> ); } }表示だけは出来ました。
次はタブの切り替えや、現在表示されているタブが分かるようにしたいと思います。import { Body, Button, Container, Content, Footer, FooterTab, Icon, Text } from "native-base"; import React from "react"; import Tab1 from "./clips"; import Tab2 from "./settings"; interface IState { selectedTab: string; } // tslint:disable-next-line: no-empty-interface interface IProps {} export default class Home extends React.Component<IProps, IState> { constructor(props: IProps) { super(props); this.state = { selectedTab: "clips" }; } public renderSelectedTab() { switch (this.state.selectedTab) { case "clips": return <Tab1 />; case "settings": return <Tab2 />; default: } } public render() { return ( <Container> <Content>{this.renderSelectedTab()}</Content> <Footer> <FooterTab> <Button vertical={true} active={this.state.selectedTab === "clips"} onPress={() => this.setState({ selectedTab: "clips" })} > <Icon name="clipboard" /> <Text>タブ1</Text> </Button> <Button vertical={true} active={this.state.selectedTab === "settings"} onPress={() => this.setState({ selectedTab: "settings" })} > <Icon name="settings" /> <Text>タブ2</Text> </Button> </FooterTab> </Footer> </Container> ); } }
clips.tsx
とsettings.tsx
を別ページとして作成し、FooterTabのButton
が
押された時に state でどのページを表示するか管理しています。
Androidの場合
上のコードをAndroidで動かすと以下のようになりました。
タブバーの色等細かい所は調整が必要そうです
参考URL