2024年6月30日日曜日

Android FlexboxLayoutの使い方を解説

どうも。どっことです。今回はFlexboxLayoutの使い方を解説します。

FlexboxLayoutを使う

タグやキーワードの一覧などに、Webサイトの見せ方の一つとして利用されている表示方法ですが、AndroidでもFlexboxLayoutというViewGroupで同様の表示が提供されています。今回はこちらのコンポーネントの使い方について解説します。

FlexboxLayoutを使ったレイアウトの実装方法

以下の順で利用方法について解説します。

  • ライブラリを追加する。
  • FlexboxLayoutをレイアウトとして利用する。
  • 表示確認

ライブラリを追加する

ライブラリを追加します。build.gradledependenciesに以下を追加します。

dependencies {
  implementation 'com.google.android.flexbox:flexbox:3.0.0'
}

FlexboxLayoutをレイアウトとして利用する

FlexboxLayoutをレイアウトとして利用します。LinearLayoutやConstraintLayoutと同様に、レイアウト内に組み込みます。

<com.google.android.flexbox.FlexboxLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:flexWrap="wrap">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="テキスト1"
        android:padding="16dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="テキスト2 少し長め"
        android:padding="16dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="テキスト3"
        android:padding="16dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="テキスト4 長くなったら折り返される"
        android:padding="16dp" />
            
</com.google.android.flexbox.FlexboxLayout>

このときFlexboxLayoutの属性にはapp:flexWrap="wrap"を設定してください。このとき、appのnamespaceが定義されていないせいで赤文字表示される場合はnamespace定義を追加してください。(ctrl + Enter で大体解決してくれる)

表示確認

上記で実装すると、以下のように表示されます。

長いテキストが設定されているTextViewが折り返された位置で表示されているのが見てわかると思います。

まとめ

今回はFlexboxLayoutの使い方について解説しました。

参考

2024年6月29日土曜日

Android RecyclerView コンテンツをドラッグ&ドロップする実装を解説

どうも。どっことです。今回はRecyclerViewを使ったコンテンツのドラッグ&ドロップの実装方法について解説します。

ドラッグ&ドロップ機能を持ったRecyclerView

RecyclerViewの一番の利点は、拡張性に富んでいることだと思います。RecyclerViewが登場する以前では、ListViewがシンプルにコンテンツ一覧を表示する機能を担っていました。実装難易度もそこまで高くなく、単に一覧表示をさせるものであれば、今でもこれで十分です。しかし、より便利に、より良いUXを提供することを考えるとListViewではもうまかないきれないです。RecyclerViewは、拡張しやすいコンポーネントとして出てきたもので、今回のような機能はまさにRecyclerViewが活きるパターンの一つだといえます。

RecyclerViewにドラッグ&ドロップを実装する

それでは実装手順を解説します。

  1. ItemTouchHelperインスタンスを実装する。
  2. ItemTouchHelperRecyclerViewにアタッチする。

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

ItemTouchHelperインスタンスを実装する

まずはItemTouchHelperを実装します。

ItemTouchHelperは、今回のドラッグ&ドロップをはじめとするユーザ操作を司るヘルパークラスとなっています。今回のドラッグ&ドロップでは、SimpleCallBack#onMove,SimpleCallBack#onMoved, SimpleCallBack#isLongPressDragEnabledのコールバックに追加実装が必要となってきます。

早速サンプルを載せます。

ItemTouchHelper(object : SimpleCallback(UP or DOWN, 0) {
    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        // 特定のコンテンツがドラッグされようとしている 
        val fromPosition = viewHolder.adapterPosition
        val toPosition = target.adapterPosition
        recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
        // ドラッグしてOKなら true を, NGなら false を返す
        return true
    }

    override fun isLongPressDragEnabled(): Boolean {
        // 長押しされた。ドラッグ&ドロップを有効にする
        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        // 呼ばれない
    }

    override fun onMoved(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        fromPos: Int,
        target: RecyclerView.ViewHolder,
        toPos: Int,
        x: Int,
        y: Int
    ) {
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
        // コンテンツがドラッグ&ドロップされた。
    }
})

