iOSのUICollectionView
のようなグリッドレイアウトをAndroidでどのように作るのか分からなかったので簡単にメモを👷♀️
結論
RecyclerView
を使って、グリッドレイアウトを構築できるようです。
ということで、早速使ってみます。
まずは、Fragment内にRecyclerView
を適当に配置します。
<androidx.recyclerview.widget.RecyclerView android:id="@+id/field_list" android:layout_width="0dp" android:layout_height="0dp" android:clipToPadding="false" android:paddingTop="12dp" android:paddingBottom="12dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
次に、グリッドレイアウトのアイテムのレイアウトを作ります。iOSでいうUICollectionViewCell
的な部分です。
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView 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:layout_width="match_parent" android:layout_height="wrap_content" app:cardBackgroundColor="@color/fideeOffWhite" app:cardCornerRadius="12dp"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/field_image" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="22dp" android:layout_marginTop="7dp" android:layout_marginEnd="22dp" app:layout_constraintDimensionRatio="h,1:1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_account" /> <TextView android:id="@+id/field_name_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="4dp" android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:ellipsize="middle" android:fontFamily="sans-serif-black" android:singleLine="true" android:text="琵琶湖" android:textAlignment="center" android:textColor="@color/fideeLightDark" android:textSize="16sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/field_image" /> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginStart="4dp" android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:layout_marginBottom="7dp" android:gravity="center" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/field_name_text"> <ImageView android:id="@+id/imageView4" android:layout_width="10dp" android:layout_height="10dp" android:layout_weight="1" app:srcCompat="@drawable/ic_location_pin" app:tint="@color/fideeSubTitle" /> <TextView android:id="@+id/field_prefecture_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginStart="2dp" android:fontFamily="sans-serif" android:gravity="center" android:text="TextView" android:textAlignment="center" android:textColor="@color/fideeSubTitle" android:textSize="12sp" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView>
次にRecyclerView
のAdapter
を作ります。iOSでいうところのUICollectionViewDataSource
です。
class FieldListAdapter(private val fields: List<FieldData>): RecyclerView.Adapter<FieldListAdapter.ViewHolder>() { class ViewHolder(view: View): RecyclerView.ViewHolder(view) { val fieldImage: ImageView = view.findViewById(R.id.field_image) val fieldName: TextView = view.findViewById(R.id.field_name_text) var fieldPrefecture: TextView = view.findViewById(R.id.field_prefecture_text) } override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.field_liste_item, viewGroup, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val field = fields[position] holder.fieldName.text = field.name holder.fieldPrefecture.text = field.prefectureName } override fun getItemCount(): Int { return fields.size } }
ちなみに、アイテムにバインドするデータは下記のFieldData
。
data class FieldData( val id: String = "", val name: String, val point: GeoPoint = GeoPoint(80.0, 150.0), val prefectureName: String = "", val imagePath: String = "", val categoryId: String = "" )
あとは、取得したRecyclerView
のインスタンスに先ほど作成したAdapter
とGridLayoutManager
を設定すれば完了です🎉 ちなみに、GridLayoutManager
の第二引数には列の数を、第三引数にはグリッドレイアウトの向きを、第四引数にはレイアウトを反転して表示するかどうかをそれぞれ設定します。
binding.fieldList.adapter = FieldListAdapter(listOf(FieldData(name = "琵琶湖"), FieldData(name = "霞ヶ浦"), FieldData(name = "相模湖")) binding.fieldList.layoutManager = GridLayoutManager(context, 3, RecyclerView.VERTICAL, false)
てな感じで本日も以上となります🍺