【Kotlin】Android RecyclerViewで選択したアイテムをハイライト表示する方法
Kotlinを使って、AndroidのRecyclerViewで選択したアイテムを適切にハイライト表示する方法を解説します。Selector DrawableとSparseBooleanArrayを組み合わせることで、タップ操作だけで項目の選択・解除を切り替えられる実装方法を、実際のコード例とともにステップごとに見ていきましょう。
完成イメージ
リストの項目をタップすると背景色が変化してハイライト表示され、もう一度タップすると元の状態に戻ります。サンプルデータにはサッカーの「バロンドール」受賞歴を使用しています。
ステップ1:新規プロジェクトの作成
Android Studioで新しいプロジェクトを作成します。メニューから「File」→「New Project」を選択し、必要な情報を入力してプロジェクトを作成してください。
ステップ2:activity_main.xmlの実装
res/layout/activity_main.xmlに以下のコードを追加します。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="8dp" />
</RelativeLayout>
ステップ3:MainActivity.ktの実装
src/MainActivity.ktに以下のコードを追加します。ここではRecyclerViewの初期化、LayoutManagerの設定、そしてアダプターへのデータ受け渡しを行っています。
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
recyclerView.addItemDecoration(SimpleItemDecoration(this))
val layoutManager = LinearLayoutManager(this@MainActivity)
recyclerView.layoutManager = layoutManager
val posts = returnListItems()
val adapter = RecyclerViewAdapter(this@MainActivity, posts)
recyclerView.adapter = adapter
}
private fun returnListItems(): List<ItemObject>? {
val items: MutableList<ItemObject> = ArrayList()
items.add(ItemObject("Ballon'd'or", "2007", "Ricardo KaKa"))
items.add(ItemObject("Ballon'd'or", "2008", "Cristiano Ronaldo"))
items.add(ItemObject("Ballon'd'or", "2009 - 2012, 2015", "Lionel Messi"))
items.add(ItemObject("Ballon'd'or", "2013, 2014, 2016, 2017", "Cristiano Ronaldo"))
items.add(ItemObject("Ballon'd'or", "2018", "Luca Modric"))
items.add(ItemObject("Ballon'd'or", "2019", "Lionel Messi"))
return items
}
}
ステップ4:Kotlinクラスファイルの作成
以下の4つのKotlinクラスファイルを作成し、それぞれ対応するコードを追加します。
ItemObject.kt
リスト1行分のデータを保持するデータクラスです。
internal class ItemObject(val awardTitle: String, val awardYear: String, val player: String) {
}
RecyclerViewAdapter.kt
リストの各行データをViewHolderにバインドするアダプタークラスです。
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.NonNull
import androidx.recyclerview.widget.RecyclerView
class RecyclerViewAdapter internal constructor(
context: MainActivity,
private val itemList: List<ItemObject>?
) : RecyclerView.Adapter<RecyclerViewHolders>() {
@NonNull
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolders {
val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.list_layout, null)
return RecyclerViewHolders(layoutView)
}
override fun onBindViewHolder(holder: RecyclerViewHolders, position: Int) {
holder.awardTitle.text = "Award Title: " + itemList!![position].awardTitle
holder.awardYear.text = "Award Year: " + itemList[position].awardYear
holder.player.text = "Player Name: " + itemList[position].player
}
override fun getItemCount(): Int {
return this.itemList!!.size
}
}
RecyclerViewHolders.kt
ここがハイライト表示の要となるクラスです。SparseBooleanArrayで項目ごとの選択状態を管理し、クリックのたびにview.isSelectedを切り替えます。このフラグの変化によって、後述のセレクターDrawableが自動的に切り替わる仕組みです。
import android.util.SparseBooleanArray
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
class RecyclerViewHolders(itemView: View) : ViewHolder(itemView),
View.OnClickListener {
var awardTitle: TextView
var awardYear: TextView
var player: TextView
private val selectedItems = SparseBooleanArray()
override fun onClick(view: View) {
if (selectedItems[adapterPosition, false]) {
selectedItems.delete(adapterPosition)
view.isSelected = false
}
else {
selectedItems.put(adapterPosition, true)
view.isSelected = true
}
}
init {
itemView.setOnClickListener(this)
awardTitle = itemView.findViewById(R.id.awardTitle)
awardYear = itemView.findViewById(R.id.awardYear)
player = itemView.findViewById(R.id.playerName)
}
}
SimpleItemDecoration.kt
リスト項目間に区切り線を描画するためのItemDecorationクラスです。
import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import androidx.annotation.NonNull
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
internal class SimpleItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private val drawable: Drawable = ContextCompat.getDrawable(context, R.drawable.line_divider)!!
override fun onDrawOver(
@NonNull canvas: Canvas,
parent: RecyclerView,
@NonNull state: RecyclerView.State
)
{
val left = parent.paddingLeft
val right = parent.width - parent.paddingRight
val childCount = parent.childCount
for (i in 0 until childCount) {
val child = parent.getChildAt(i)
val params = child.layoutParams as RecyclerView.LayoutParams
val top = child.bottom + params.bottomMargin
val bottom = top + drawable.intrinsicHeight
drawable.setBounds(left, top, right, bottom)
drawable.draw(canvas)
}
}
}
ステップ5:Drawableリソースファイルの作成
以下のDrawableリソースファイルを作成し、それぞれのコードを追加します。
background_selector.xml
選択状態(state_selected)に応じて背景色を切り替えるセレクターです。選択時はholo_green_light、未選択時はholo_purpleが適用されます。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="https://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/holo_green_light" android:state_pressed="false" android:state_selected="true" />
<item android:drawable="@android:color/holo_purple" android:state_selected="false" />
</selector>
line_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="https://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="2dp"
android:height="2dp" />
<solid android:color="@color/colorPrimaryDark" />
</shape>
ステップ6:list_layout.xmlの作成
レイアウトリソースファイル(list_layout.xml)を作成し、以下のコードを追加します。ルートレイアウトのbackground属性に、ステップ5で作成したセレクター(@drawable/background_selector)を指定するのがポイントです。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_selector"
android:padding="16dp">
<TextView
android:id="@+id/awardTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="New Text"
android:textColor="@android:color/background_dark"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/awardYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/awardTitle"
android:layout_alignStart="@+id/awardTitle"
android:layout_marginTop="20dp"
android:text="New Text"
android:textColor="@android:color/background_dark" />
<TextView
android:layout_marginBottom="10dp"
android:id="@+id/playerName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="New Text"
android:textColor="@android:color/background_dark" />
</RelativeLayout>
ステップ7:AndroidManifest.xmlの編集
androidManifest.xmlに以下のコードを追加します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.q11">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
アプリの実行と動作確認
それではアプリを実行してみましょう。実機のAndroidスマートフォンをPCに接続しているものとします。Android Studioからアプリを実行するには、プロジェクト内のいずれかのアクティビティファイルを開き、ツールバーの「Run」
アイコンをクリックします。候補として表示された自分のモバイルデバイスを選択すると、端末にアプリの初期画面が表示されます。


