NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。
今回はコミュニティSDKの一つ、Flutter SDKとDeepL APIを使って翻訳アプリを作ってみます。前回は画面の仕様とSDKの初期化について解説しましたので、今回は翻訳画面と翻訳処理について解説します。
完成版のコード
作成したデモアプリのコードはNCMBMania/flutter_translation_app: Flutter SDKとDeepL APIを組み合わせた翻訳アプリですにアップロードしてあります。
メイン画面について
メイン画面(MyApp)ではFlutterアプリの初期化を行っているだけです。
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Translation App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: MainPage(),
);
}
}
MainPageウィジェットについて
MainPageはタブを用意して、翻訳画面と履歴画面をそれぞれ読み込んでいます。
// タブ表示用
class MainPage extends StatelessWidget {
MainPage({Key? key}) : super(key: key);
final _tabs = [
const Tab(icon: Icon(Icons.translate)), // 翻訳画面
const Tab(icon: Icon(Icons.list)), // 履歴画面
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: _tabs.length,
child: Scaffold(
appBar: AppBar(
title: const Text('翻訳アプリ'),
bottom: TabBar(
tabs: _tabs.toList(),
),
),
body: const TabBarView(
children: [
TranslationPage(),
HistoryPage(),
],
),
),
),
);
}
}
TranslationPageについて
TranslationPageは_TranslationPageStateを読み込んでいるだけです。
class TranslationPage extends StatefulWidget {
const TranslationPage({Key? key}) : super(key: key);
@override
State<TranslationPage> createState() => _TranslationPageState();
}
_TranslationPageStateについて
_TranslationPageStateの役割は以下の3つです。
- 翻訳画面の構築
- 入力テキストの翻訳とNCMBへの保存
- 入力テキストの削除
- 翻訳結果のクリップボードへのコピー
// 翻訳画面
class _TranslationPageState extends State<TranslationPage> {
}
インスタンス変数
用意しているインスタンス変数は次の通りです。
// テキスト編集用コントローラー
final _controller = TextEditingController();
// 翻訳結果が入る変数
var _translateText = "";
// DeepL用ライブラリ
final _translator = Translator(authKey: dotenv.env['DEEPL_AUTH_KEY']!);
画面構築
ColumnとRowを組み合わせているだけなので難しいものではありません。翻訳するボタンをタップした際のイベント _translate
と 翻訳結果をクリップボードにコピーする _copyText
、入力テキストを削除する _clearText
を呼び出しています。
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'翻訳する言葉を入力してください',
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 260,
child: TextFormField(
onFieldSubmitted: (str) {
_translate();
},
controller: _controller,
decoration: const InputDecoration(
hintText: "日本語…",
),
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
TextButton(onPressed: _translate, child: const Text("翻訳する"))
],
),
Padding(
padding: const EdgeInsets.all(10),
child: Container(color: Colors.white),
),
_translateText != ""
? Column(
children: [
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
const Text("翻訳結果"),
TextButton(
onPressed: _copyText, child: const Icon(Icons.copy)),
TextButton(
onPressed: _clearText, child: const Icon(Icons.clear))
]),
Text(_translateText),
],
)
: const Text("翻訳結果がこの下に表示されます")
],
),
);
}
翻訳処理を行う _translate 関数について
翻訳処理は translator.translateTextSingular
だけで完結します。2つ目の引数は翻訳後の言語です。翻訳が完了したら、元の日本語とともにニフクラ mobile backendのデータストア(クラウドデータベース)に保存します。その際にはNCMBObjectを利用します。saveメソッドはasync/awaitですが、処理を特に待つ必要はないのでawaitを使っていません。
// 翻訳処理
void _translate() async {
// 入力されたテキスト(日本語)
var originalText = _controller.text;
// DeepLの翻訳処理
final result =
await _translator.translateTextSingular(originalText, 'en-US');
// 結果を入れるデータストアのオブジェクト
final translate = NCMBObject("Translate");
// オブジェクトに必要なデータをセット
translate
..set("original", originalText)
..set("translate", result.text);
// 保存
translate.save();
// 画面に翻訳結果を反映
setState(() {
_translateText = result.text;
});
}
クリップボードへコピーする _copyText 関数について
クリップボードを操作する際には flutter/services
が必要です。
import 'package:flutter/services.dart';
そして、以下のようにClipboardクラスにデータを送信します。
// 翻訳結果をクリップボードにコピー
void _copyText() {
Clipboard.setData(ClipboardData(text: _translateText));
}
入力値をクリアする_clearText関数について
こちらはテキストを削除するだけです。
// 入力、翻訳結果を消す処理
void _clearText() {
_controller.text = "";
setState(() {
_translateText = "";
});
}
まとめ
今回は翻訳画面の作成と翻訳処理、そしてクリップボードへのコピー処理までを解説しました。次回は翻訳結果の履歴取得と表示までを解説します。