こんにちは、ふりいです。
画面にあるボタンがクリックされた時の処理の実装方法は大きく2つあるようです。
今回は、その2つについて解説していこうと思います。
これまでに作ったソースコードとも見比べながら、それぞれの特徴を見ていきます。
また、結局どちらを使うべきかについても考えていきましょう。
Contents
onClickを使った実装方法について
先日、ボタンをクリックするとダイアログ画面が表示されるコードを書きました。
詳しくは以下を参照してみて下さい。
≫参考:現役SEがゼロから作るAndroidアプリ構築【デモ作成①~改良編~】
こちらはonClickを使った実装となっていることがわかりますね。
xmlファイルの中に、「onClick」という属性を指定しています。
activity_main.xml
android:onClick="showHandOverDialog"
そして、指定したメソッド名に対応する処理をactivity側で実現するという流れですね。
activity側は、以下の部分が該当します。
MainActivity.java
public void showHandOverDialog(View view) {
HandOverDialogFragment handOverDialogFragment = new HandOverDialogFragment();
handOverDialogFragment.show(getSupportFragmentManager(), "dialog");
}
onClickのメリット・デメリット
onClickについての実装方法はわかりました。
次にメリット・デメリットについても見ていきます。
まずメリットですが、以下のような感じでしょうか。
・どのボタンが、どのメソッドを実行するのかがxmlを見るとわかる。
・簡単にメソッドを追加できる。
xmlとjavaの両方に記載する必要があるので、相互の関係性は把握しやすいですね。
一方でデメリットはどのようなものが考えられるかというと、
・javaを見ただけでは、どの画面で実行されるメソッドがわかりにくい。
・xmlのコードのボリュームが膨大になると、onClickを探すに苦労しそう。
xmlをいじらないといけない点がデメリットにもなり得るのかなと感じました。
また、何かあった時に2か所直さないといけなくなりそうなのも少し気になりますね。
OnClickListenterを使った実装方法について
次に、OnClickListenterを使ってのダイアログの表示方法について見ていきます。
ここまで一緒にコードを書いてくれている方のために、onClickありの状態から変える感じで進めます。
onClickありのソースからonClick関連のコードを削ると、以下のようになります。
少し長くなってしまいますが、コードをまるっとコピーできるようにしてあります。
(今回は「HandOverDialogFragment.java」は変更しません)
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=".activity.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.867"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.941"
app:srcCompat="@android:drawable/ic_menu_add" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.example.app.activity;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.example.app.R;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
上記のコードを修正していきます。
OnClickListenterを用いた実装では、xmlに対しての修正はありません。
よって、javaの方をがっつり変更します。
参考にするのは、以下の記事です。
≫参考:フローティング操作ボタンを追加する - Android デベロッパー
先に変更後のコードですが、このようになりました。
MainActivity.java
package com.example.app.activity;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import com.example.app.ui.HandOverDialogFragment;
import com.example.app.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = findViewById(R.id.floatingActionButton);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
HandOverDialogFragment handOverDialogFragment = new HandOverDialogFragment();
handOverDialogFragment.show(getSupportFragmentManager(), "dialog");
}
});
}
}
18~25行目を追加したような状態ですね。
各行について、簡単に補足します。
18行目では、ボタンID(=floatingActionButton)から、対応するビューの情報を取得しています。
floatingActionButtonは「activity_main.xml」で設定しているIDで、今回はボタンと紐づきます。
19行目からは、Javaでシステム開発をやっている私には、そんなに見かけない形です。
「fab.setOnClickListener」の中身として設定されているのは、匿名クラスというやつです。
匿名クラスは、簡単にクラス定義とインスタンス生成ができちゃう代物ですね。
本来なら、クラスを作る場合にはクラス名をつけたりする必要があります。
しかし、匿名クラス(無名クラス)を使用すると、命名等は不要になるメリットがあります。
この中に、クリック時の動作を記載しています。
クリックされるたびにonClickメソッドが動いてくれます。
22行目、23行目はこれまで見てきたダイアログ表示のためのコードと同じですね。
OnClickListenterのメリット・デメリット
OnClickListenterに関連する実装方法は他にも複数あります。
今回は匿名クラスを用いた方法を紹介しましたが、後々、他の実装方法も登場するかもしれません。
匿名クラスを用いた方法についてのメリットについて、以下のようなことを感じました。
・メソッドの命名等も不要なので、比較的速く実装できる
・追加や修正、削除も結構簡単にできそう
コードのボリュームもあまり増えない印象でした。
ぱぱっと作るには丁度いいかもしれません。
次にデメリットですが、
・実行する処理が比較的多いので、処理が重い
・命名していないので、あとで「これ何するんだっけ?」が起きそう
気を付ければあまり問題ないのかもしれませんが、ここらへんが気になった点ですね。
処理が重くなりそうなのが、一番ひっかかりますね。
結局どちらを使うべきか
onClickを使うか、OnClickListenterを使うか。
んー、その処理の目的によるとしか言えなそうですね。
個人的には、xmlにonClick属性をつける方が理解しやすいです。
しかし、ネットでは推奨していない声が多い感じでした。
上記以外にも便利なライブラリを使用して簡潔に書く方法もあるようです。
書いては反省し、書いては反省しを繰り返して改善していくしかなさそうですね。
今回は以上となります。
みなさんの参考になれば幸いです。