1
4

More than 3 years have passed since last update.

4. Android学習 メモ帳アプリ開発

Posted at

勉強できること
LinearLayoutの使い方
ListViewの使い方
ファイル保存

環境
AndroidStudioのバージョン:4.0.1
言語:Java

メモ帳アプリを作ろう

ざっくり設計:
メモ内容を入力し、入力したメモを一覧表示する
メモの内容を保存する
エディタの内容を削除する

イメージ図:
image.png

image.png

早速作っていきます。
まずxmlに、
メモ内容を入力するためのEditText
メモ内容を保存、消すためのButton
メモ内容を一覧表示するListView
を定義していきます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical">

    <!--メモ内容を入力するためのViewです-->
    <EditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <!-- 保存するボタン、内容を消すボタンは横並びなので -->
    <!-- LinearLayoutを入れ子にして、layout_weightを使って均等割り付けにして実現します -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >

        <!--メモ内容を保存するためのButtonです-->
        <Button
            android:id="@+id/save_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="保存する"
            />

        <!--メモ内容を消すためのButtonです-->
        <Button
            android:id="@+id/clear_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="内容を消す"
            />
    </LinearLayout>

    <!--メモ内容一覧表示するViewです-->
    <ListView
        android:id="@+id/memo_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

次にActivityに
ボタンクリック時の処理、リストにメモ内容を反映させる処理を書いていきます。
ListViewはAdapterを使ってリストを追加していきます。

package com.example.memoapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    ArrayAdapter <String> adapter;

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

        final EditText editText = (EditText)findViewById(R.id.edit_text);
        Button saveButton = (Button)findViewById(R.id.save_button);
        Button clearButton = (Button)findViewById(R.id.clear_button);
        ListView listView = (ListView)findViewById(R.id.memo_list);

        // ListViewに対してアイテムを動的に追加していく場合はadapterを利用します
        // simple_list_item_1 はデフォルトで提供されているTextViewのみ持つレイアウトです。
        // 自作したLayoutを指定して複雑なリストも作成可能です。
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        listView.setAdapter(adapter);

        // 保存ボタンをタップ時の処理
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // エディタの内容を取得します
                String memo = editText.getText().toString();

                // メモ内容が入力されていない場合は保存しないようにします
                if (memo.isEmpty()) {
                    // Toastを使ってメッセージを表示します
                    Toast.makeText(getApplicationContext(), "メモ内容が入力されていません", Toast.LENGTH_SHORT).show();
                    return;
                }

                // リストにメモ内容を反映します
                adapter.add(memo);

                // エディタはクリアします
                editText.setText("");
            }
        });

        // 消すボタンをタップ時の処理
        clearButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // エディタに空文字をセットします
                editText.setText("");
            }
        });
    }
}

実行すると、このような感じになっているかと思います。

Screenshot_20201223-220944.png

ですがこのままだとアプリを一度終了すると、メモ内容が保存されず、
メモ内容が消えてしまうので、保存する機能をつけていきます。

Androidではデータの保存方法が3つあります。

保存方法 詳細
Shared Preferences 設定値などを保存するときに利用します。
ファイル保存 ファイルに書き込むことでデータを保存します。
SQLite DB Androidで用意されているDBです。

今回はファイルにデータを保存する方法をとります。
BufferedReader、BufferedWriterを使ってファイルの書き込み、読み込み処理を実装します。

    private String fileName = "memo.txt";
    private String splitStr = "///";

    // 保存されているメモを取得する
    private String[] readMemo() {
        BufferedReader reader = null;
        String memoTxt = "";
        try {
            reader = new BufferedReader(new InputStreamReader(openFileInput(fileName)));
            String str;
            while((str = reader.readLine()) != null) {
                memoTxt = memoTxt + str;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // メモが保存されていない場合はnullを返す
        if (memoTxt == "") {
            return null;
        }

        // 区切り文字で区切って返す
        return memoTxt.split(splitStr);
    }

    // メモを端末に保存する
    private void saveMemo(String str) {
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(openFileOutput(fileName, Context.MODE_PRIVATE)));
            writer.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Activityファイル自体はこのようになります。

package com.example.memoapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class MainActivity extends AppCompatActivity {

    ArrayAdapter <String> adapter;

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

        final EditText editText = (EditText)findViewById(R.id.edit_text);
        Button saveButton = (Button)findViewById(R.id.save_button);
        Button clearButton = (Button)findViewById(R.id.clear_button);
        final ListView listView = (ListView)findViewById(R.id.memo_list);

        // ListViewに対してアイテムを動的に追加していく場合はadapterを利用します
        // simple_list_item_1 はデフォルトで提供されているTextViewのみ持つレイアウトです。
        // 自作したLayoutを指定して複雑なリストも作成可能です。
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        listView.setAdapter(adapter);

        // 保存済みのメモがあれば読み込む
        String[] saveMemoList = readMemo();
        if (saveMemoList != null) {
            adapter.addAll(saveMemoList);
        }

        // 保存ボタンをタップ時の処理
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // エディタの内容を取得します
                String memo = editText.getText().toString();

                // メモ内容が入力されていない場合は保存しないようにします
                if (memo.isEmpty()) {
                    // Toastを使ってメッセージを表示します
                    Toast.makeText(getApplicationContext(), "メモ内容が入力されていません", Toast.LENGTH_SHORT).show();
                    return;
                }

                // リストにメモ内容を反映します
                adapter.add(memo);

                // エディタはクリアします
                editText.setText("");

                // メモの内容を保存します
                String memoTmp = "";
                for (int i = 0; i < adapter.getCount(); i++) {
                    memoTmp += adapter.getItem(i) + splitStr;
                }
                saveMemo(memoTmp.substring(0, memoTmp.length() - splitStr.length()));
            }
        });

        // 消すボタンをタップ時の処理
        clearButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // エディタに空文字をセットします
                editText.setText("");
            }
        });
    }

    private String fileName = "memo.txt";
    private String splitStr = "///";

    // 保存されているメモを取得する
    private String[] readMemo() {
        BufferedReader reader = null;
        String memoTxt = "";
        try {
            reader = new BufferedReader(new InputStreamReader(openFileInput(fileName)));
            String str;
            while((str = reader.readLine()) != null) {
                memoTxt = memoTxt + str;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // メモが保存されていない場合はnullを返す
        if (memoTxt == "") {
            return null;
        }

        // 区切り文字で区切って返す
        return memoTxt.split(splitStr);
    }

    // メモを端末に保存する
    private void saveMemo(String str) {
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(openFileOutput(fileName, Context.MODE_PRIVATE)));
            writer.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

メモを書いて、一覧に反映し、保存するメモアプリができました。
メモアプリは一覧のメモの削除や編集機能、保存日時の表示など様々な機能があると
より便利になるので色々試してみてください。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4