FC2ブログ

スマフォのアプリを作りたい(21):メニュー作成の一例

   プログラミング [2020/04/08]
チャットと音声認識を組み合わせたくて、React Nativeでチャット(react-native-gifted-chat)と音声認識(react-native-google-speech-api)を試しました。
そろそろ組み合わせたものを作ろうかとも思ったのですが、その前に録音した音声を再生するところをやって見ようと思います。
さらにその前に、現状のApp.jsをちょっと変更したくなりました。

というのも、現状のソースは、
App.jsの下にChat.js(チャット制御)とSpeech.js(Google Speech to Text音声認識と録音制御)の2つのコンポーネントがぶら下がっている構成です。

----JSX:App.js-------------------------------------
:
import React, { Component } from 'react';
//import { SafeAreaView, View, Text, } from 'react-native';
import { Router, Scene, } from 'react-native-router-flux';

import Chat from './Chat';
import Speech from './Speech';

export default class App extends Component<{}> {
render() {
return (
<Router>
<Scene key='root'>
<Scene key='Text' component={Speech} title="Speech:Google音声認識" />
<Scene key='Chat' component={Chat} title="VTChat:チャットサンプル" />
</Scene>
</Router>
);
}
}
---------------------------------------------------

App.js内でreact-native-router-fluxを使って<Router><Scene key=’root><Scene ・・・/><Scene ・・・/></Scene>と2つ並べています。
2つの<Scene ・・・/>の切り替え方を知らないので、今のところ1番目の<Scene ・・・/>が動作を開始した後、切り替えは多分できないようになってます。

せっかくなので、音声認識(&録音)、新規:音声再生、チャットをそれぞれ切り替え可能にしたいと、ちょっと調べました。


◆<Tabs>を使って複数の機能をメニュー化する

「react-native-router-flux 切り替え」でぐぐって見ると、以下のサイトが引っ掛かりました。
参考:https://rara-world.com/react-native-tab-routing/
サンプルが載ってます。
しばらく、React Native JSXのコードから遠ざかっていたので、なんかサンプルコードに違和感が・・・

ともかく、react-native-router-fluxの<Tabs>というコンポーネントがあって、それを使って並べるようです。
結果の絵でもあれば、ちょっとイメージできていいんだろうけど、載ってません。

やってみた方が早いですね。

では、まずはコードです。
こんな風にしました。
----JSX:App.js-------------------------------------
/**
* Sample React Native App => Chat Sample
* https://github.com/facebook/react-native
*
* @format
* @flow
*/

import React, { Component } from 'react';
import { SafeAreaView, View, Text, StyleSheet } from 'react-native';
import { Router, Scene, Tabs } from 'react-native-router-flux';
import Icon from 'react-native-vector-icons/MaterialIcons';

import Chat from './Chat';
import Speech from './Speech';

const TabBarIcon = (props) => {
return (
<View style={styles.tabIconContainerStyle}>
<Icon
name={props.iconName}
color={props.focused ? 'blue' : 'grey'}
style={styles.tabIconStyle}
/>
</View>
);
}


export default class App extends Component<{}> {
render() {
return (
<Router>
<Tabs key='root' swipeEnabled={true} animationEnabled={true}>
<Scene key='Text'
component={Speech}
title="Speech:音声認識&録音"
iconName='mic'
iconColor='red'
icon={TabBarIcon}
initial
/>
<Scene key='Chat'
component={Chat}
title="Chat:チャット"
iconName='chat'
iconColor='red'
icon={TabBarIcon}
/>
</Tabs>

</Router>
);
}
}

const styles = StyleSheet.create({
tabIconContainerStyle: {
justifyContent: 'center',
alignems: 'center',
},
tabIconStyle: {
width: 24,
height: 24,
fontSize: 24,
},
});

---------------------------------------------------

どんなiconを使うのかは、「iconName」パラメタで指定しているようです。

「import Icon from 'react-native-vector-icons/MaterialIcons';」というのも初めて見るの書き方。
参考:https://qiita.com/kana-t/items/3cad4fae393b6a5fc8a0

react-native-vendor-iconsをインストールした後で分かったのですが、
react-native-vector-iconsに含まれる、アイコンのセット(.json)をimportしていることになるみたいです。

「(プロジェクトフォルダ)\node-modules\react-native-vector-icons\dist\glyphmaps」の下にMaterialIcons.jsonがあって、
中身を見ると、アイコン名らしき名前と番号がダーっと書かれてました。
その中から、「mic」と「chat」を選びました。

react-native-vendor-iconsのインストールは、いつもの通り、プロジェクトフォルダをカレントにして
npm install react-native-vector-icons --save
を実行しましす。

それで、「react-native run-android」を実行します。
すると、以下のような画面が出ました。
20200407_1.jpg

画面下部分に表示されているのがTabバーで、2つのメニューが表示されています。
起動時は、「音声認識&録音」側の機能が有効です。
各メニューをタップするとそれぞれの画面への切り替えが可能です。

ただし、アイコンは□に×のマークで、うまくアイコンが取り込めてないようです。

「rnpm link ・・・」もやれと書いてあるサイトがあった。
(↑注:iOS対応の場合であってrnpmです。npmではない。)
でも、「npm link ・・・」とやって、その後正常だったことは一度もない。
ちょっと躊躇してたのですが、やってみました。
(↓注:やってはいけません。)
npm link react-native-vector-icons

で結果は・・・


やっぱりヘンテコなエラーが出まくりました。

これまでも、「react-native run-android」は、2回に1回くらいの割合で失敗してました。
主なエラーは、以下の内容の場合が多いです。
----コマンドプロンプト-----------------------------

