Androidでは、様々な部品オブジェクトが標準で用意されています。
メニューに関する部品もたくさんありますが、
本記事では、折り畳みできるリストビューのサンプルとなります。
これを利用すると、アコーディオンメニューとしても活用できます。
ぜひ、参考にしていただければと思います。
手順
大まかな手順としては、下記のようになります。
1.ListViewの配置
2.リストグループビューのレイアウトの作成
3.リストアイテムビューのレイアウトの作成
4.リストビューの設定
listgroup.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/listgroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:paddingTop="10dp" android:paddingBottom="10dp" android:text="グループ" android:textSize="20sp" app:layout_constraintStart_toStartOf="parent" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout> |
listitem.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/listitem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="50dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:text="アイテム" android:textSize="15sp" app:layout_constraintStart_toStartOf="parent" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout> |
リストビューの設定
対象のActivityに、リストビューを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
package com.hoge.ui.submenu import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.BaseExpandableListAdapter import android.widget.TextView import android.widget.Toast import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.navigation.Navigation import com.hoge.R import com.hoge.databinding.FragmentSubmenuBinding class SubmenuFragment : Fragment() { private lateinit var submenuViewModel: SubmenuViewModel private var _binding: FragmentSubmenuBinding? = null private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { submenuViewModel = ViewModelProvider(this).get(SubmenuViewModel::class.java) _binding = FragmentSubmenuBinding.inflate(inflater, container, false) val root: View = binding.root val group: MutableList<String> = ArrayList() group.add("グループA") group.add("グループB") group.add("グループC") //子要素のリスト追加 val item_group1: MutableList<String> = ArrayList() item_group1.add("グループA-1") item_group1.add("グループA-2") val item_group2: MutableList<String> = ArrayList() item_group2.add("グループB-1") item_group2.add("グループB-2") item_group2.add("グループB-3") val item_group3: MutableList<String> = ArrayList() item_group3.add("グループC-1") item_group3.add("グループC-2") item_group3.add("グループC-3") item_group3.add("グループC-4") val items: MutableList<List<String>> = ArrayList() items.add(item_group1) items.add(item_group2) items.add(item_group3) //ExpandableListViewの初期化 val adapter = CustomListAdapter(root.context, group, items) binding.lvMenu.setAdapter(adapter) binding.lvMenu.setOnChildClickListener { parent, v, groupPosition, childPosition, id -> val adapter1 = parent.expandableListAdapter as CustomListAdapter val groupname = adapter1.getGroup(groupPosition) as String val itemname = adapter1.getChild(groupPosition, childPosition) as String Toast.makeText( root.context, "$groupname : $itemname", Toast.LENGTH_LONG ).show() true } binding.lvMenu.expandGroup(0) return root } override fun onDestroyView() { super.onDestroyView() _binding = null } //ExpandableListViewのアダプター internal inner class CustomListAdapter( context: Context, _listGroup: List<String>, _listItem: List<List<String>> ) : BaseExpandableListAdapter() { var listGroup: List<String> var listItem: List<List<String>> var context: Context override fun getGroupCount(): Int { return listGroup.size } override fun getChildrenCount(groupPosition: Int): Int { return listItem[groupPosition].size } override fun getGroup(groupPosition: Int): Any { return listGroup[groupPosition] } override fun getChild(groupPosition: Int, childPosition: Int): Any { return listItem[groupPosition][childPosition] } override fun getGroupId(groupPosition: Int): Long { return 0 } override fun getChildId( groupPosition: Int, childPosition: Int ): Long { return 0 } override fun hasStableIds(): Boolean { return false } override fun getGroupView( groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup? ): View? { var convertView: View? = convertView if (convertView == null) { val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater convertView = inflater.inflate(R.layout.listgroup, parent, false) } val tv: TextView = convertView!!.findViewById<TextView>(R.id.listgroup) tv.text = listGroup[groupPosition] return convertView } override fun getChildView( groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup? ): View? { var convertView: View? = convertView if (convertView == null) { val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater convertView = inflater.inflate(R.layout.listitem, parent, false) } val tv: TextView = convertView!!.findViewById<TextView>(R.id.listitem) tv.text = listItem[groupPosition][childPosition] return convertView } override fun isChildSelectable( groupPosition: Int, childPosition: Int ): Boolean { return true } //コンストラクタ init { this.context = context this.listGroup = _listGroup this.listItem = _listItem } } } |
動作イメージ
初期表示
初期状態は、expandGroup のインデックスで調整可能です。