シンプルなメモ帳アプリをつくろう(入門編最終回 )

入門編の最終回として、今まで解説してきた各章で紹介した機能を取り入れた、シンプルなメモ帳アプリを解説していきます。わからないことがあれば、各章を見返してみてください。

メモアプリの仕様説明

画面は、以下のスクリーンショットで掲載している2画面構成となっています。
各章で説明してきた「Activity」「Intent」「Layout(UI)」「Sqlite」「ActionBar」を学んでいれば、
シンプルなつくりなのですぐ理解出来ると思います。

アプリ完成形のスクリーンショット

メモ帳のリスト画面

memo_list

メモ帳の編集画面
memo_edit

メモ帳の検索画面
memo_search


Android Studio SampleMemoプロジェクトの構成

Screen-Shot-2014-08-31-at-23.15.45 Screen-Shot-2014-08-31-at-23.12.08

メモ帳アプリで関連しているファイルは、基本的に、java、resのフォルダ配下のファイル及びAndroidManifest.xmlのファイルになります。

関連ファイル

プログラムファイル 内容
MemoListActivity.java リスト画面
MemoEditActivity.java 編集画面
MemoAdapter.java リスト画面との橋渡しの役割
MemoDao.java memoテーブルのData Access Object
DatabaseHelper.java SQLiteOpenHelperを継承しているクラス
リソースファイル 内容
angular_circle_corner.xml 編集画面の背景を角丸にしている
activity_memo_list.xml リスト画面のレイアウト
activity_memo_list_row.xml リスト画面のメモ、日付、メモIDのView
activity_memo_edit.xml 編集画面のレイアウト
memo_list.xml リスト画面のアクションバーのメニューボタン
memo_edit.xml 編集画面のアクションバーのメニューボタン
それでは、一番はじめに起動した時に表示されるリスト画面から
ソースコードベースで解説していきます。

ソースコード説明

リスト画面の解説

/**
 * 保存したメモの一覧
 */
public class MemoListActivity extends Activity {

    private static final String TAG = "MemoListActivity";
    private String mSearchWord = null;
    private ListView listView;

    /**
    レイアウトのセット及びlistView変数への格納のみになります。
    MemoEditActivityから戻ってきた場合、onCreateメソッドは実行されない為、
    onResumeメソッドで、基本的な処理を記載するようにしています。
            ※ onCreateは1度実行されると、2度目の実行はされません。
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_memo_list);

        // XMLで定義したListViewを取得する
        listView = (ListView) findViewById(R.id.ListView01);
    }

    /**
    このクラス内のsetDatabaseDataBySearchWordメソッドを呼び、
    そのメソッドで、データベースから値を取得しListViewにデータをセットしています。
     */
    @Override
    protected void onResume() {
        super.onResume();

        setDatabaseDataBySearchWord(mSearchWord);
    }

    /**
     オプションメニューの作成処理になります。
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.memo_list, menu);

        // SearchViewの作成
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.actionbar_search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        // イベントリスナー処理
        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {

            // 検索窓から文字が入力される度に実行されます。
            @Override
            public boolean onQueryTextChange(String searchWord) {
                setDatabaseDataBySearchWord(searchWord);
                mSearchWord = searchWord;
                return true;
            }

            // 検索ボタンもしくは、キーボードでEnterされた際に実行されます。
            @Override
            public boolean onQueryTextSubmit(String searchWord) {
                return true;
            }
        };

        // イベントリスナーをセットします。
        searchView.setOnQueryTextListener(queryTextListener);

        return super.onCreateOptionsMenu(menu);
    }

    /**
     メニューのアイテムが選択された際の処理です。
     新規ボタンがタップされていれば、MemoEditActivityへ遷移します。
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        // 新規ボタン追加ボタンがタップされた処理
        if (id == R.id.actionbar_add) {
            Intent intent = new Intent();
            intent.setClassName(this, "net.hundredapps.samplememo.MemoEditActivity");
            startActivity(intent);
            return true;

        }

        // 検索ボタンがタップされた処理
        if (id == R.id.actionbar_search) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
    このActivity内での一番大事な検索処理になります。
     */
    private void setDatabaseDataBySearchWord(String searchWord) {

        ArrayList> memoLists;
        MemoDao dao = new MemoDao(getApplicationContext());
        dao.connection();

        if (TextUtils.isEmpty(searchWord)) {
            memoLists = dao.searchAll();
        } else {
            memoLists = dao.searchAllByWord(searchWord);
        }
        dao.close();

        setListView(memoLists);
    }

    /**
     アダプタを介して、リストビューにデータをセットしています。
     */
    private void setListView(ArrayList> memoLists) {

        MemoListAdapter memoListAdapter = new MemoListAdapter(getApplicationContext());
        memoListAdapter.setMemoLists(memoLists);
        listView.setAdapter(memoListAdapter);
        listView.setOnItemClickListener(new ClickEventOnMemoActivity());
        //listView.setTextFilterEnabled(true);
    }