まずSimpleCallBack#isLongPressDragEnabledでは、ユーザがコンテンツを長押しした時にドラッグ&ドロップを開始するかどうかを返します。trueなら開始する、falseならしないということになります。今回は簡単のため、trueを返すようにしています。

onMoveコールバックでは、ユーザのドラッグによりコンテンツをドラッグさせても問題ないかをチェックします。同じRecyclerView内に複数の種類のコンテンツが表示されている場合=並び替えをさせたくない場合はここでfalseを返すことで、そのドラッグ&ドロップを無効にすることができます。

そしてonMovedコールバックは、実際にコンテンツのドラッグ&ドロップが行われたタイミングでここの処理が呼び出されます。このタイミングで、コンテンツの要素を渡された引数の内容をもとに更新してあげるのがよいでしょう。

ItemTouchHelperをRecyclerViewにアタッチする

あとは実装したItemTouchHelperRecyclerViewにアタッチするだけです。Activity#onCreatedFragment#onViewCreatedあたりで以下を読んであげれば問題ありません。

itemTouchHelper.attachToRecyclerView(recyclerView)

まとめ

今回はRecyclerViewを使ったコンテンツのドラッグ&ドロップの実装方法について解説しました。RecyclerViewは拡張性が高く、今回以外の拡張も豊富に取り揃えているので、今後もテーマにしていきたいと思います。

参考

2024年6月23日日曜日

Android RecyclerViewを使ったコンテンツ一覧の実装方法を解説 その2

どうも。どっことです。今回はRecyclerViewをより実用的に利用する場合の実装方法について解説します。

RecyclerViewでのコンテンツ一覧のカスタマイズ

前回の解説では、RecyclerViewの必要最低限の実装について解説しました。しかしこれだけでは実用性に欠いており、より実用に近いケースが必要なことを課題として挙げていました。

今回は前回に挙げた課題、つまり以下の内容を解説していきたいと思います。

  • 表示要素を動的にする。
    • データベースやAPIから取得した情報を一覧に表示するようなケースを解説します。
  • クリックしたらその要素に対応する画面を表示したい。(クリックリスナーの制御)
    • RecyclerViewで表示しているコンテンツに対応するページに遷移させる実装を解説します。

それぞれ解説します。

RecyclerViewの表示要素を動的に制御する

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

  1. CustomAdapterのコンストラクタに表示要素のリストを追加する。
  2. getCount()メソッドを修正する。
  3. 表示要素の配列を使ってonBindViewHolder()でViewをカスタマイズする。

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

CustomAdapterのコンストラクタに表示要素のリストを追加する

CustomAdapterに、表示要素を管理するリストを渡します。今回はToDoリストを意識して以下のTodoクラスをあらかじめ用意します。

data class Todo(val id: Int, val title: String)

このデータのリストをCustomAdapterのコンストラクタで渡します。

class CustomAdapter(private val list: List<Todo>) : RecyclerView.Adapter<ViewHolder>()

getCount()メソッドを修正する

表示要素の数を設定します。表示要素は前項のリストの要素数と同じになるはずです。

override fun getItemCount(): Int {
    return list.size
}

表示要素の配列を使ってonBindViewHolder()でViewをカスタマイズする

ViewHolderに表示要素を反映していきます。onBindViewHolderでは表示要素の位置がパラメータとして参照できるのでそれを使って表示要素にアクセスします。

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    if (holder is CustomViewHolder) {
        val todo = list[position]
        holder.textView.text = todo.title
    }
}

クリックしたらその要素に対応する画面を表示する

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

  1. タップ時のインターフェースを用意する。
  2. Viewがタップされた時の処理を追加する。
  3. CustomAdapter内でViewがタップされた時の処理を設定する。

こちらも順に解説します。

タップ時のインターフェースを用意する

Viewがタップされた時に、ActivityFragmentに必要な情報を渡すためのインターフェースを実装します。Todoクラスのデータを渡すように定義します。

interface ToDoClickListener {
    fun onClickToDo(todo: Todo)
}

このインターフェースをCustomAdapterのコンストラクタに追加します。

