[Android その３] Androidのアプリケーションの基本開発

# Android  APP 基本開発(Java)
今回作るAPPはとーーーーーーっても簡単なやつです。(なぜなら私もほぼ初めてといえるので)
間違いもあると思いますが、頑張ります(頑張りましょうｍ)
## プロジェクトの作成
Android Appでのプロジェクトの開発については、調べて作ってみてくださいｍｍ

## メモアプリ
単純なメモアプリを作りたいと思います。
画面の作成、ボタンの作成、ボタン押下で、テキストボックスのダイアログを表示させて、入力したら、画面に表示させるようにします。

## 実装
### UIの設計
メモアプリの基本UIを設計します。シンプルなリストビューでメモの一覧を表示し、メモの追加ボタンを用意します。

###### activity_main.xml の編集
このファイルはプロジェクトのres/layoutフォルダにあります。
```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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- メモのリストを表示するリストビュー -->
    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:padding="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/addButton"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <!-- メモを追加するためのボタン -->
    <Button
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add Memo"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginBottom="16dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>


```

#### 実装の説明
##### 1. XML宣言
```xml
<?xml version="1.0" encoding="utf-8"?>
```
この行はXMLファイルの宣言です。version="1.0"はXMLのバージョンを示し、encoding="utf-8"はファイルの文字エンコーディングを指定しています。UTF-8は、多くの言語をサポートする一般的な文字エンコーディングです。

##### 2. ConstraintLayout要素の開始タグ
```xml
<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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
```
この部分はConstraintLayoutの開始タグで、レイアウトの親コンテントとして機能します。

##### 属性の説明
<details><summary>属性の説明 </summary>

* 'androidx.constraintlayout.widget.ConstraintLayout':
    * ConstraintLayoutは、他のビューを柔軟に配置するためのレイアウトです。制約（constraints）を使って、各ビューの位置やサイズを親ビューや他のビューに対して指定します。
*  'xmlns:android="http://schemas.android.com/apk/res/android":
    * これはAndroidの標準的なXML名前空間で、Androidの基本的な属性を使用するために必要です。
* 'xmlns:tools="http://schemas.android.com/tools"':
    *  開発ツール専用の名前空間で、アプリが実行されている間には影響を与えないが、レイアウトエディタでの表示に使用される属性を定義します。
* 'android:id="@+id/main"':
    * このConstraintLayoutのユニークなIDです。このIDはJavaコードでレイアウトを参照するときに使います。
* 'android:layout_width="match_parent"':
    * レイアウトの幅を親ビュー（画面全体）と同じに設定します。
* 'android:layout_height="match_parent"':
    * レイアウトの高さを親ビュー（画面全体）と同じに設定します。
* 'tools:context=".MainActivity"':
    * このレイアウトがどのアクティビティで使用されるかを指定します。これは開発時のツールでのプレビューや設定を助けるためのもので、実行時には影響しません。

</details>

##### 3. ListView要素
```xml
<ListView
    android:id="@+id/listView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:padding="16dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/addButton"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>
```
ListViewは、複数のアイテムを縦にリスト表示するためのコンポーネントです。ここでは、メモのリストを表示するために使用されています。

##### 属性の説明
<details><summary>属性の説明 </summary>

* 'ListView':
    * ListViewは、複数のアイテムを縦方向にスクロールして表示するためのUIコンポーネントです。ここでは、メモのリストを表示するために使用されています。
* 'android:id="@+id/listView':
    * このListViewのユニークなIDです。Javaコードでこのビューを操作する際に参照されます。
* 'android:layout_width="0dp"':
    * ビューの幅をゼロに設定していますが、ConstraintLayoutの制約により制御されます。この属性は、ConstraintLayout内でビューのサイズを制約に従わせるために設定されます。
* 'android:layout_height="0dp':
    * 高さも同様にゼロに設定されていますが、制約により設定されるサイズに依存します。
* 'android:padding="16dp"':
    * ListViewの内部の全ての辺に16dpのパディングを追加しています。これは、リストアイテムとビューの端との間にスペースを作るためです。
* 'app:layout_constraintTop_toTopOf="parent"':
    * ListViewの上端を親（ConstraintLayout）の上端に制約しています。
* 'app:layout_constraintBottom_toTopOf="@+id/addButton"':
    * ListViewの下端をButtonの上端に制約しています。これにより、ListViewはボタンの上に配置されます。
* 'app:layout_constraintLeft_toLeftOf="parent"':
    * ListViewの左端を親（ConstraintLayout）の左端に制約しています。
* 'app:layout_constraintRight_toRightOf="parent"':
    * ListViewの右端を親（ConstraintLayout）の右端に制約しています。

</details>

##### 4. Button要素
```xml
<Button
    android:id="@+id/addButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Add Memo"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:layout_marginBottom="16dp"/>
```
Buttonは、ユーザーがタップして何らかのアクションを実行するためのUIコンポーネントです。ここでは、「Add Memo」というテキストの付いたボタンが定義されています。

