LoginSignup
4
3

More than 3 years have passed since last update.

要素の高さがバラバラのRecyclerViewを使う(Pinterest的レイアウト)

Posted at

某有名画像サイトのように要素を表示したい!


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画像を表示するためにピカソ

build.gradle
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    implementation 'com.squareup.picasso:picasso:2.3.3'

ネットの画像を表示するためにインターネットパーミッション
マニフェストに追加

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />

activity_main.xml

先にレイアウトファイルから

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に注意

item.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="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

続いてアダプタ

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を実装しておわり

MainActivity.kt

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便利。
完成!!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3