android

androidアプリ作成時のメモです。

1318 views

はじめに

GUIアプリケーションでは、設定画面を作ることがあると思います。
設定画面の基本的な操作は、テキストボックスや、チェックボックスなどに入力したあと、OKボタンを押すと、反映されるというのが基本的な操作かと思います。

ですが、アプリを使う立場に立つと、OKボタンを押し忘れて再設定したり、長い設定画面の一番下のOKボタンまで移動するなど、地味に面倒です。

そこで、今回は、テキストボックスや、チェックボタンの変更を監視し、変更されたら即座に設定を保存する、というサンプルプログラムを作ってみたいと思います。

やり方はいろいろあると思いますが、今回はjetpackのデータバインディング、LiveDataを使います。

gradleの設定

データバインディングを行う場合、build.gradleのandroid{...}に以下を追記します。

    dataBinding {
        enabled = true
    }

あと、「apply plugin: 'kotlin-android-extensions'」も追記する。

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"
    apply plugin: 'kotlin-android-extensions'

フラグメントを作成する

[New]→[Fragment]→[Fragment(with ViewModel)を選択してフラグメントを作成します。
今回はConfigFragmentという名前のフラグメントを作成します。

layoutフォルダの下にフラグメントのレイアウトファイルがあるので、それを編集してGUI画面を作成します。
今回は、スイッチボタンを配置してみます。

このスイッチが押しただけで、状態を保存できるようにします。OKボタンはありません。

ひとまず、フラグメントが作成できたら、同時にConfigViewModelというデータ管理クラスのファイルが作成されています。
このファイルを開き、編集します。

class ConfigViewModel : ViewModel() {
    // TODO: Implement the ViewModel
    val switch = MutableLiveData<Boolean>()
}

ここが一つ目の肝です。3行目のswitch変数は、スイッチがONの場合true、スイッチがOFFの場合falseになります。
このswitch変数にGUIでの操作が直接流れ込むようにします。
config_fragment.xmlを以下のように変更します。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="viewmodel"
            type="com.konishisoft.kenpin.ConfigViewModel" />
    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ConfigFragment">

        <Switch
            android:id="@+id/sample_switch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="@={viewmodel.switch}"
            android:text="スイッチ" />
    </FrameLayout>

</layout>

まず、データバインディングを使用するには、全体をlayoutタグで囲みます。
5行目~9行目にかけて、どのviewModelをバインドするかを記述します。
そして20行目で、チェックされた結果はviewmodelのswitch変数に流し込むように記述します。

android:checked="@={viewmodel.switch}"

このように記述すると、GUIの変更はビューモデルに、ビューモデルを変更したらGUIが勝手に変わるというように双方向でのやり取りができます。
以下のように=を省略すると、ビューモデルを変更したときにGUIが変更されますが、GUIを変更してもビューモデルの値は書き変わらない、一方通行のやり取りもできます。

android:checked="@{viewmodel.switch}"

ケースに応じて使い分けてください。

フラグメントの変更

フラグメントのコード内で、viewとviewモデルの関連付けを行います。

package com.konishisoft.kenpin

import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.Observer
import com.konishisoft.kenpin.databinding.ConfigFragmentBinding //ここがポイント1

class ConfigFragment : Fragment() {

    companion object {
        fun newInstance() = ConfigFragment()
    }

    private lateinit var viewModel: ConfigViewModel
    private lateinit var binding: ConfigFragmentBinding    //ポイント1のライブラリをインポートすると使える


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //ここも変更する
        binding = ConfigFragmentBinding.inflate(inflater, container, false)
        binding.viewmodel = viewModel   //ビューモデルをバインドする
        return binding.root //バインディングのrootを返す
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        // TODO: Use the ViewModel
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = ViewModelProvider(this).get(ConfigViewModel::class.java)

        val viewswitchObserver = Observer<Boolean>{//リスナー作成
            //スイッチを切り替えるたびに反応する
            Toast.makeText(context, "status:${it.toString()}", Toast.LENGTH_SHORT).show()
        }
        //リスナ―登録
        viewModel.switch.observe(this, viewswitchObserver)
    }

}

肝は、20行目。configFramentBindingですが、このクラスは自動生成されているクラスです。
layoutにconfig_fragment.xmlがあると思いますが、この名前をハンガリアン記法に変更してBindingに変更すればOKです。
インポートを自動でやってくれないときがあるので、そのときは、上記のポイント1を参考にimportしてください。

29行目でbindingのviewmodelとConfigViewModelを関連付けます。

最後、42行目~46行目でスイッチの監視を行うリスナーを作成します。
スイッチが変更されるたびに、トーストが表示されます。
そして、47行目で、viewmodelのswitch変数にリスナーを設定して終了です。

参考文献

この本を参考に作りました。
androidの中級者向けの本です。
jetpackについて、何ができるのかがまとまっているので、非常によかったです。

Android Jetpackプログラミング Android Studio 4 + Kotlin対応

Page 3 of 19.

前のページ 次のページ



[添付ファイル]


お問い合わせ

プロフィール

マッスル

自己紹介

本サイトの作成者。
趣味:プログラム/水耕栽培/仮想通貨/激辛好き
プログラムは趣味と勉強を兼ねて、のんびり本サイトを作っています。
フレームワークはdjango。
仮想通貨はNEMが好き。
水耕栽培は激辛好きが高じて、キャロライナ・リーパーの栽培にチャレンジ中。

サイト/ブログ

https://www.osumoi-stdio.com/pyarticle/

ツイッター

@darkimpact0626