平凡エンジニアからの出発

一に努力、二に理想、三に積小為大。

【AndroidTraining】Thread 1

Lesson

Thread 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • 別スレッドからTextViewの更新をする

Snap Shot

※count up していく f:id:atuyan39:20210414014506p:plain

Step by Step

  1. 新規にTrainingThreadActivity.javaを追加する
  2. TextView(別スレッドから更新する)、Button(別スレッドを開始する)を追加する
  3. Buttonにクリックリスナーを追加する
  4. 別スレッドを新規に作成する
  new Thread(() -> {
    // 時間のかかる処理等を記載する
  }).start();

5 . メインスレッド(UIスレッド)へ通知を行うために、Handlerを作成します。
その際に、getMainLooperを使い、メインスレッドのLooperを取得し、Handlerの引数として渡します。
このHadnlerに対して、post(Runnable r)メソッドを呼ぶことで、
メインスレッドのViewに操作することができるようになります。

  Handler handler = new Handler(getMainLooper());
  String text = "count:";
  for (int i = 0; ; i++) {
    try {
      String finalText = text + i;
      Thread.sleep(THREAD_SLEEP_TIME);
      handler.post(() -> mTextView.setText(finalText));
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

Code

Thread 1 · atuyan39/AndroidTraining@fa686c4 · GitHub

Reference

developer.android.com

Memo

ThreadやLooperやMessage、細かい機構までわかるように今後問題を作っていきたい。

【AndroidTraining】ImageView 1

Lesson

ImageView 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • 任意の画像を表示する

Snap Shot

f:id:atuyan39:20210412235124p:plain

Step by Step

  1. 新規にTrainingImageViewActivity.javaを追加する
  2. src\main\res\drawable配下に、画像を追加する
  3. レイアウトファイルにImageViewのパーツを追加する
  4. 2で追加したリソースを参照するように設定する

Code

ImageView 1 · atuyan39/AndroidTraining@b4f4ec2 · GitHub

Reference

developer.android.com

Memo

いつもバックエンドのアプリ開発をしているので、画像を操作するのは新鮮

【AndroidTraining】Activity 2 画面を切り替えよう

Lesson

Activity 2
画面を切り替えよう

Mission

下記の仕様を満たすアプリを作りましょう。

  • SubActivityへの画面遷移をする
  • MainActivityとSubActivityのライフサイクルのログを出力する

Snap Shot

f:id:atuyan39:20210412003617p:plainf:id:atuyan39:20210412003621p:plain

ログ

◆Mainアクティビティ起動
2021-04-11 22:53:41.323 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onCreate
2021-04-11 22:53:41.412 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStart
2021-04-11 22:53:41.413 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onPostCreate
2021-04-11 22:53:41.413 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResume
2021-04-11 22:53:41.414 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResumeFragments
2021-04-11 22:53:47.898 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onPause

◆Subアクティビティ起動(Mainアクティビティはバックグラウンドへ)
2021-04-11 22:53:47.952 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onStart
2021-04-11 22:53:47.952 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onPostCreate
2021-04-11 22:53:47.953 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onResume
2021-04-11 22:53:47.953 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onResumeFragments
2021-04-11 22:53:48.484 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStop
2021-04-11 22:53:48.484 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onSaveInstanceState

◆Subアクティビティ終了(Mainアクティビティがフォアグラウンドへ)
2021-04-11 22:53:54.943 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onPause
2021-04-11 22:53:54.969 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onRestart
2021-04-11 22:53:54.969 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStart
2021-04-11 22:53:54.970 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResume
2021-04-11 22:53:54.970 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResumeFragments
2021-04-11 22:53:55.528 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onStop
2021-04-11 22:53:55.532 29929-29929/com.hatenablog.atuyan39.androidtraining D/LifeCycle_Sub: onDestroy

Step by Step

  1. 前回の環境(Activity 1)を用意する
  2. 新しくActivity(TrainingSubActivity.java)を追加する
  3. ライフサイクルのメソッドをoverrideする(コピペ)
    • onCreate
    • onRestart
    • onStart
    • onRestoreInstanceState
    • onPostCreate
    • onResume
    • onResumeFragments
    • onPause
    • onStop
    • onSaveInstanceState
    • onDestory
  4. ButtonとTextのViewを各Activityに追加する
  5. TrainingActivityのボタン押下時に、SubActivityを起動する処理を追加する
        Button button = findViewById(R.id.activity_2_button);
        button.setOnClickListener((v -> {
            // アクティビティを起動する
            Intent intent = new Intent(this, TrainingSubActivity.class);
            startActivity(intent);
        }));

6 . TrainingSubActivityのボタン押下時に、SubActivityを終了する処理を追加する

        Button button = findViewById(R.id.activity_2_button_sub);
        button.setOnClickListener(v -> {
            // このActivityを終了させる
            finish();
        });

Code

Activity 2 · atuyan39/AndroidTraining@947a89c · GitHub

Reference

とくになし

Memo

startActivityの仕組みを理解したい

【AndroidTraining】Actvitiy 1

Lesson

Activity 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • Activityのライフサイクルのログを出力する

Snap Shot

◆アプリ起動
2021-04-11 00:40:05.876 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onCreate
2021-04-11 00:40:05.901 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStart
2021-04-11 00:40:05.901 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onPostCreate
2021-04-11 00:40:05.902 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResume
2021-04-11 00:40:05.902 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResumeFragments

◆アプリをバックグラウンドへ(Recentボタンを押下)
2021-04-11 00:40:10.481 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onPause
2021-04-11 00:40:10.939 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStop
2021-04-11 00:40:10.940 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onSaveInstanceState

◆再度アプリを表示
2021-04-11 00:40:13.330 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onRestart
2021-04-11 00:40:13.331 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStart
2021-04-11 00:40:13.332 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResume
2021-04-11 00:40:13.333 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onResumeFragments

◆アプリを閉じる
2021-04-11 00:40:24.006 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onPause
2021-04-11 00:40:24.500 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onStop
2021-04-11 00:40:24.501 26324-26324/com.hatenablog.atuyan39.androidtraining D/LifeCycle: onDestroy

Step by Step

  1. 新しくActivity(TrainingActivity.java)を追加する
  2. ライフサイクルのメソッドをoverrideする
    • onCreate
    • onRestart
    • onStart
    • onRestoreInstanceState
    • onPostCreate
    • onResume
    • onResumeFragments
    • onPause
    • onStop
    • onSaveInstanceState
    • onDestory
  3. ログを追加

Code

Activity 1 · atuyan39/AndroidTraining@d110e7f · GitHub

Reference

Activity

◆ライフサイクルについて
AndroidDeveloperにある詳細記事

developer.android.com

より細かいライフサイクルの部分も説明 www.atmarkit.co.jp

Memo

ライフサイクルはなんとなく使っているので、詳しく学びたい

【AndroidTraining】Switch 1

Lesson

Switch 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • Switchを二つを使い、論理演算(AND, OR, XOR, NAND)を表現する

Snap Shot

f:id:atuyan39:20210410000148p:plainf:id:atuyan39:20210410000154p:plainf:id:atuyan39:20210410000159p:plainf:id:atuyan39:20210410000205p:plain

Step by Step

1 . 新しくActivity(TrainingSwitchActivity.java)を追加する
2 . xmlに、SwitchのViewを追加する
3 . Viewを取得する
4 . Switchの変更通知を受けるリスナーを設定する

Switch toggleButtonA = findViewById(R.id.switch_1_switch_a);
        toggleButtonA.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // isCheckedからSwitchの状態がわかる
            }
        });

