某有名画像サイトのように要素を表示したい!
Pinterestアンドロイドアプリより
こういう高さがそれぞれの要素のwrapになってるやつをやってみたかった。
今回作るもの
少しわかりづらいがimageの高さに合わせて要素が積み重なっている。
画像はLolem Picsumのものを表示
結論
先に結論からいくと、RecyclerViewのレイアウトマネージャーをStaggeredGridLayoutManagerにするだけで出来る。
val layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)
recyclerView.adapter = adapter
recyclerView.layoutManager = layoutManager
LinearLayoutとかGridLayoutとかはよく使うけどStaggeredGridLayoutManagerはあんまり聞いたことないし、単語の意味も知らなかったから使ったことなかったが、実はすごく便利だった。(ちなみにstaggerは「よろめく」とかいう意味らしい)
引数
StaggeredGridLayoutManager(一行に表示する要素の数, recyclerViewの方向(縦向きか横向きか))
一応recyclerViewをあんまり使ったことのない方向けにrecyclerViewの実装コードも以下に掲載しておきます。
全コード
RecyclerViewを普通に実装していくだけなのでコードだけ載せます。解説等は他の方の記事にもたくさん載っていますので必要な方は探してみてください。
作るファイルは以下の通り
ファイル名 | 内容 |
---|---|
MainActivity.kt | recyclerViewの実装 |
Adapter.kt | recyclerViewのアダプタ |
activity_main.xml | recyclerViewを置くレイアウトファイル |
item.xml | recyclerViewの中身のレイアウトファイル |
依存関係とパーミッション
URL画像を表示するためにピカソ
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.squareup.picasso:picasso:2.3.3'
ネットの画像を表示するためにインターネットパーミッション
マニフェストに追加
<uses-permission android:name="android.permission.INTERNET" />
activity_main.xml
先にレイアウトファイルから
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
item.xml
ImageViewのところが赤く表示されるかもしれませんが今回のやつには関係ないので無視して大丈夫です。
ImageViewのheightはwrap_contentに注意
<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:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img"
android:layout_width="170dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_background" />
</androidx.constraintlayout.widget.ConstraintLayout>
Adapter.kt
続いてアダプタ
class Adapter(private val context: Context, private val urlList: ArrayList<String>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class ImgViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val img = view.img
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val item = inflater.inflate(R.layout.item, parent, false)
return ImgViewHolder(item)
}
override fun getItemCount(): Int {
return urlList.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Picassoを使ってURLの画像を読み込む
Picasso.with(context).load(urlList[position]).into(holder.itemView.img)
}
}
MainActivity.kt
最後にrecyclerViewを実装しておわり
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val urlList = arrayListOf<String>()
// Lolem Picsumの縦横ランダムな大きさの画像のURLを取得する
for(i in 0..17){
val index = (100..800).random()
val width = (250..600).random()
val height = (150..600).random()
urlList.add("https://i.picsum.photos/id/$index/$width/$height.jpg")
}
//アダプタとレイアウトマネージャーをセット
val adapter = Adapter(this, urlList)
val layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)
recyclerView.adapter = adapter
recyclerView.layoutManager = layoutManager
}
}
いやぁ、Lorem Picsum便利。
完成!!