##### 属性の説明
<details><summary>属性の説明 </summary>

* 'Button':
    * Buttonは、ユーザーがタップしてアクションをトリガーするためのUIコンポーネントです。ここでは、メモを追加するためのボタンです。
* 'android:id="@+id/addButton"':
    * このButtonのユニークなIDです。Javaコードでこのボタンを参照し、クリックリスナーを設定する際などに使用されます。
* 'android:layout_width="wrap_content"':
    * ボタンの幅をその内容に合わせて自動的に設定します（テキストの長さに応じて）。
* 'android:layout_height="wrap_content"':
    * ボタンの高さをその内容に合わせて自動的に設定します。
* 'android:text="Add Memo"':
    * ボタンに表示されるテキストです。この場合、「Add Memo」というラベルが表示されます。
* 'app:layout_constraintBottom_toBottomOf="parent"':
    * ボタンの下端を親（ConstraintLayout）の下端に制約しています。これにより、ボタンは画面の最下部に配置されます。
* 'app:layout_constraintLeft_toLeftOf="parent"':
    * ボタンの左端を親（ConstraintLayout）の左端に制約しています。
* 'app:layout_constraintRight_toRightOf="parent"':
    * ボタンの右端を親（ConstraintLayout）の右端に制約しています。これにより、ボタンは水平方向に中央揃えされます。
* 'android:layout_marginBottom="16dp"':
    * ボタンの下に16dpの余白を追加します。これにより、ボタンと画面の下端の間にスペースができます。

</details>

##### 5. ConstraintLayoutの終了タグ
```xml
</androidx.constraintlayout.widget.ConstraintLayout>
```
この行はConstraintLayoutの終了タグで、レイアウトの定義を閉じます。

###### activity_main.xml の編集

### MainActivityの実装
MainActivityクラスを編集して、基本的な機能（メモの追加と表示）を実装します。

###### MainActivity.java
```java
package com.example.memoapp;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ArrayList<String> memoList; //メモを格納するリスト
    private ArrayAdapter<String> adapter; //リスト表示用のアダプター

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // メモリストの初期化
        memoList = new ArrayList<>();

        // リストビューとアダプターの設定
        ListView listView = findViewById(R.id.listView);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, memoList);
        listView.setAdapter(adapter);

        // メモ追加ボタンのクリックイベント
        Button addButton = findViewById(R.id.addButton);
        addButton.setOnClickListener(v -> showAddMemoDialog());
    }

    // メモ追加のダイアログ表示
    private void showAddMemoDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("new Memo");

        final EditText input = new EditText(this);
        builder.setView(input);
        builder.setPositiveButton("Add", ((dialog, which) -> {
            String memo = input.getText().toString();
            if (!memo.isEmpty()) {
                addMemo(memo);
            }
        }));
        builder.setNegativeButton("Cancel", ((dialog, which) -> dialog.cancel()));
        builder.show();
    }

    private void addMemo(String memo) {
        memoList.add(memo);
        adapter.notifyDataSetChanged(); //リストビュー更新
    }
}
```

##### 1. パッケージとインポート
```java
package com.example.memoapp;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
```
##### 説明
<details><summary>説明 </summary>


* 'package com.example.memoapp;': パッケージ宣言です。MainActivityクラスが属するパッケージを指定しています。com.example.memoappは一般的なパッケージ名の形式です。
* 'import文':
    * 'android.os.Bundle': アクティビティの状態を保存し、再構築するためのオブジェクトを提供します。
    * 'android.widget.*':  Androidのウィジェットライブラリをインポートしています。ArrayAdapter, Button, EditText, ListViewなど、UIコンポーネントを使用するために必要です。
    * 'androidx.appcompat.*': AppCompatライブラリを使用しているため、AlertDialogとAppCompatActivityをインポートしています。AppCompatは互換性のために必要です。
    * 'java.util.ArrayList':ArrayListクラスを使用するためのインポート文です。メモを格納するリストとして使用されます。
    
</details>

##### 2. MainActivityクラスの宣言
```java
public class MainActivity extends AppCompatActivity {
```
##### 説明
<details><summary>説明 </summary>


* 'public class MainActivity': クラスの宣言です。MainActivityという名前で定義されており、public修飾子によりどこからでもアクセス可能です。
* 'extends AppCompatActivity': MainActivityはAppCompatActivityを継承しています。これにより、最新のAndroid機能を利用しながら、古いデバイスとも互換性が保たれます。

    
</details>

##### 3. フィールド変数の宣言
```java
private ArrayList<String> memoList; //メモを格納するリスト
private ArrayAdapter<String> adapter; //リスト表示用のアダプター
```
##### 説明
<details><summary>説明 </summary>


* 'private ArrayList<String> memoList': memoListは、メモを格納するためのArrayListです。String型のデータを保持します。
* 'private ArrayAdapter<String> adapter': 
    adapterはArrayAdapterのインスタンスで、リストビューにデータを表示するためのアダプターです。ArrayAdapterは、ArrayListのデータをリストビューに適切な形式で表示するために使用されます。

    
