androidアプリ作成時のメモです。
1590 views
GUIアプリケーションでは、設定画面を作ることがあると思います。
設定画面の基本的な操作は、テキストボックスや、チェックボックスなどに入力したあと、OKボタンを押すと、反映されるというのが基本的な操作かと思います。
ですが、アプリを使う立場に立つと、OKボタンを押し忘れて再設定したり、長い設定画面の一番下のOKボタンまで移動するなど、地味に面倒です。
そこで、今回は、テキストボックスや、チェックボタンの変更を監視し、変更されたら即座に設定を保存する、というサンプルプログラムを作ってみたいと思います。
やり方はいろいろあると思いますが、今回はjetpackのデータバインディング、LiveDataを使います。
データバインディングを行う場合、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。
ChatGPTで自動プログラム作成に取り組み中。
https://www.osumoi-stdio.com/novel/