class CustomAdapter(
    private val list: List<Todo>,
    private val listener: ToDoClickListener
) : RecyclerView.Adapter<ViewHolder>() {

Viewがタップされた時の処理を追加する

Viewがタップされた時の実装をします。Todoデータへのアクセスが必要なので、この処理もonBindViewHolderに実装するとハマることなく実装できます。


override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    if (holder is CustomViewHolder) {
        val todo = list[position]
        holder.textView.text = todo.title
        holder.itemView.setOnClickListener {
            listener.onClickToDo(todo) // 要素がタップされたら、それに対応するTodoデータを渡す
        }
    }
}

CustomAdapter内でViewがタップされた時の処理を設定する

Viewがタップされた時に、インターフェースから渡された情報を使って必要な処理をするよう実装します。例えば、渡されたTodoデータを渡す形で、詳細画面に実装するなどでしょうか。インターフェースの実装はActivityFragmentに実装しても良いですし、実装した無名オブジェクトを渡しても問題ありません。今回は無名オブジェクトを渡します。


val adapter = CustomAdapter(listOf(
    Todo(0, "買い物"),
    Todo(1, "掃除"),
    Todo(2, "洗濯")
), object : ToDoClickListener {
    override fun onClickToDo(todo: Todo) {
        // 画面に反映、画面遷移など必要な処理を実装する
    }
})

まとめ

今回はRecyclerViewをより実用的に利用する場合の実装方法について解説しました。RecyclerViewによるコンテンツ表示はカスタマイズ性が高く、さまざまな利用パターンに当てはめられるので、今後もRecyclerViewによるコンテンツ表示について解説していきます。

2024年6月22日土曜日

Android 通知領域に通知を表示する方法を解説

どうも。どっことです。今回は、通知を実際に表示する実装方法を解説します。

通知領域に通知を表示する

通知チャンネルも実装できて、いよいよ通知を表示する方法まで来ました。さっそく実装方法を解説していきます。

通知を表示する実装の流れ

  • AndroidManifest.xmlにパーミッションの追加
  • 通知の表示の許諾確認
    • 拒否された時はさらに確認
  • 通知の表示処理

AndroidManifest.xmlにパーミッションの追加

まずはAndroidManifest.xmlに今回の通知表示に必要となるpermission.POST_NOTIFICATIONSの権限を追加します。このpermission.POST_NOTIFICATIONSが実装時に忘れやすいので、実装時にはぜひ備忘録としてご確認いただけると嬉しいです。

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

通知の表示の権限許諾確認

権限許諾ですが、実装方法は通常のパーミッションチェックと同様です。つまりregisterForActivityResultを使ってlauncherを生成し、Manifest.permission.POST_NOTIFICATIONSの許諾確認をします。このManifest.permission.POST_NOTIFICATIONSも実装時に忘れやすいので、ぜひ参考にしてください。

private val launcher = registerForActivityResult(
  ActivityResultContracts.RequestPermission()
) { 
  /** 許諾ダイアログが閉じられた。何かやりたいことがあればここに実装。*/ 
}

...

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    TODO("あとで追加実装")
    launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
}

拒否された時の再許諾確認

権限を確認したにもかかわらず拒否されてしまった場合ですが、一般的には次回などで「この権限がXXXという理由で必要なんだ」という権限を必要としている理由を説明した上で再度権限を確認する流れとなります。前項のTODO("あとで追加実装")に追記していきます。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
        // 権限を許諾してもらっている。後続処理に流さないでOK
        return
    }
    val shouldShow = shouldShowRequestPermissionRationale(
        Manifest.permission.POST_NOTIFICATIONS
    )
    if (shouldShow) {
        // 過去に許諾確認したけど、許可してくれなかった人。
        // ダイアログなどで権限を必要としている理由を説明した上で再度依頼する。
    } else {
        // それ以外。初回のケース、または「もう表示しない」設定としたケース。
        launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
    }
}

通知の表示処理

そしてManifest.permission.POST_NOTIFICATIONSの許諾を確認をした上で、問題なければNotificationを表示するようNotificationManagerに依頼します

if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
    val notification = Notification.Builder(this, "id")
        .setContentTitle("this is title")
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentText("this is text")
        .build()
    NotificationManagerCompat.from(this)
        .notify(null, 0, notification)
}

