20190527のAndroidに関する記事は4件です。

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.gradle
    defaultConfig {
        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/4b996da

apk確認

Android Studioの Build -> Analyze APK で lib以下の*.soファイルが各アーキテクチャに過不足なく存在するか確認します。
私の場合はlibrealmreact.soの64bit版が存在していませんでした。
ちょうど数日前に64bit対応されたバージョン2.28.0がリリースされていたので使用するrealmのバージョンも上げる必要がありました。
このようにネイティブバイナリを使っているライブラリの場合はこのような問題があるので、soファイルの存在チェックはアプリを動かす前にしたほうがよさそうです。

詳しいやり方
https://developer.android.com/distribute/best-practices/develop/64-bit#look_for_native_libraries_using_apk_analyzer

動作確認

64bit対応しているデバイスで動作確認します。
アプリのインストールはabiオプションを指定して次のようにすることで、64bitライブラリのみ使用するアプリがインストールできます。

adb install --abi arm64-v8a YOUR_APK_FILE.apk

デバイスが64bit対応しているか調べる方法は こちらの記事を参照してください。

詳しいやり方
https://developer.android.com/distribute/best-practices/develop/64-bit#test_your_app_on_64-bit_hardware

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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に公開する方法

https://medium.com/flutter-community/how-to-implement-circularrevealanimation-as-flutter-library-and-publish-it-on-pub-dev-on-the-way-34e8cd21a46


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アプリのための実用的なアーキテクチャ

https://medium.com/coding-with-flutter/widget-async-bloc-service-a-practical-architecture-for-flutter-apps-250a28f9251b


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のスクロールとウィジェットアニメーションの同期

https://medium.com/flutter-community/synchronising-widget-animations-with-the-scroll-of-a-pageview-in-flutter-2f3475fcffa3


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ウィジェットパーフェクトステート管理出来ますか?

https://medium.com/flutter-community/widget-perfect-state-management-in-flutte-is-it-possible-73e76c205620


州の管理を容易かつ効果的にするためのMellati Meftahによる努力。

Flutter - バウンスボタンアニメーション

https://medium.com/flutter-community/flutter-bouncing-button-animation-ece660e19c91


アニメーションボタンの作成に関するDaniele Cambiによるチュートリアル。

Shimmerパッケージを使ったFlutter簡単なスケルトンビュー

https://medium.com/flutter-community/easy-skeleton-views-in-flutter-using-shimmer-package-acdde0288e1b


情報をロードしている間にスケルトンを表示することは最近かなり流行しています。 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)

https://www.youtube.com/watch?v=mYDFOdl-aWM&list=PLjxrf2q8roU3ahJVrSgAnPjzkpGmL9Czl&index=32&t=6s&linkId=67913821


ボーリングショーのこのエピソードでは、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ハンドブック

https://github.com/ayush221b/hack19-handbook


Hack'19の参加者を手助けするための、一連の資料がまとめられている、便利なハンドブック。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Android】Databinding × レイアウトファイル(XML)で文字列を結合しつつ表示させる

databindingを使って、更に文字列を結合してtextViewに表示したかっただけなんだ...
既知かもしれんけど、結構ハマったので忘備録。。。

はじめに書いてたレイアウトファイル

activity_sample.xml
android: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.xml
android:text='@{sampleViewModel.birthdayYear + @string/common_year
              + sampleViewModel.birthdayMonth + @string/common_month
              + sampleViewModel..birthdayDate  + @string/common_day}'

いつもお世話になってるstackoverflowからこの記事を発見。
databindingのバグじゃない?って書いてあるけどほんとかなー。

AndroidStudioの補完くん優秀だからだいたい @stringの候補出してくれるけど、
この箇所に限っては補完候補全然出てこないので不安になる。タイポ注意ネ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NativeBaseでタブ表示やリスト表示を試して雰囲気を掴む

NativeBaseとは?

ReactNative用のUIライブラリ

:computer:環境構築


yarnを使ってライブラリをインストール

$ yarn add native-base

:pencil: 実装


試しに、リスト表示+クリックした箇所をログ表示するまでをやってみます。

リスト表示

App.tsx
import { 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.tsx
import {
  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シュミレータで確認すると、以下の様な感じになりました :eyes:

アイテムをクリックするとコンソールログに出力されます :sparkles:


クリップボードに長押ししたテキストを保存する

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}」をクリップボードにコピーしました。`);
  }
}

これで長押しするとクリップボードに選択した文字列が設定されるようになりました :tada:


タブバーを下部に設置する

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>
    );
  }
}

iOSシュミレータでの実行結果
スクリーンショット 2019-05-27 8.09.19.png (511.8 kB)

表示だけは出来ました。:tada:
次はタブの切り替えや、現在表示されているタブが分かるようにしたいと思います。

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.tsxsettings.tsx を別ページとして作成し、FooterTabの Button
押された時に state でどのページを表示するか管理しています。

iOSシュミレータでの実行結果
5.png

タブ切り替えもちゃんと出来てます :tada:
6.png


Androidの場合

上のコードをAndroidで動かすと以下のようになりました。

7.png

タブバーの色等細かい所は調整が必要そうです :eyes:

:link: 参考URL


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む