クリップボードへのコピーを簡単化するAndroidアプリ再改訂
前回作ったアプリは、各行の左にあるCボタンを押さないと、書き換えた内容が保存されませんでした。書換えたものが自動的に保存されないのは、ユーザインターフェースとして良くないと感じたので、下記のように仕様を変更しました。
使用方法(README.mdより抜粋)
- 実装上の事情により、ClipboardMgrと使い方が異なります。
- 最上端のclipboard行のみ入力可能です。(初期値はアプリ起動時のクリップボードの内容)
- clipboard行に入力中の内容は、逐次、クリップボードに反映されます。
- 各行で左のPボタンを押すと、clipboardの内容が、行内のテキスト欄にPasteされます。
- clipboard行が空の状態でPボタンを押すと、行内のテキスト欄が空になります。
- 各行で左のCボタンを押すと、行内のテキスト欄の内容が、clipboard行およびクリップボードにCopyされます。
- テキスト欄が空の行でCボタンを押すと、clipboard行およびクリップボードがが空になります。
- 各行のテキストは、アプリ終了後も保管され、再起動時に表示されます。
クリップボードへのコピーを簡単化するAndroidアプリ改訂
前回の記事「Android StudioでClipboardMgrを作成しました - Itsukaraの日記」で、クリップボードへのコピーを簡単化するアプリを作成しましたが、今回、ListViewを使って改訂しました。改訂版は、機能が少し異なるため、別の名前(ClipboardManager)としました。
ListViewにより画面に表示される件数を実行時に決めることができるため、件数を40件に増やしました。ただ、残念ながら、画面上のテキスト部分に入力した文字列を保管対象とするために、ひと手間余計に掛ります。具体的には、テキストを入力後に、C(Copy)ボタンを押す必要があります。なお、P(Paste)ボタンを押して表示された文字列は、C(Copy)ボタンを押す必要がありません。
どうやら、ListViewの中にEditTextを含める場合は、色々と問題があるようです。色々と調べたところ、解決策は「Creating ListView with EditText and TextWatcher in Android」に書かれてはいるのですが、ListViewを使わず、ListView的なことを自前で実装してます。なんか、方向が違う気がしたので、取り込みませんでした。EditTextも簡単に組み合わせできる機能をGoogleから提供してほしいものです。
Android StudioでClipboardMgrを作成しました
Android Studio版電卓アプリを更に少し修正
Android Studio版電卓アプリを少し使っていて不便と感じた点を改善しました。
- ボタンと文字を大きくしました。
- 計算結果をクリップボードにコピーする機能を追加しました。
- 他のアプリで計算結果をペーストすることができます。
- 画面が回転しても計算結果を維持する機能を追加しました。
- Androidでは、画面回転の度にアクティビティ(画面表示を処理するクラス)がDestroy、再Createさます。そこで、Destroy前にアクティビティの状態を一度退避し、Create後に再設定するようにしました。
- ビルドが非常に遅いので、gradle.propertiesを修正しました。
- gradleに割り当てるメモリ量を増やし、並列にビルドするようにしました。
また、ソースコード掲載場所は下記です。
Android Studio版電卓アプリを少し修正
下記記事に書いたAndroid Studio版電卓アプリの件、コードを少し簡潔にしました。具体的には、電卓の各ボタン毎にEventListenerを設定する処理をもっと簡潔にしました。ご参考まで。
ちなみに、元々は、ボタン毎の処理(特に+,-,*,/,%)で同じような部分があるので、Effective Java にのっている エレガントな Enum の使い方メモ | Futurismoを参考に、演算子ごとの処理をEnum活用で纏めようかと思ったのですが、もっと長くて冗長な部分(今回修正部分)があったので、簡潔化したものです。
Enumを使った修正は、あまりコードが短くならなそうなので、止めました。それにしても、JavaのEnumは、結構いろいろな使い方があるものですね。別の機会に活用したいと思います。
Javaのシングルトンの使い方を例題で確認しました
Javaのシングルトンについて知りたかったのでJavaでSingletonパターンを実装するのにclassとenumのどちらを使うべきか - SELECT * FROM life;を読ませて頂きました。しかし、シングルトンの定義しか書いていないため、使い方が今一つ分かりませんでした。そこで、例題を作って確かめてみました。下記で、シングルトンの使い方を2つ書きましたが、2つ目は、enum型の要素に対して直接メソッドを呼び出すので、かなり不自然に感じました。(実際は1つめも同じではありますが...)
import java.util.Arrays; import java.util.List; // 下記はテスト用の補助的なクラスです class StringList { List<String> stringList; public StringList(String... strings) { stringList = Arrays.asList(strings); // stringList = new LinkedList<>(); // for (String string: strings) { // stringList.add(string); // } } public List<String> getStringList() { return stringList; } } // シングルトンクラスです enum RichestPerson { INSTANCE; private String name = "Bill Gates"; // フィールドの初期時値は実行時に設定することも可能 private StringList favoriteFruits = new StringList("Orange", "Strawberry", "'Every fruits except Apple'"); private StringList favoriteDrinks = new StringList("Coke", "Coffee", "Wine"); public String getName() { return name; } public List<String> getFavoriteFruits() { return favoriteFruits.getStringList(); } public List<String> getFavoriteDrinks() { return favoriteDrinks.getStringList(); } public void changePerson(String name, StringList favoriteFruits, StringList favoriteDrinks) { this.name = name; this.favoriteFruits = favoriteFruits; this.favoriteDrinks = favoriteDrinks; } } /* error: enum types are not extensible class test extends RichestPerson { } */ // テスト実施クラス public class SingletonTest { public static void main(String[] args) { SingletonTest singletonTest = new SingletonTest(); singletonTest.test(); } public void test() { /* error: enum types may not be instantiated RichestPerson theOne = new RichestPerson(); */ /* error: non-static method getName() cannot be referenced from a static context String theName = RichestPerson.getName(); */ // 下記は、自然な使い方 RichestPerson theOne = RichestPerson.INSTANCE; // 下記も、これだけ見ると、あまり不自然に見えない System.out.print("Favorite Fruits of "+theOne.getName()+":"); List<String> favoriteFruitsOfRichestPerson = theOne.getFavoriteFruits(); for (String fruit: favoriteFruitsOfRichestPerson) { System.out.print(" "+fruit); } System.out.println(""); // 下記はenum型の要素に対してメソッドを呼び出すので、なんか不自然な感じ System.out.print("Favorite Fruits of "+RichestPerson.INSTANCE.getName()+":"); List<String> favoriteDrinksOfRichestPerson = RichestPerson.INSTANCE.getFavoriteDrinks(); for (String drink: favoriteDrinksOfRichestPerson) { System.out.print(" "+drink); } System.out.println(""); } } /* 実行結果: Favorite Fruits of Bill Gates: Orange Strawberry 'Every fruits except Apple' Favorite Fruits of Bill Gates: Coke Coffee Wine */
Android Studioで作った電卓アプリをCloud9でJavascript化
Android Studioで電卓アプリを作った際に色々と苦労した点を直前の記事に書きました。また、「この程度の処理ならばJavascriptで十分だし、Androidに限らずに使えるので、その方が良いのでは?」思ったことも書きました。そこで、さっそく電卓アプリをJavascrip化してみました。
Javascriptへの移植は、クラウドで開発環境が使えるCloud9を使いました。昨日から試しに使ってますが、開発環境を用意しなくても色々なプログラミング言語を簡単に試せるので、とても便利ですね。HTML以外に、Ruby on Rails、Node.js、PHP/Apache、Python、C++、Wordpressなどのテンプレートが用意されています。また、Linuxのコマンドが使えますので、後からいろいろ追加できると思います。ただ、Javaのテンプレートがないのが残念。...と思っていたら、「CS50 Harvard University」というテンプレートを使うと、Javaも使えました。
Javascriptと違って、JavaはスマホやMedia Padでは簡単に試せないですが、Cloud9があれば、簡単に試せます。Dokojavaというサイトもあるようですが、私のスマホでは動かず、残念に思っていたところでした。Javaのコードをちょっと試す環境としても、Cloud9はとても便利です。すみません、話がそれました。
Cloud9は、開発した成果を簡単に外部に公開できる点もうれしいです。電卓アプリのJavascript移植版を下記に公開していますので、よろしかったらアクセスしてみてください。