#はじめに
既存のアプリをタブレット対応して下さいと言われた時にListを単純に横に伸ばしただけだと空白が広くなりすぎて見づらいとか、リスト上に文字が多く表示されてゴチャゴチャしたりとかあるかと思います。
スマホ用とタブレット用で別のlayoutを作成すれば良いのですが、どうにかして同じレイアウトで良い感じにならないかと考えた結果...
Grid表示とMaster/Detail Flowレイアウトを組み合わせたら結構いい感じになるんじゃないかと思ったので簡単なものを作ってみました
#つくったもの
Gridレイアウトの横に並ぶセルの数を画面の横幅に合わせて変えただけ。
#つくりかた
簡単に作る為に、Master/Detail Flowテンプレートでプロジェクトを作成
グリッド表示するのにCardViewを使用すると見た目が楽なので追加
dependencies {
//省略
implementation 'androidx.cardview:cardview:1.0.0'
}
リスト表示をCardViewに変更
<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:cardCornerRadius="6dp"
app:cardElevation="6dp"
app:cardUseCompatPadding="true"
app:contentPadding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/id_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
tools:text="no" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
tools:text="explain" />
</LinearLayout>
</androidx.cardview.widget.CardView>
/res/layout-w900dpにあるやつをlayout-w600dpにコピペしてRecyclerViewとFrameLayoutの横幅の表示をlayout_weightで1:3になるように変更
(layout-w900dpの方は1:2にになるように変更)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:baselineAligned="false"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".ItemListActivity"
android:weightSum="4">
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_list"
android:name="com.example.masterdetailsample.ItemListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context="com.example.masterdetailsample.ItemListActivity"
tools:listitem="@layout/item_list_content" />
<FrameLayout
android:id="@+id/item_detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
ItemListActivity.ktのsetupRecyclerViewのところにGridLayoutManagerでGrid表示するように設定し、spanCountを画面サイズによって変更するように追記
private fun setupRecyclerView(recyclerView: RecyclerView) {
recyclerView.adapter = SimpleItemRecyclerViewAdapter(this, DummyContent.ITEMS, twoPane)
val spanCount = getSpanCount()
recyclerView.layoutManager =
GridLayoutManager(this, spanCount, RecyclerView.VERTICAL, false)
}
private fun getSpanCount(): Int {
val dMetrics = DisplayMetrics()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
val display = this.display;
display?.getRealMetrics(dMetrics)
} else {
@Suppress("DEPRECATION")
window.windowManager.defaultDisplay.getRealMetrics(dMetrics)
}
var realWidth = dMetrics.widthPixels / dMetrics.density
return if ( realWidth >= 600 && realWidth < 900) 1 else 2
}
完成
gitHub:https://github.com/iKimishima/MasterDetailGridList.git
#まとめ
これでどんな画面サイズが来ても大丈夫!
と思ったけど今回はTempleteを使用したのでMaster/Detail Flowの設定が必要なかったが、既存アプリにMaster/Detail Flowを導入するときは大変だろうなと思った冬の夜。