Canvas だけでもアプリはできる!
ノート PC に、Visual Studio Community 2022 の C++ によるモバイル開発機能のインストールと、 その時点で最新だった Android Studio のインストールを完了しましたので、 Android アプリの開発環境が整ったということになりました。
アプリ開発にとりかかる前に、 「Android Studio で新規プロジェクトを作成する」 などで、作成可能ないくつかのプロジェクト、 すべての基本となる Empty Activity、 全画面を使用できる Fullscreen Activity、 JNI で C++ 関数を呼び出せる Native C++、 そして AdMob インタースティシャル広告を表示できる Google AdMob Ads Activity とコードを確認、動作を試しましたので、いよいよこれから本番です。
過去すでに Android Studio を別のマシンで使用して 「素因数分解トレーニングアプリ」 を開発していますが、改めてちゃんとアプリを作りたいな、と思い、リスタートしています。
なお、使用している Android Studio は、2022 年 5 月中旬にインストールした、2021.2.1 Patch 1 の Chipmunk です。
ここでは Empty Activity でアプリ独自のビューを作成し、 描画関数 onDraw が引数で受け取る Canvas に自由にテキストを描画するまでのコードについて書いています。
なお、本サイトの
ご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。
投稿 June 23, 2022
このシリーズで最終的に作りたいアプリは、 画面に表示された、100 までの 4 つの数字のうち、素数を選んですばやくタップ! というものをイメージしています。
では、Android Studio を起動して、Empty Activity を作成しましょう。 詳細な手順は「Android Studio で新規プロジェクトを作成する」に書いています。
アプリ名を記入する Name の欄には、 「FlashSosuu」と入力しました。 日本語のアプリのタイトルはあとで定義できますから、英文字で適切な名前がいいと思います。 全角文字を入力するとどうなるのかは、試していません。 半角スペースは入っても問題なさそうですが、必要がなければ入れないほうがいいのかも知れません。
Package name はパッケージ名で、 世界で唯一の名前(文字列)にならなくてはなりませんので、通常は自分のドメイン名にアプリ名を加えたものにします。 テスト目的だけであれば com.example のままでよく、 書き換える場合は既存のアプリとの重複を避け、他人の権利を侵害しないよう、責任ある独自の文字列にする必要があります。
プロジェクトの作成には毎回それなりの時間がかかるようです。 準備が完了し、コードの MainActivity.java が開かれたら、コーディングの開始です。
MainActivity クラスの定義だけが記入されています。
唯一定義されている onCreate 関数は、アクティビティが作成されたときに呼び出され、 アプリの作成処理が実行されます。
そこに書かれている setContentView の呼び出しで、xml で定義された activity_main ビューを設定していますので、 この行をコメントアウトして、書き換えます。
new で新しく作成した、 FlashSosuuView という名前のクラスを設定しました。 FlashSosuuView クラスはまだどこにも定義されていませんので、赤色表示になっています。 これで独自の View を使用するように設定できました。
FlashSosuuView クラスは View を定義するコードですので、Java のコードとなります。 Java のコードは、画面の左側、app の階層の下、 java にあるパッケージ名の中に置くようです。 すでに MainActivity があるところです。
ちなみにエクスプローラーでアプリのフォルダを開いたときには、 src / main / java / com / straightapps / FlashSosuu といったように、 パッケージ名を分解したフォルダに Java のコードが置かれることになっているようです。
では、新しいクラス FlashSosuuView を追加します。 もちろん何という名前でも問題ありません。 わかりやすい名前がベストですから、末尾は View がいいと思います。
画面左側、MainActivity があるフォルダ、 この場合は com.straightapps.flashsosuu をクリックして選択し、それを右クリックしてメニューを表示させます。
ポップアップされたメニューの先頭にある New をポイントし、 さらに表示されたメニューで Java Class をクリックします。
New Java Class という名前のダイアログが表示されました。
Class が選択されていることを確認し、タイトルのすぐ下、 Name と書かれている部分に作成したいクラス名、 この場合は先ほど setContentView 関数に渡すことにした、FlashSosuuView と入力して、Enter キーを押します。
新しく FlashSosuuView.java のようなファイルが作成され、開かれた状態になります。
この定義だと、単に View という名前が付いただけの新しいクラスですから、 setContentView 関数に渡すことができる View クラスではありません。 まずは何より、View の派生クラスとするため、クラスの定義に extends View を追加して、 View 派生クラスにします。
View は Java で定義されたクラスですが、
適切な
赤文字になっている View にマウスポインタを乗せる(以降「ポイントする」と書いたりもします)と、ヒントが表示されます。 そこで Import class をクリックすれば、import 文を自動入力してくれます。
必要な import 文が挿入されましたが、同時に行全体に赤い波線が引かれました。
赤い波線のある行をポイントすると、理由がわかります。
書かれている通り、継承している android.view.View クラスにはコンストラクタがない、ということです。 このクラス用のコンストラクタを書かなくてはいけませんが、問題ありません。 その下にある「Create constructor matching super」をクリックすれば、自動的に作成・追加してもらえます。
どの引数を取るものがいいかを聞かれていますので、一番上、引数が Context だけのもので OK です。 選択して OK ボタンをクリックです。 左下にある Copy JavaDoc にチェックを入れると、細かいコメントが付与されるのだと思いますが、チェックしません。
ひとまずこれで独自のビューが設定され、コーディングの準備完了です。
投稿 June 23, 2022
ここまでで、独自のビューがアプリに設定され、エラーはなくなりましたが、 独自のビューにはコンストラクタしか実装されていませんので、何も表示されませんし、何もできません。
今追加してもらったコンストラクタの内容はいったんおいておいて、先に最低限必要な関数を実装しましょう。
まずは、アプリのウィンドウが生成され、フォーカスを得たときに呼びされる onWindowFocusChanged 関数を実装します。
クラスに新しい関数を追加するには、作成した View クラスの定義の何もない部分を右クリックして、メニューを表示します。
表示されたメニューの真ん中より少し下にある、Generate... をクリックします。
表示された Generate と書かれたポップアップで、Override Methods... をクリックします。 これは、継承した View クラスにある関数を上書きするための関数を作成する、という意味になります。
今度は Select Methods to Override/Implement と書かれたポップアップが表示されます。
関数名がたくさん並んだリストから、onWindowFocusChanged を見つけて選択します。
画面左上の、a と z が書かれた下向き矢印、 マウスポインタを乗せると Sort Alphabetically と表示される、「アルファベット順」にしておくと、少しは選びやすいと思います。 この場合、クラス別にアルファベット順になります。 一番上にある android.view.View クラスの中に onWindowFocusChanged 関数はありますので、 その枠内でアルファベット順で探します。
OK ボタンを押すと、関数が自動的に挿入されます。
同じ手順で、描画のための関数 onDraw をオーバーライドします。
もう 1 つ、同じ手順で、タッチイベント処理のための関数 onTouchEvent もオーバーライドします。
とりあえず必要なオーバーライドは、これだけです。
次は、画面にテキストを描画するためのコードを追加します。
投稿 June 23, 2022
クラスの定義とコンストラクタの定義の間には、クラス内のグローバル変数などを記述できます。
ここでは画面サイズを記録するための
Paint クラスが未定義で赤文字になっていますので、 赤で表示されている Paint の文字をポイントし、 ヒントが表示されたら、View のときと同じように Import class をクリックし、 import 文を自動挿入してもらって解決します。
コンストラクタでは、今回は画面に文字を描きたいので、テキスト描画のための基本設定を行っておきます。
コードの内容については各行に書いたコメントの通りですが、簡単に言えば、 新しい Paint クラスを作成して変数 paint に保存し、 テキストの色や描画スタイルを設定しています。
ウィンドウが作成されたときに呼び出される onWindowFocusChanged 関数では、描画可能領域を取得しておきます。
this は自分自身を表すクラスで、 getWidth 関数と getHeight 関数で、 利用可能な領域の幅と高さを、ピクセル単位で取得できます。
描画を行う onDraw 関数は、 引数で Canvas を受け取っていますので、 JavaScript と同じように、自由に書き込みが行えます。
とりあえずは適当な描画コードを書き込みます。
最初の drawColor 関数は、背景の塗りつぶしです。 引数で指定しているのは背景色で、Color クラスの argb 関数に、 透明度、赤、緑、青の順で 0 〜 255 の値を指定して、色を作成しています。 透明度 255 は不透明、あとは 222 を指定していますので、明るめのグレーです。
Color クラスが未定義で赤文字になっていますので、 マウスポインタを乗せてヒントが表示されたら、View のときと同じように Import class をクリックし、 import 文を自動挿入してもらって解決します。
setStyle 関数で文字のラインのスタイルを設定、 setColor 関数で文字色を黒の不透明に設定、 setStroleWidth 関数で文字のラインの太さを設定、 setTextSize 関数で文字の大きさを、画面の横サイズの 10 分の 1に設定しました。 実際には文字が等幅ではありませんので、おそらく指定しているのは文字の高さであり、10 文字で画面ぴったりではありません。
そしていよいよ drawText 関数を呼び出して、 画面左端 0 から、文字の下のラインが高さの半分の位置 cyView / 2 に、 「テキスト描画!」と描画します。
最後にタッチイベント処理 onTouchEvent 関数ですが、 これを扱いはじめると大変になりますので、今は switch 文だけ入れておいて、何もしないでおきます。
意味としては、引数で受け取ったイベント情報 event を参照し、 getAction 関数で、どのような動作が行われたかを判断します。 MotionEvent.ACTION_DOWN は、画面にタッチされた、という意味です。 マウスや Windows でいうところの WM_LBUTTONDOWN です。
何も処理していませんので、どうやっても super.onTouchEvent 関数が呼び出されます。
投稿 June 23, 2022
アプリのアイコンは最終的には用意が必要ですが、なくてもデフォルトのものが使われるので、今はいりません。
アプリのタイトルは、簡単に設定できます。
画面左側、res、values と開くと strings.xml がありますので、ダブルクリックで開きます。
app_name に定義されている FlashSosuu は、プロジェクト作成時に入力したものですので、変更します。
「Flash 素数選択」としました。
アプリの設定は、 画面左側 manifests を開くと見つかる AndroidManifest.xml にありますが、 権限などが必要ない今は、書き換える必要はなさそうです。
投稿 June 23, 2022
Android スマホ実機を接続します。 まだ一度も実機での実行テストをしていない場合は、 「Android Studio で新規プロジェクトを作成する」 を参照して、あらかじめ問題がないことを確認しておきましょう。
画面最上部、少し右側に接続した機種名が表示されていることを確認し、 その右にある、右向きの緑の矢印をクリックして実行します。
準備が完了すると、実機の画面が変わります。
onDraw 関数が実行され、画面に「テキスト描画!」の文字が表示されました。 横向き(ランドスケープ)でも動作します。
横方向の画面サイズをベースに文字を決めていますので、このようなサイズになっています。 本来はちゃんと計算しなくてはいけません。
動作の確認を完了したら、スマホのメモリ容量を節約するため、アンインストールしておきます。 なお、引き続き同名(同パッケージ名)で開発を進める場合は、アンインストールの必要はないと思います。
これで全画面に自由に文字を描画できるようになりましたので、 canvas クラスにある関数を使えば図形も描けるでしょう。
続き 「Android Studio で画像を自由に描画する」 では、画像を描画したり、タッチイベント処理をしたりします。
Canvas だけでもアプリはできる! #2
Android Studio で画像を自由に描画する
透過ありの PNG 画像をリソースに追加し、等倍で、あるいは拡大・縮小して描画します。 タッチ処理も追加し、タッチした位置に画像が追従してくるコードにしています。
Canvas だけでもアプリはできる! #3
Android Studio でタイマーによる自動画面更新
MainActivity にタイマーを設定して、一定間隔で処理を呼び出すコードを作成しています。
Canvas だけでもアプリはできる! #4
Android Studio で効果音を鳴らす
効果音のような短い音を鳴らすコードを作成しています。
Canvas だけでもアプリはできる! #5
Android Studio で画面を準備する
効果音再生が不要でしたら、アクションバーの消去、画面の縦固定指定、背景画像描画、そしてタッチでウェブサイトを開くコードに進んでも構いません。
Canvas だけでもアプリはできる! #6
Android Studio でボタン表示&入力
座標管理クラスを作成して画面に適切なサイズのボタンを表示し、どれが押されたか判断するタッチ処理を実装しています。 トースト表示や独自クラスの作成についても書いています。
Canvas だけでもアプリはできる! #7
Android Studio でゲームクラスを更新
正解のボタンをタッチしたとき効果音を鳴らす等の正解処理を行い、2 秒後に次の問題に自動的に進む処理を実装しています。 不正解ならトーストで理由を表示します。
Android Studio で全画面プロジェクトを作成する
Empty Activity では画面上部に邪魔になり得るタイトル表示領域がありますが、 Fullscreen Ativity なら、それがなくなるのか、新規プロジェクトを作成して確認しています。
Android Studio で ActionBar を非表示にする
Empty Activity では画面上部に邪魔になり得るタイトル表示領域がありますが、 プロジェクト内の設定の書き換えにより、別プロジェクトにしなくても非表示にできるようです。
Android Studio で Native C++ プロジェクトを作成する
目的としている C++ ネイティブコードを併用する Activity は、 Native C++ プロジェクトを作成すれば、比較的簡単に着手できそうです。
Android Studio で AdMob プロジェクトを作成する
もうひとつの目的としては、AdMob でアプリ内に広告を入れる、です。 AdMob Ads Activity なら簡単に実装できるのでしょうか?
C++ ネイティブアプリでアプリ名を設定する方法の詳細を検討しています。
Android 開発に関する記事をまとめた Android 開発トップ もご覧ください。
以降の数学の基本となる素因数分解の基本部分を、ひたすらトレーニングするための JavaScript コードについて書いています。
因数分解の公式の一部について、ひたすらトレーニングするための JavaScript コードについて書いています。