Execution failed for task ':app:・・・'.
> Could not read path '・・・・・

---------------------------------------------------

リトライでうまくいく場合がほとんどで、それでもダメなときは、エラー原因とされているフォルダを手動で作成したり、「gradlew cleanBuildCache」をやったりしてる間に成功してました。

ただし、今回の「npm link ・・・」後は、さらに失敗が続きます。
こんな画面が出ます。
20200407_2.jpg

このとき、「選択node ・・・」のコマンドプロンプトには。
----コマンドプロンプト(選択node)------------------

error: bundling failed: Error: Unable to resolve module `react-native-vector-icons/MaterialIcons` from `App.js`: react-native-vector-icons/MaterialIcons could not be found within the project.

If you are sure the module exists, try these steps:
1. Clear watchman watches: watchman watch-del-all
2. Delete node_modules: rm -rf node_modules and run yarn install
3. Reset Metro's cache: yarn start --reset-cache
4. Remove the cache: rm -rf /tmp/metro-*
at ModuleResolver.resolveDependency (D:\AppMake\proj\VTChat\node_modules\metro\src\node-haste\DependencyGraph\ModuleResolution.js:186:15)
at ResolutionRequest.resolveDependency (D:\AppMake\proj\VTChat\node_modules\metro\src\node-haste\DependencyGraph\ResolutionRequest.js:52:18)
at DependencyGraph.resolveDependency (D:\AppMake\proj\VTChat\node_modules\metro\src\node-haste\DependencyGraph.js:282:16)

---------------------------------------------------

なんなんですかね。
「watchman watch-del-all」だの「rm -rf /tmp/metro-*」だの「yarn start --reset-cache」だのって、これまで一切やったことのないものばかり。
前も、意味も分からず変なコマンドを実行させて、環境そのものを動作不能にした経験があるため、こんな口車には乗りたくありません。

遅きに失しますが、『「npm link」とは何ぞや』をぐぐってみました。
参考:https://www.yoheim.net/blog.php?q=20171202
出来上がってないパッケージを使うときに必要と読める。
エクスプローラーでプロジェクト内のnode-modules\react-ative-vector-iconsを見ると、ショートカットフォルダのアイコンになってる!?
実体はどこにあるんだろう。
上記の参考サイトでは、npmリンクを辞めたいときは「npm install」しちゃえとあります。
再度「npm install react-native-vector-icons --save」しました。

「react-native run-android」は、「> Could not read path '・・・・・」が出て3回失敗しましたが、
4回目で現状復帰ができました!!
※結局、iOSでやるべきコマンドを「npm link ・・・」と勘違いして実施した、さるの2重の読みまつがいだったのをこの後に気付きました。


再度、アイコンがチャント出ない事例を検索しました。
参考:https://uedive.net/2019/142/rn-fa-android/
参考:https://dev-yakuza.github.io/react-native/react-native-vector-icons/

1)以下を「(プロジェクトファイル)\app\build.gradle」のお尻に追加します。
----app/build.gradle-------------------------------
//apply from: "../../node_modules/react-native/react.gradle"
//project.ext.vectoricons = [
// iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf', 'FontAwesome.ttf' ] // Name of the font files you want to copy
//]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" // add this line
---------------------------------------------------

1行目のコメントアウトした行は、生かしてあった場合、以下のエラーになりました。
使っている環境によるかと思います。
----コマンドプロンプト(react-native run-android)---

* Where:
Script 'D:\AppMake\proj\VTChat\node_modules\react-native\react.gradle' line: 104

* What went wrong:
A problem occurred configuring project ':app'.
> Cannot add task 'bundleDebugJsAndAssets' as a task with that name already exists.

---------------------------------------------------

2~4行目は、以下2)をやった後だったので、要らないかな~と思ってコメントアウトした。
根拠はありません。

2)node-modules\react-native-vector-icons\Fonts」をコピーします。
貼り付け先は「android\app\src\main\assets」です。
念のため、フォルダ名の「Fonts」は「fonts」に変更しました。


アイコン出ました~\(^o^)/
20200407_3.jpg


メニューの切り替えもOKです。
双方動かしてみました。
<音声認識>
20200407_4.jpg


<チャット>
20200407_5.jpg


ちなみに、チャットを入力しようとするとソフトキーボードが表示されます。
そうするとTabバーが隠れちゃいます。
ソフトキーボードの引っ込め方が分からなくて、四苦八苦しました。
〇に→キーで引っ込みました。正式な操作なのかは不明です・・・・。
20200407_6.jpg



ちょっとのつもりで初めて、本題じゃないところで思わぬ時間が掛かってしましました。
React Nativeはマジ難儀な環境です。


次回からは、メニューを1個増やして、録音した音声の再生をやってみます。

では、この辺で。ご機嫌よう。
m(__)m


スポンサーサイト





コメントの投稿

非公開コメント

カレンダー
01 | 2024/02 | 03
- - - - 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 - -
プロフィール

さるもすなる

Author:さるもすなる
さるです。別HPサイト「さるもすなる」から侵食してきました。 山菜/きのこ、それとタイトルにしたPPバンド籠のことをメインに徒然に・・・・暇を持て余したさるの手仕事:男手芸のブログってことで。

最新記事
最新コメント
月別アーカイブ
カテゴリ
天気予報

-天気予報コム- -FC2-
本家のHPのトップ
山菜や茸の話です
PPバンドの籠作品と作り方です
投稿をお待ちしております



PVアクセスランキング にほんブログ村 にほんブログ村 ハンドメイドブログへ



マニュアルのお申し込み



検索フォーム
リンク
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR