KotlinでAndroidアプリ開発 3. Fragment/ListView
Author: 水卜
Author: 水卜
Activityが画面全体を遷移させるのに対し、fragmentは画面の一部を入れ替えるものと理解。Activityと同じようにxmlでUIを構築できる。
ListViewを使うとき、ArrayAdapterクラスでListViewのレイアウトやデータを渡す。
adapterを使うとき、第一引数にcontextを入れる。
contextとはActivityやApplicationのabstract class
fragmentからgetContext()すると、fragmentの呼び出し元であるActivityのcontextを返す。
Activityと違い、onCreateから呼び出そうとするとnull pointer exceptionになる。
onViewCreatedから呼ぶとうまくいく
private val texts = arrayOf("A", "B", "C")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = ArrayAdapter( context!!, android.R.layout.simple_list_item_1, this.texts)
this.careerInfoIndexList.adapter = adapter
}
onViewCreatedの中に以下のように書く
(activity as AppCompatActivity).supportActionBar?.title = "Sample"
list_item.xmlを定義する。RelativeLayoutがやりやすかった。
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:id="@+id/info_title"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"/>
<TextView
android:id="@+id/info_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/info_title"
android:layout_toStartOf="@id/btn_change"
android:layout_marginEnd="8dp"/>
<Button
android:text="@string/change_info"
android:layout_width="50dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:background="@drawable/btn_frame_style"
android:id="@+id/btn_change" android:textColor="@color/colorInfo"/>
</RelativeLayout>
今回はボタンのレイアウトも変えた。
drawable/btn_frame_style.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ffffff" />
<corners android:radius="2dp" />
<stroke
android:width="2dp"
android:color="@color/colorInfo" />
</shape>
これでUIパーツのレイアウトはできたのでコードを書いていく。
class InfoFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity).supportActionBar?.title = "情報"
val informationList = listOf(
Information("A", "", 0),
Information("B", "", 0),
Information("C", "", 0)
)
val adapter = InfoAdapter(context!!, informationList)
this.InfoIndexList.adapter = adapter
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_info, container, false)
}
}
data class Information(val title: String, val data: String, val formId: Int)
data class ViewHolder(val titleTextView: TextView, val dataTextView: TextView, val button: Button)
class InfoAdapter(context: Context, informationList: List<Information>) : ArrayAdapter<Information>(context,0, informationList) {
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
var view = convertView
var holder: ViewHolder
if (view == null) {
view = layoutInflater.inflate(R.layout.list_item, parent, false)
holder = ViewHolder(
view.info_title,
view.info_data,
view.btn_change
)
view.tag = holder
} else {
holder = view.tag as ViewHolder
}
val information = getItem(position) as Information
holder.titleTextView.text = information.title
holder.dataTextView.text = information.data
return view!!
}
}
対応するfragmentのレイアウトファイルにはListViewを適当に置いておく。
このときエラーが出ても大体インポートし忘れとかだったりする。