</details>

##### 4. onCreateメソッドのオーバーライド
```java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // メモリストの初期化
    memoList = new ArrayList<>();

    // リストビューとアダプターの設定
    ListView listView = findViewById(R.id.listView);
    adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, memoList);
    listView.setAdapter(adapter);

    // メモ追加ボタンのクリックイベント
    Button addButton = findViewById(R.id.addButton);
    addButton.setOnClickListener(v -> showAddMemoDialog());
}
```
##### 説明
<details><summary>説明 </summary>


* '@Override': このメソッドがスーパークラス(AppCompatActivity) のメソッドをオーバライドしていることを表します。
* 'protected void onCreate(Bundle savedInstanceState)': アクティビティのライフサイクルメソッドの一つで、アクティビティが最初に作成されたときに呼び出されます。このメソッドは、アクティビティの初期化を行うもので、アプリが軌道された際に最初に実行されるメソッドです。 
* 'super.onCreate(savedInstanceState);': スーパークラス(AppCompatActivity) のonCreateメソッドを呼び出します。これにより、アクティビティの標準的な初期化処理が行われます。
* 'setContentView(R.layout.activity_main);': アクティビティのレイアウトを設定します。ここでは、activity_main.xmlファイルに定義されたレイアウトが適用されます。
* 'memoList = new ArrayList<>();': memoListを新しい空のArrayListで初期化します。このリストはユーザーが追加するメモを格納するために使用されます。 
* 'ListView listView = findViewById(R.id.listView);': activity_main.xml レイアウトファイルで定義されたListViewを取得し、listView変数に割り当てます。 
* 'adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, memoList);': ArrayAdapterを作成し、memoListを表示するためのレイアウトとして、simple_list_item_1を使用します。このアダプターは、メモリリストのデータをリストビューに表示するための仲介役です。
* 'listView.setAdapter(adapter);': listViewにadapterを設定します。これにより、リストビューがmemoListの内容を表示するようになります。 
* 'Button addButton = findViewById(R.id.addButton);': XMLレイアウトで定義されたButtonを取得し、addButton変数に割り当てます。 
* 'addButton.setOnClickListener(v -> showAddMemoDialog());': addButtonのクリックイベントリスナーを設定します。このボタンがクリックされると、showAddMemoDialog()メソッドが呼び出されます。

</details>


##### 5. メモ追加のダイアログ表示メソッド
```java
// メモ追加のダイアログ表示
private void showAddMemoDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("new Memo");

    final EditText input = new EditText(this);
    builder.setView(input);
    builder.setPositiveButton("Add", ((dialog, which) -> {
        String memo = input.getText().toString();
        if (!memo.isEmpty()) {
            addMemo(memo);
        }
    }));
    builder.setNegativeButton("Cancel", ((dialog, which) -> dialog.cancel()));
    builder.show();
}
```
##### 説明
<details><summary>説明 </summary>


* 'private void showAddMemoDialog()': メモを追加するためのダイアログを表示するメソッドです。
* 'AlertDialog.Builder builder = new AlertDialog.Builder(this);': AlertDialogのビルダーを作成します。thisは現在のアクティビティを指しています。
* 'builder.setTitle("new Memo");': ダイアログのタイトルを設定します。
* 'final EditText input = new EditText(this);': ユーザーが新しいメモを入力するためのEditTextフィールドを作成します。
* 'builder.setView(input);': EditTextをダイアログのビューとして設定します。
* 'builder.setPositiveButton("Add", ((dialog, which) -> {...}))':「Add」ボタンを追加し、そのクリック時の動作を設定します。ユーザーが入力したテキストが空でない場合は、addMemo(memo)メソッドを呼び出して新しいメモをリストに追加します。
* 'builder.setNegativeButton("Cancel", ((dialog, which) -> dialog.cancel()));': 「Cancel」ボタンを追加し、クリック時にダイアログを閉じる動作を設定します。
* 'builder.show();': ダイアログを表示します。
    
</details>

##### 6. メモの追加メソッド
```java
private void addMemo(String memo) {
    memoList.add(memo);
    adapter.notifyDataSetChanged(); //リストビュー更新
}

```
##### 説明
<details><summary>説明 </summary>


* 'private void addMemo(String memo)': 新しいメモをmemoListに追加し、リストビューを更新するメソッドです。
* 'memoList.add(memo);': memoListに新しいメモを追加します。
* 'adapter.notifyDataSetChanged();': ArrayAdapterにリストデータが変更されたことを通知し、リストビューを再描画させます。これにより、新しいメモが即座にリストビューに表示されます。
    
</details>

## 終わり
とーーーーーてっも簡単な内容でしたが、何となくわかっていただけたらと思います。
続きも公開することもあると思うので、その時はどうぞよろしくお願いいたしますｍｍｍｍ