実際にうまく動作していれば、上記の場合以下のような通知が通知領域に表示されます。

まとめ

今回は通知領域に通知を表示する方法を解説しました。実装はそんなに複雑ではないものの、参照すべき定数を毎回忘れてしまいがちなので、ぜひ参考にしていただけると嬉しいです。

2024年6月17日月曜日

Android 通知チャンネルを作成する方法を解説

どうも。どっことです。今回は通知チャンネルを作成するための実装方法について解説します。

通知チャンネルを作成する方法

Android 8(Oreo)から 通知領域に通知を表示するためには、その通知に対応する通知チャンネルをあらかじめ作成しておかなければならなくなりました。

以前の記事で「作成した通知チャンネルの設定画面に遷移する」実装方法を解説しましたが、そもそも通知チャンネルの追加方法を解説していなかったので、今回はこちらをテーマに解説していこうと思います。

通知チャンネルの作成

通知チャンネルは以下の手順で作成します。

  1. NotificationManagerのインスタンスを取得
  2. 通知チャンネルインスタンスを生成
  3. NotificationManagerに通知チャンネルの作成を依頼

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

NotificationManagerのインスタンスを取得

まずはNotificationManagerのインスタンスを取得します。androidxではNotifcationManagerCompatというクラスが提供されており、今まではAndroidのバージョンがO未満かどうかで制御をする必要がありましたが、このクラスが提供されたことによりAndroidのバージョンを気にせず制御することができるようになりました。

呼び出し方も単純で、以下でOKです。

val manager = NotificationManagerCompat.from(this)

通知チャンネルインスタンスを生成

次に実際に作成する通知チャンネルのインスタンスを生成します。最小の構成では、ID、Importanceとタイトルさえあれば作成できるはずです。

val channel = NotificationChannelCompat.Builder("id", NotificationManagerCompat.IMPORTANCE_DEFAULT)
    .setName("ChannelName")
    .setDescription("ChannelDescription")
    .build()

実装するとき一番よく忘れるのが、Importanceです。定数はNotificationManagerCompatで定義されていますので、そちらを参照してください。以下が定義されています。

  • NotificationManagerCompat.IMPORTANCE_MAX
  • NotificationManagerCompat.IMPORTANCE_HIGH
  • NotificationManagerCompat.IMPORTANCE_DEFAULT
  • NotificationManagerCompat.IMPORTANCE_LOW
  • NotificationManagerCompat.IMPORTANCE_MIN
  • NotificationManagerCompat.IMPORTANCE_NONE
  • NotificationManagerCompat.IMPORTANCE_UNSPECIFIED

NotificationManagerに通知チャンネルの作成を依頼

最後に生成した通知チャンネルのインスタンスをNotificationManager#createNotificationChannel()で渡して、通知チャンネルの作成を依頼します。

manager.createNotificationChannel(channel)

まとめ

今回は通知チャンネルの作成手順を解説しました。Androidの通知に関する処理は、最新のバージョンになるに連れて必要な実装が増えていくのが辛いところですが、素敵なアプリには必要不可欠な要素の一つだと思いますので、是非ともマスターしたいところですね。

おまけ:通知チャンネルの削除を依頼する

作るのと同じで、NotificationManager#deleteNotificationChannel(id)を呼ぶことで、通知チャンネルの削除依頼することができます。

manager.deleteNotificationChannel(channel)

参考

2024年6月12日水曜日

Mac SourceTreeで間違えたパスワードを記憶してしまったときの解消方法を解説

どうも。どっことです。今回はMacを使っていると時々やってしまう間違えたパスワードの解消方法について解説します。

パスワードを間違えて入力してしまった!そんなとき

最近はPCがID/パスワードをいい感じに記憶してくれるので、とても便利になりました。ただ、そんなPCが間違えたID/パスワードを記憶してしまうと、それを使ってログインやアクセスを自動で試みて、結局失敗してエラーが出て終了。「何かよくわからないけど勝手にアクセスして、勝手に失敗して、エラー吐いて、終わった。だったら最初から聞いてくれ...」状態になります。