まとめ
RecyclerViewでの選択ハイライト表示は、「ViewのisSelectedフラグ」と「StateListDrawable(セレクター)」を組み合わせることでシンプルに実装できます。なお、より新しいRecyclerViewのバージョンではadapterPositionは非推奨となっているため、必要に応じてbindingAdapterPositionへの置き換えを検討してください。マルチ選択や単一選択など、要件に合わせてSparseBooleanArrayの管理方法をカスタマイズしてみてください。
-
Android RecyclerViewで選択したアイテムを適切にハイライト表示する方法【初心者向け完全ガイド】
はじめにこの記事では、Androidアプリ開発においてRecyclerViewで選択されたアイテムを適切に強調表示(ハイライト表示)する方法を、ステップごとのサンプルコード付きで詳しく解説します。リスト形式のUIは多くのアプリで使われており、ユーザーがどの項目を選んだかを視覚的に分かりやすくすることは、使いやすいアプリを作る上で非常に重要なポイントです。Step 1:新規プロジェクトの作成と依存関係の追加まずAndroid Studioで新しいプロジェクトを作成します。File → New Project を選択し、必要な情報を入力してプロジェクトを作成しましょう。次に、build.gradl
-
KotlinでAndroidアプリのGridViewスクロールを無効化する方法を徹底解説
この記事では、Kotlinを使ってAndroidアプリのGridView(グリッドビュー)のスクロール機能を無効にする方法を、サンプルコードとともにわかりやすく解説します。GridViewは画像ギャラリーやメニュー表示などによく使われるUIコンポーネントですが、状況によってはスクロールさせたくないケースもあります。そのような場合に役立つテクニックです。実装の手順ステップ1:新規プロジェクトを作成するまず、Android Studioで新しいプロジェクトを作成します。メニューから「File」→「New Project」を選択し、必要な項目をすべて入力してプロジェクトを作成してください。ステップ2