目次
概要
基本的に、xmlファイルで設定したボタンといったUIは、Activityで使うことになる。
しかし、そうするのは個人的に嫌だ。なぜなら、画面表示と処理でファイルを分けたいからだ。
新しくファイルを生成する際、Activity(Frafment + ViewModel)というものがあるが、その形式で実装したい!
ソースコード
まずは全体を把握していただこう
AndroidManifest.xml
このファイルは直接修正することはしていない
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Test"
tools:targetApi="31">
<activity
android:name=".SubActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
このファイルも直接修正をすることはしていない
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
fragment_main.xml
ボタンと文字を表示するためのUIを設置している
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="@+id/pushedText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"/>
<Button
android:id="@+id/decideButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="決定" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.seeking_star.test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.seeking_star.test.ui.main.MainFragment
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
MainFragment.kt
package com.seeking_star.test.ui.main
import androidx.lifecycle.ViewModelProvider
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.RadioGroup
import android.widget.TextView
import com.seeking_star.test.R
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view = inflater.inflate(R.layout.fragment_main, container, false)
val textView = view.findViewById<TextView>(R.id.pushedText)
val decideButton = view.findViewById<Button>(R.id.decideButton)
decideButton.setOnClickListener {
textView.text = "ボタン押されたよ"
}
return view
}
}
MainViewModel.kt
package com.seeking_star.test.ui.main
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
// TODO: Implement the ViewModel
}
デモ動画
詳細
val view = inflater.inflate(R.layout.fragment_main, container, false)
今回の根幹となるのはこの部分だ。この一行でfragmentのxmlファイルのレイアウト情報を取得する。そのために必要なものはonCreateViewメソッドの引数である以下二つだ。
LayoutInflaterクラスのinflate(int resource, ViewGroup root, boolean attachToRoot)メソッドを使用する。
このメソッドは特定のxmlファイルからviewの情報を取得できる。
引数は以下のように設定する。
引数 | 内容 |
resource | xmlファイルのID |
root | 引っ張ってくるViewの親Viewのこと。 今回はonCreateViewメソッドのcontainerを使用する |
attachToRoot | falseにする。 詳しくはこちら。 |
こうすることでxmlファイルのViewの情報を格納できる。
これを元に、findViewByIdメソッドを使用してボタンなどのオブジェクトを生成できる。
これでMVVMモデルといった実装もできるだろう。