練習問題として、数値を入力して計算する「計算アプリ」を作成します。
練習問題のJavaコードは、「GUIコンポーネントを含むJavaコードの実行」に示す手順で実行して確認できます。練習問題 – 計算アプリの作成
練習問題として、次の機能を持つ計算アプリを作成します。
- 入力した二つの値を足し算する機能
- 入力した二つの値を掛け算する機能
- 計算するときに確認する機能
計算アプリを作成するための補足
- 「+」アイコンは「android:drawable/ic_input_add」、「X」アイコンは「android.R.drawable.presence_offline」をそれぞれ使用する
- 画面中央に表示する同じ形状のアイコンの表示は、デザインエディタを使って、パレットのWidgetsからImageViewを使用して表示する
初期画画面
計算アプリを起動すると次の初期画面を表示します。
- GUIコンポーネント「TopMenuBar」に表示されている「+」アイコンと「X」アイコンでそれぞれ足し算と掛け算を指示する。このアイコンをクリックすることで、画面中央に表示されている同じ形状のアイコンが切り替わる。
- 2か所のデータ入力欄を作成する。
- 「計算」ボタンを押されると、計算確認のダイアログを表示する
- 計算した結果は中央右側に作成したTextViewに表示する
足し算機能
GUIコンポーネント「TopMenuBar」で「+」アイコンを選択します。同じ形状の「+」アイコンが画面中央に表示されます。
二つの値を設定して「計算」ボタンを押すと、計算確認のダイアログが表示され、「はい」ボタンを押すと計算結果が次のように表示されます。
掛け算機能
GUIコンポーネント「TopMenuBar」で「X」アイコンを選択します。同じ形状の「X」アイコンが画面中央に表示されます。
二つの値を設定して「計算」ボタンを押すと、計算確認のダイアログが表示され、「はい」ボタンを押すと計算結果が次のように表示されます。
計算確認機能
「計算」ボタンを押すと次のように計算確認のダイアログを表示します。「はい」ボタンが押されると、呼び出し元の機能に従って引き算または掛け算を行います。「いいえ」ボタンが押されると処理は行いません。
練習問題 – 解答
計算アプリの作成方法を示します。
足し算と掛け算の選択
足し算と掛け算の選択は、「5.3 GUIの基礎(ナビゲーション系)」で学習したGUIコンポーネント「TopMenuBar」で行います。パレットから「Menu Item」をクリックして、コンポーネント・ツリーにドラッグアンドドロップすると、次のように表示されます。
メニューアイテム「item1」のIDを示すプロパティ「id」と、表示する文字を示すプロパティ「title」などを次のように変更します。
- プロパティ「id」:「item1」
- プロパティ「title」:「Item1」
- プロパティ「icon」:「ic_input_add」
- プロパティ「showAsAction」:「ifRoom」
メニューアイテム「item2」のIDを示すプロパティ「id」と、表示する文字を示すプロパティ「title」などを次のように変更します。
- プロパティ「id」:「item2」
- プロパティ「title」:「Item2」
- プロパティ「icon」:「presence_offline」
- プロパティ「showAsAction」:「ifRoom」
作成した「top_menu.xml」を示します。
top_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- #① -->
<item
android:id="@+id/item1"
android:icon="@android:drawable/ic_input_add"
android:title="Item1"
app:showAsAction="ifRoom" />
<!-- #➁ -->
<item
android:id="@+id/item2"
android:icon="@android:drawable/presence_offline"
android:title="Item2"
app:showAsAction="ifRoom" />
</menu>
- #①の「android:id」は、「item1」のプロパティ「id」
- #①の「android:icon」は、「item1」のプロパティ「icon」
- #①の「android:title」は、「item1」のプロパティ「title」
- #①の「app:showAsAction」は、「item1」のプロパティ「showAsAction」
- #➁の「android:id」は、「item2」のプロパティ「id」
- #➁の「android:icon」は、「item2」のプロパティ「icon」
- #➁の「android:title」は、「item2」のプロパティ「title」
- #➁の「app:showAsAction」は、「item2」のプロパティ「showAsAction」
値の入力と「計算」ボタンの作成
値を入力する方法は、「5.4 GUIの基礎(コントロール系)」の「テキスト入力」で行います。ただし、EditTextのプロパティ「inputType」を「number」にします。また、「計算」ボタンは「5.1 デザインエディタの操作方法」の「Buttonの表示」で行います。なお、配置方法については、「5.1 デザインエディタの操作方法」の「Buttonの作成」を参照します。
- パレットの「Containers」から「Toolbar」を選択してコンポーネントツリーのTextViewの上ににドラッグアンドドロップします。
- パレットの「Text」から「Number」を選択してコンポーネントツリーのTextViewの上にドラッグアンドドロップし、表示された「Number」をドラッグして配置します。プロパティ「id」は「firstValue」、プロパティ「inputType」は「number」に設定します。
- パレットの「Widgets」から「ImageView」を選択してコンポーネントツリーのTextViewの上にドラッグアンドドロップし、表示された「ImageView」をドラッグして配置します。プロパティ「id」は「imageView」、プロパティ「srcCompat」は「ic_input_add」に設定します。
- パレットの「Text」から「Number」を選択してコンポーネントツリーのTextViewの上にドラッグアンドドロップし、表示された「Number」をドラッグして配置します。プロパティ「id」は「secondValue」、プロパティ「inputType」は「number」に設定します。
- すでにコンポーネントツリーに配置されている「TextView」をドラッグして配置します。プロパティ「id」は「textView」に設定します。
- パレットの「Buttons」から「Button」を選択してコンポーネントツリー最後にドラッグアンドドロップし、表示された「Button」をドラッグして配置します。プロパティ「id」は「button」、プロパティ「text」は「計算」に設定します。
GUIコンポーネントの配置が終了するとデザインエディタには次のように表示されます。
作成した「activity_main.xml」を示します。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- #① -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<!-- #➁ -->
<EditText
android:id="@+id/firstValue"
android:layout_width="65dp"
android:layout_height="65dp"
android:ems="10"
android:inputType="number"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.092"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.329" />
<!-- #③ -->
<ImageView
android:id="@+id/imageView"
android:layout_width="27dp"
android:layout_height="20dp"
app:layout_constraintBottom_toBottomOf="@+id/firstValue"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.341"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/firstValue"
app:layout_constraintVertical_bias="0.466"
app:srcCompat="@android:drawable/ic_input_add" />
<!-- #④ -->
<EditText
android:id="@+id/secondValue"
android:layout_width="65dp"
android:layout_height="65dp"
android:ems="10"
android:inputType="number"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.534"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/imageView"
app:layout_constraintVertical_bias="0.466" />
<!-- #⑤ -->
<TextView
android:id="@+id/textView"
android:layout_width="93dp"
android:layout_height="40dp"
app:layout_constraintBottom_toBottomOf="@+id/secondValue"
app:layout_constraintHorizontal_bias="0.908"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/secondValue"
app:layout_constraintVertical_bias="0.84" />
<!-- #⑥ -->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="計算"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.499" />
</androidx.constraintlayout.widget.ConstraintLayout>
- #①は、Toolbar。足し算または掛け算の選択
- #➁は、Number。最初の値
- #③は、ImageView
- #④は、Number。次の値
- #⑤は、TextView。計算結果の表示領域
- #⑥は、Button
ダイアログとイベント処理
計算確認のダイアログ表示やボタンなどのイベント処理を行います。計算確認のダイアログは、「5.5 GUIの基礎(通知系)」で学習した「Dialog」で行います。
「ImageView」への表示を識別するため、「onOptionsItemSelected」メソッドで「getItemId」を呼び出し、メニューアイテムに対応する一意のID (=プロパティ「id」によって定義されるID)で次の処理を判断します。「+」アイコン(ic_input_add)が表示されているときは、「ImageView」のプロパティ「srcCompat」に「ic_input_add」を設定します。「X」アイコン(presence_offline)が表示されているときは、「ImageView」のプロパティ「srcCompat」に「presence_offline」を設定します。
作成した「MainActivity.java」を示します。
MainActivity.java
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.Button;
import android.view.View;
import androidx.appcompat.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.TextView;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView textView = null;
private EditText firstValue;
private EditText secondValue;
private boolean plus = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar); // #①
setSupportActionBar(myToolbar); // #➁
// ボタンの取得
Button button = (Button) findViewById(R.id.button);
// リスナーの登録
button.setOnClickListener((View.OnClickListener) this); // #③
textView = findViewById(R.id.textView);
firstValue = findViewById(R.id.firstValue);
secondValue = findViewById(R.id.secondValue);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) { // #④
getMenuInflater().inflate(R.menu.top_menu, menu); // #⑤
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { // #⑥
ImageView myImage = findViewById(R.id.imageView);
switch (item.getItemId()) { // #⑦
case R.id.item1:
myImage.setImageResource(android.R.drawable.ic_input_add); // #⑧
plus = true;
return true;
case R.id.item2:
myImage.setImageResource(android.R.drawable.presence_offline); // #⑨
plus = false;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onClick(View v) { // #⑩
textView.setText(" ");
if (v.getId() == R.id.button) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("計算アプリ") // #⑪
.setMessage("計算を行いますか?") // #⑫
.setPositiveButton( // #⑬
"はい", // #⑭
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String value = "";
if (plus) {
value = String.valueOf(Integer.parseInt(firstValue.getText().toString()) + // #⑮
Integer.parseInt(secondValue.getText().toString()));
} else {
value = String.valueOf(Integer.parseInt(firstValue.getText().toString()) * // #⑯
Integer.parseInt(secondValue.getText().toString()));
}
textView.setText("= " + value);
}
})
.setNegativeButton( // #⑰
"いいえ", // #⑱
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//
}
})
.show();
}
}
}
- #①は、GUIコンポーネント「Toolbar」をオブジェクト化する
- #➁は、「setSupportActionBar」を使用してツールバーがアクティビティのアプリバーとして設定する
- #③は、ボタンが押されたときに発生したイベントを受け取るイベントリスナを、「setOnClickListener」メソッドを使って関連付ける。
- #④は、「onCreateOptionsMenu」メソッドを使ってメニューを作成する
- #⑤は、作成した「R.menu.top_menu」をメニューに設定する
- #⑥は、メニューアイテムが選択されると「onOptionsItemSelected」メソッドを呼び出す
- #⑦は、パラメータで与えられた選択された「MenuItem」を使って、項目を識別するため、「getItemId」を呼び出す。メニューアイテムに対応する一意のID (=プロパティ「id」によって定義されるID)で次の処理を判断する
- #⑧は、「ImageView」の表示を「ic_input_add」に設定する。
- #⑨は、「ImageView」の表示を「presence_offline」に設定する。
- #⑩は、ボタンが押されたとき、発生したイベントを受け取る「OnClick」を定義する
- #⑪は、タイトル「計算アプリ」を設定する
- #⑫は、メッセージ「計算を行いますか?」を設定する
- #⑬は、肯定ボタンを設定する
- #⑭は、ボタン名「はい」を設定する
- #⑮は、足し算の計算を行い、結果を「TextView」に表示する。
- #⑯は、掛け算の計算を行い、結果を「TextView」に表示する。
- #⑰は、否定ボタンを設定する
- #⑱は、ボタン名「いいえ」を設定する
本節の説明は以上になります。