ラベル ListView の投稿を表示しています。 すべての投稿を表示
ラベル ListView の投稿を表示しています。 すべての投稿を表示

2024年11月4日月曜日

Android 追加読み込みListViewを実装する方法を解説

どうも。どっことです。今回はListViewに追加読み込みする機能を実装する方法について解説します。

追加読み込み機能を持つListView

またまた、いにしえのListViewに関する解説です。RecyclerViewはカスタマイズ性に長けていますが、「単に一覧で表示してくれればいい」程度であれば、シンプル実装できるListViewもまだまだ使い道のあるコンポーネントかと思います。今回はそんなListViewで、追加読み込みをする機能の実装について解説しようと思います。

追加読み込みListViewを実装する

実装手順は以下の通りです。

  1. 読み込み表示Viewを実装する
  2. 読み込み表示Viewを表示する
  3. 読み込み処理タイミングを検知する

順番に解説していきます。

読み込み表示Viewを実装する

まずは読み込み表示用のViewを実装します。一般的にはプログレスを表示する形かと思いますので、そのViewを用意しておきます。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp">

    <ProgressBar
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

読み込み表示Viewを表示する

次に読み込み表示用Viewの表示処理を実装します。ListViewにはFooterViewとしてViewを追加することができるので、ここに読み込み表示Viewを設定します。

listView.addFooterView(createFooterView())
fun createFooterView(): View {
    return layoutInflater.inflate(R.layout.view_progress, null)
}

読み込み処理タイミングを検知する

読み込み処理を実装します。OnScrollListener#onScrollを使って、スクロールが最下部に来た時を検知し、読み込み処理を実施します。

listView.setOnScrollListener(object : OnScrollListener {
    override fun onScrollStateChanged(view: AbsListView?, scrollState: Int) {
        // ここでは気にしない
    }
    override fun onScroll(view: AbsListView?, firstVisibleItem: Int,visibleItemCount: Int, totalItemCount: Int) {
        if (totalItemCount == firstVisibleItem + visibleItemCount) {
            // todo:すべての要素が表示されたので、追加読み込みを処理する
        }
    }
}

onScrollStateChangedが気になる人は、判定処理をあらかじめ実装したinterfaceを定義して、そちらを渡すような実装としても良いかもしれません。

interface OnBottomScrolledListener : OnScrollListener {
    /**
     * 最下部までスクロールされたことを検知
     **/
    fun onScrolledToBottom()

    override fun onScrollStateChanged(view: AbsListView?, scrollState: Int) {
        // ここでは気にしない
    }
    override fun onScroll(view: AbsListView?, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
        if (totalItemCount == firstVisibleItem + visibleItemCount) {
            onScrolledToBottom()
        }
    }
}
listView.setOnScrollListener(object : OnBottomScrolledListener {
    override fun onScrolledToBottom() {
        // 最下部までスクロールされたことを検知したので、追加読み込みする
    }
}

また「読み込んだ結果、追加分が0件だった」場合に再度読み込み処理が実施されないよう、フラグなどでの管理も入れておきます。

listView.setOnScrollListener(object : OnBottomScrolledListener {
    override fun onScrolledToBottom() {
        if (!isLoadNecessary) {
            // 何もせず終了
            // このタイミングで読み込み表示Viewも消しておきましょう
            listView.addFooterView(null)
            return
        }
        // 最下部までスクロールされたことを検知したので、追加読み込みする
    }
}

まとめ

今回は下スクロールしたら追加読み込みしてくれるListViewについて解説しました。前回の解説でもコメントしましたが、RecyclerViewの登場によりListViewはもはやいにしえのコンポーネントとなっていますが、やはり初期装備が揃ってくれているおかげで実装が簡単という点がAndroidエンジニア初心者には優しいですね。

参考

2024年6月3日月曜日

Android ListViewでコンテンツ一覧を表示する実装方法を解説

どうも。どっことです。今回はListViewでコンテンツ一覧を表示する実装方法について解説していきます。

ListViewを使ってコンテンツ一覧を表示する

RecyclerViewの登場によりもはや下火となったListViewですが、昔から開発が続いているアプリや、チームの技術力を加味した技術選定の結果、ListViewを使わざるを得ない状況も多かれ少なかれあると思います。今回は、そんないにしえのコンポーネントとなったListViewによるコンテンツの一覧を表示する方法について解説していきたいと思います。

実装方法

以下の流れで実装していきます。すでにRecyclerViewの記事(こちら)を見てくださっている方は、これとほぼ同じイメージで問題ありません。

  1. ListViewをレイアウトに配置
  2. ArrayAdapterを継承したCustomAdapterクラスを実装
  3. 表示要素を設定する
  4. ListViewCustomAdapterを繋ぎ込み
  5. その他

順番に解説していきます。

ListViewをレイアウトに配置

まずはListViewをレイアウトXMLに配置します。

<ListView
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

ArrayAdapterを継承したCustomAdapterクラスを実装

次にArrayAdapterを継承したCustomAdapterを実装します。表示する要素群をコンストラクタのvaluesとして、ArrayAdapterGenericsにその型を指定してあげてください。以下のサンプルは、Int型の要素群を渡しているので、ArrayAdapterGenericsIntを指定しています。

class CustomAdapter(context: Context, values: List<Int>) :
    ArrayAdapter<Int>(context, 0, values) {
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        TODO("このあと実装")
    }
}

表示要素を設定する

CustomAdapter内で表示要素を処理します。

レイアウトファイルの用意

まずは一覧として表示するために、レイアウトXMLを用意します。今回はファイル名をlist_view_item.xmlとしました。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

用意したレイアウトファイルでViewを生成、表示内容の当て込み

CustomAdapter#getViewメソッドをオーバーライドし、前項目で用意したレイアウトファイルを使ってViewを生成します。そしてそのViewに対して表示内容を設定していきます。

class CustomAdapter(context: Context, values: List<Int>) :
    ArrayAdapter<Int>(context, 0, values) {
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
          // convertViewがあれば(再利用されているViewである)それを、なければ前項目で用意したレイアウトを使ってViewを生成
        val view = convertView
            ?: LayoutInflater.from(parent.context).inflate(R.layout.list_view_item, parent, false)
          // View内に用意したTextViewに表示内容を当てこむ
        val textView: TextView = view.findViewById(R.id.text_view)
        val value = getItem(position)
        textView.text = value.toString()
        return view
    }
}

ListViewとCustomAdapterの繋ぎ込み

最後にListViewCustomAdapterを繋ぎ込みます。このときCustomAdapterのコンストラクタでは、表示要素のリストを渡しましょう。

val listView: ListView = findViewById(R.id.list_view)
listView.adapter = CustomAdapter(this, listOf(12, 23, 34, 45)) 

最終的に、実装した時のイメージは以下になります。

その他

区切り線

ListViewでは区切り線をデフォルトで表示してくれますが、不要であればListViewのパラメータとしてdivider="@null"を設定することで消すことができます。

<ListView
    android:id="@+id/list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null" />

タップ時の処理

ListViewではタップした時の処理を制御するためのリスナー(OnItemClickLister)も提供されています。

listView.setOnItemClickListener { parent, view, position, id ->
    // 要素がタップされた時の処理
}

高速スクローラ

スクロールバーをタッチすると、高速にスクロールできるタブを表示してくれる。

listView.setFastScrollEnabled(true);

まとめ

今回は、ListViewによるコンテンツ一覧の実装方法について解説しました。使う頻度はもう多くないかと思いますが、いざという時には躊躇わずに使えるようにしておきたいですね。

参考

移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。