5 . 論理演算のメソッドを追加する
6 . 演算結果をSwitch(結果用)に設定する

    private void updateView(boolean a, boolean b) {
        mToggleButtonAnd.setChecked(and(a, b));
        mToggleButtonOr.setChecked(or(a, b));
        mToggleButtonXor.setChecked(xor(a, b));
        mToggleButtonNand.setChecked(nand(a, b));
    }

Code

Switch 1 · atuyan39/AndroidTraining@0080eb9 · GitHub

Reference

Switch

Switch  |  Android デベロッパー  |  Android Developers

Memo

View(xml)を作るのが大変

【AndroidTraining】CheckBox 1

Lesson

CheckBox 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • CheckBoxのチェックの変化をトーストで知らせる。

Snap Shot

f:id:atuyan39:20210409011552p:plainf:id:atuyan39:20210409011558p:plain

Step by Step

1 . 新しくActivity(TrainingCheckBoxActivity.java)を追加する。
2 . xmlに、CheckBoxのViewを追加する。
3 . Viewを取得する

        // Viewを取得
        CheckBox checkBox = findViewById(R.id.check_box_1);

4 . CheckBoxのクリックリスナーを設定する

        // checkBoxの変更の通知を受け取る
        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // 処理
            }
        });

5 . ToastにCheckboxの値(ON, OFF)を設定して、通知する

                // 三項演算子で一行にまとめると短くて済む
                // R.string.cb1_check_onをstringに変換する場合は、getString(id)
                String toastText = isChecked ? "チェックが付きました" : "チェックが外れました";
                Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_SHORT).show();

Code

CheckBox 1 · atuyan39/AndroidTraining@14a06ed · GitHub

Reference

CheckBox

developer.android.com

Memo

【AndroidTraining】SharedPreference 1

Lesson

SharedPreference 1

Mission

下記の仕様を満たすアプリを作りましょう。

  • ユーザーが入力した文字を保存し、画面に表示する

Snap Shot

◆確認手順

  1. 文字を入力(hello)
  2. Saveボタンを押下
  3. Displayボタンを押下
  4. 入力した文字が表示されること
  5. アプリを再起動する
  6. Displayボタンを押下
  7. 前回保存した文字が表示されること
f:id:atuyan39:20210408003557p:plainf:id:atuyan39:20210408003552p:plain

Step by Step

1 . 新しくActivity(TrainingSharedPreferenceActivity.java)を追加する
2 . xmlに、TextView, EditView, ButtonのViewを追加する
3 . Viewを取得する

        // Viewを取得
        TextView textView = findViewById(R.id.sp1_text_view);
        EditText editText = findViewById(R.id.sp1_edit_text);
        Button saveButton = findViewById(R.id.sp1_save_button);
        Button displayButton = findViewById(R.id.sp1_display_button);

4 . ボタンにクリックリスナーを設定する

        // Saveボタンクリック時の処理
        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                saveInputData(editText.getText().toString());
            }
        });

        // Displayボタンクリック時の処理
        displayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(getInputData());
            }
        });

5 . SharedPreferenceを操作する処理を実装する

    @NonNull
    private String getInputData() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        return sharedPreferences.getString(KEY_INPUT, "Nothing Input!");
    }

    private void saveInputData(@Nullable String text) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY_INPUT, text);
        editor.apply();
    }

※おまけ(SharedPreferenceの変更通知を受け取り、トースト表示する)

        // SharedPreferenceの更新時にToastを表示する
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                Toast.makeText(getApplicationContext(), "update!", Toast.LENGTH_SHORT).show();
            }
        });

Code

SharedPreference 1 · atuyan39/AndroidTraining@c9b52bd · GitHub

Reference

SharedPreference

とても丁寧でわかりやすい記事。 qiita.com

Android Developer

SharedPreferences  |  Android Developers

Memo

Preferenceの情報が格納されている場所
/data/data/<アプリのパッケージ名>/shared_prefs