エンジニアの方で特によくあるのはSourceTreeだと思います。SourceTreeGithubなどで管理しているGitリポジトリにアクセスするためのクライアントソフトですが、悲しいことに一度パスワードを記憶するとSourceTree側からパスワードを再入力する導線が表示されなくなります。そのためパスワードを間違えて記憶してしまうと「パスワード間違えたのはわかっているから解消させてくれ...」ということになります。ということで今回は、SourceTreeを例とした上記問題の解消方法について解説していきたいと思います。

解消手順

手順は以下の通りです。

  1. キーチェーンアクセスを表示する。
  2. SourceTreeで認証情報を検索する。
  3. 表示された認証情報を削除する。
  4. SourceTreeで再度認証情報を入力する。

順番に解説します。

キーチェーンアクセスを表示する

キーチェーンアクセスを起動します。 Command + Spaceでspotlight検索を表示し、キーチェーンアクセスを表示します。

SourceTreeで認証情報を検索する

キーチェーンアクセスではそのマシンの認証情報をすべて管理しています。検索窓にSourceTreeを入力し、該当の認証情報を探しましょう。

表示された認証情報を削除する

認証情報が見つかったら、右クリックして認証情報を削除しましょう。

SourceTreeで再度認証情報を入力する

ここまでの手順により、マシンからSourceTreeで入力された認証情報が削除されるので、再度SourceTreeから認証情報を入力すれば、正しい認証情報を記憶させることができます。

まとめ

今回はSourceTreeをはじめとした誤った認証情報の解消方法について解説しました。ID/パスワードだけでなく、例えばアクセストークンといった認証情報などもキーチェーンアクセスで管理されているので、今回の内容を参考に解消していただければ嬉しいです。

参考

2024年6月11日火曜日

Android ディスプレイがスリープされるのを無効にする方法を解説

どうも。どっことです。今回は、ディスプレイスリープを無効にする実装方法を解説します。

ディスプレイスリープを無効に設定する

動画の再生中やドキュメントの表示中、タイマー表示中などの画面を常に表示しておきたいケースでディスプレイがスリープしてしまうのは避けたいと思います。アプリ側でディスプレイがスリープしてしまうことを無効にする設定があるので、今回はこちらを解説したいと思います。ただし、スリープを無効にすることは電力消費の観点から必要最低限の範囲で設定することを心がけましょう。

スリープを無効に設定する

スリープを無効にするためにはActivityから参照できるwindowインスタンスに対して、FLAG_KEEP_SCREEN_ONのフラグを設定します。

window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

スリープ無効設定をクリアする

スリープ無効設定をクリアするためには、windowインスタンスに対して、FLAG_KEEP_SCREEN_ONのフラグをクリアしてあげます。

window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

まとめ

今回はディスプレイがスリープされる設定を無効にする実装方法を解説しました。使い所が限られる機能ですが、動画再生などディスプレイをスリープさせたくないような利用方法をアプリに提供する場合、必要な実装になりますので参考にしていただけると幸いです。

参考

2024年6月8日土曜日

Excel(Windows10) Excelではショートカットを設定できる!

どうも。どっことです。今回は、Excelでショートカットキーの設定方法を紹介します。

Excelにショートカットキーを設定する

業務・プライベートに限らず何かとお世話になるExcelですが、なんと自分の好きなコマンドにショートカットを設定することができます。いろいろ機能があるExcelですが、ショートカットでさらに作業の効率化を図ることができるので、ぜひ設定しておきましょう。

設定手順

手順は以下の通りです。

  1. エクセルのオプションを表示する。
  2. クイックアクセスツールバーを選択する。
  3. コマンドの選択から、自分が追加したいコマンドを選択し追加ボタンをクリックします。
  4. 設定がすべてできたら、完了ボタンをクリックします。

設定完了後のショートカットキー

上記で設定が完了します。これにより、クイックアクセスツールバーに追加したコマンドが表示されているかと思いますが、これの左からの位置Altがショートカットキーに対応しています。例えば、一番左の位置にあれば1+Altで対応するコマンドを実行できる。という具合です。

参考

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/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。