    /**
     リストでメモがタップされた際の処理(後々、ファイル分割しやすいように内部クラスとして記述)になります。
     インテントを生成し、メモIDをセット後、MemoEditActivityへ遷移します。
     (このイベントリスナーである内部クラスは、上記のsetListViewメソッドで呼び出しています。)
     */
    class ClickEventOnMemoActivity implements AdapterView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {

            TextView idView = (TextView)view.findViewById(R.id.id);

            Intent intent = new Intent();
            intent.setClassName(getApplicationContext(), "net.hundredapps.samplememo.MemoEditActivity");
            intent.putExtra("memo_id", idView.getText().toString());
            startActivity(intent);
        }
    }

}

以上が、リスト画面の解説になります。

編集画面の解説

/**
 * 編集画面
 */
public class MemoEditActivity extends Activity {

    private MemoDao dao = null;

    /**
     メモIDを取得し、該当するメモ内容をデーターベースから該当するデータを取得しています。
     メモ内容を取得後、EditTextのViewにデータをセットして表示させています。
     又、メモIDが取得出来なかったら、新規メモの作成と見なし、そのままEditViewを表示しています。
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_memo_edit);

        // アクションバーの戻るを設定
        getActionBar().setDisplayHomeAsUpEnabled(true);

        // インテントの取得
        Intent data = getIntent();
        if (data != null) {

            // memoIdを取得
            String memoId = data.getStringExtra("memo_id");
            if (memoId != null) {

                // TextViewを取得し、メモIDをセット
                TextView textView = (TextView) findViewById(R.id.memo_id);
                textView.setText(memoId);

                // データ検索
                MemoDao memoDao = new MemoDao(getApplicationContext());
                memoDao.connection();
                HashMap memoMap = memoDao.searchById(memoId);
                memoDao.close();

                // EditTextのViewにデータを格納
                EditText editText = (EditText) findViewById(R.id.edittext01);
                editText.setText(memoMap.get("content").toString());

            }

        }

    }

    /**
     更新と削除のメニューを作成しています。
     /app/src/main/res/menu/memo_edit.xml参照
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.memo_edit, menu);
        return true;
    }

    /**
     アクションバーの更新ボタンと削除ボタンがタップされた処理が記載されています。
     まず、更新ボタンですが、メモ内容が入るEditViewを取得します。メモ内容がなければ、
     何もしません。メモ内容があれば、更に、TextViewにmemo_idが存在しているか確認します。
     存在していれば、前の画面でリストをタップしてきた状態(編集モード)となるので、データベースを
     更新します。なければ、新規にデータを追加するとなります。
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        // 保存ボタンがタップされた処理
        if (id == R.id.actionbar_save) {

            // EditTextのViewから入力内容を取得
            EditText edit = (EditText)findViewById(R.id.edittext01);
            String content = edit.getText().toString();
            if (content == null) return false;

            // TextViewを取得し、メモIDを取得
            TextView textView = (TextView)findViewById(R.id.memo_id);
            String memoId = textView.getText().toString();


            MemoDao memoDao = new MemoDao(getApplicationContext());
            memoDao.connection();

            if (memoId == null || memoId.length() == 0) {
                // データ新規追加
                memoId = String.valueOf(memoDao.addMemo(content.trim()));
                textView.setText(String.valueOf(memoId));
            } else {
                // データ更新処理
                memoDao.updateContentById(memoId, content.trim());
            }
            memoDao.close();
            Toast.makeText(this, "保存しました。", Toast.LENGTH_SHORT).show();

            return true;

        // 削除ボタンがタップされた処理
        } else if (id == R.id.actionbar_delete) {
            TextView memoIdView = (TextView)findViewById(R.id.memo_id);
            String memoId = memoIdView.getText().toString();
            // 削除処理
            MemoDao memoDao = new MemoDao(getApplicationContext());
            memoDao.connection();
            memoDao.delById(memoId);
            memoDao.close();

            Toast.makeText(this, "削除しました。", Toast.LENGTH_SHORT).show();
            finish();// activity終了
            return true;

        // アクションバーの戻るがタップされた処理
        } else if (id == android.R.id.home){
            finish();// activity終了
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

その他

MemoListAdapter.javaは、
「Android User Interface(画面)の作り方」を参照
MemoDao.java、DatabaseHelper.javaの2ファイルは、
「Android SQLiteのDB操作を学ぼう」参照

まとめ

以上で、「これからはじめるAndroidアプリ開発〜入門編〜」は、終了になりますが、
如何でしたでしょうか?

今後は、次のステップ(中級編)として、
タブレット対応、カレンダー機能、背景変更機能、フォントカラー変更機能などの
機能追加を交えながら解説して行きたいと思います。

ABOUTこの記事をかいた人

hundredappsの管理人であり、ソフトウェア開発者です。 開発したソフトウェアで、世の中の不便を1つでも改善できたらと思います。