diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index 44d002016..b222344c3 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -8,11 +8,9 @@ import android.content.DialogInterface
 import android.content.Intent
 import android.graphics.Rect
 import android.os.Bundle
-import android.view.LayoutInflater
 import android.view.MotionEvent
 import android.view.View
 import android.view.WindowManager
-import android.widget.TextView
 import androidx.activity.OnBackPressedCallback
 import androidx.annotation.IntDef
 import androidx.appcompat.app.AppCompatActivity
@@ -21,10 +19,10 @@ import androidx.fragment.app.FragmentActivity
 import androidx.fragment.app.FragmentManager
 import androidx.preference.PreferenceManager
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.google.android.material.slider.Slider
 import com.google.android.material.slider.Slider.OnChangeListener
 import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.DialogSliderBinding
 import org.yuzu.yuzu_emu.features.settings.model.Settings
 import org.yuzu.yuzu_emu.fragments.EmulationFragment
 import org.yuzu.yuzu_emu.fragments.MenuFragment
@@ -139,27 +137,22 @@ open class EmulationActivity : AppCompatActivity() {
     }
 
     private fun adjustScale() {
-        val inflater = LayoutInflater.from(this)
-        val view = inflater.inflate(R.layout.dialog_slider, null)
-        val slider = view.findViewById<Slider>(R.id.slider)
-        val textValue = view.findViewById<TextView>(R.id.text_value)
-        val units = view.findViewById<TextView>(R.id.text_units)
-
-        slider.valueTo = 150F
-        slider.value = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+        val sliderBinding = DialogSliderBinding.inflate(layoutInflater)
+        sliderBinding.slider.valueTo = 150F
+        sliderBinding.slider.value = PreferenceManager.getDefaultSharedPreferences(applicationContext)
             .getInt(Settings.PREF_CONTROL_SCALE, 50).toFloat()
-        slider.addOnChangeListener(OnChangeListener { _, value, _ ->
-            textValue.text = value.toString()
+        sliderBinding.slider.addOnChangeListener(OnChangeListener { _, value, _ ->
+            sliderBinding.textValue.text = value.toString()
             setControlScale(value.toInt())
         })
-        textValue.text = slider.value.toString()
-        units.text = "%"
+        sliderBinding.textValue.text = sliderBinding.slider.value.toString()
+        sliderBinding.textUnits.text = "%"
         MaterialAlertDialogBuilder(this)
             .setTitle(R.string.emulation_control_scale)
-            .setView(view)
+            .setView(sliderBinding.root)
             .setNegativeButton(android.R.string.cancel, null)
             .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
-                setControlScale(slider.value.toInt())
+                setControlScale(sliderBinding.slider.value.toInt())
             }
             .setNeutralButton(R.string.slider_default) { _: DialogInterface?, _: Int ->
                 setControlScale(50)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index 8891705a5..4114f3fdc 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -24,6 +24,8 @@ import kotlinx.coroutines.withContext
 import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
 import org.yuzu.yuzu_emu.activities.EmulationActivity.Companion.launch
+import org.yuzu.yuzu_emu.databinding.CardGameBinding
+import org.yuzu.yuzu_emu.model.Game
 import org.yuzu.yuzu_emu.model.GameDatabase
 import org.yuzu.yuzu_emu.utils.Log
 import org.yuzu.yuzu_emu.viewholders.GameViewHolder
@@ -51,25 +53,24 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameViewHolder {
         // Create a new view.
-        val gameCard = LayoutInflater.from(parent.context)
-            .inflate(R.layout.card_game, parent, false)
-        gameCard.setOnClickListener(this)
+        val binding = CardGameBinding.inflate(LayoutInflater.from(parent.context))
+        binding.root.setOnClickListener(this)
 
         // Use that view to create a ViewHolder.
-        return GameViewHolder(gameCard)
+        return GameViewHolder(binding)
     }
 
     override fun onBindViewHolder(holder: GameViewHolder, position: Int) {
         if (isDatasetValid) {
             if (cursor!!.moveToPosition(position)) {
-                holder.imageIcon.scaleType = ImageView.ScaleType.CENTER_CROP
+                holder.binding.imageGameScreen.scaleType = ImageView.ScaleType.CENTER_CROP
                 activity.lifecycleScope.launch {
                     withContext(Dispatchers.IO) {
                         val uri =
                             Uri.parse(cursor!!.getString(GameDatabase.GAME_COLUMN_PATH)).toString()
                         val bitmap = decodeGameIcon(uri)
                         withContext(Dispatchers.Main) {
-                            holder.imageIcon.load(bitmap) {
+                            holder.binding.imageGameScreen.load(bitmap) {
                                 error(R.drawable.no_icon)
                                 crossfade(true)
                             }
@@ -77,20 +78,23 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte
                     }
                 }
 
-                holder.textGameTitle.text =
+                holder.binding.textGameTitle.text =
                     cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE)
                         .replace("[\\t\\n\\r]+".toRegex(), " ")
-                holder.textGameCaption.text = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION)
+                holder.binding.textGameCaption.text = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION)
 
                 // TODO These shouldn't be necessary once the move to a DB-based model is complete.
-                holder.gameId = cursor!!.getString(GameDatabase.GAME_COLUMN_GAME_ID)
-                holder.path = cursor!!.getString(GameDatabase.GAME_COLUMN_PATH)
-                holder.title = cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE)
-                holder.description = cursor!!.getString(GameDatabase.GAME_COLUMN_DESCRIPTION)
-                holder.regions = cursor!!.getString(GameDatabase.GAME_COLUMN_REGIONS)
-                holder.company = cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION)
+                val game = Game(
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_TITLE),
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_DESCRIPTION),
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_REGIONS),
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_PATH),
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_GAME_ID),
+                    cursor!!.getString(GameDatabase.GAME_COLUMN_CAPTION)
+                )
+                holder.game = game
                 val backgroundColorId =
-                    if (isValidGame(holder.path!!)) R.attr.colorSurface else R.attr.colorErrorContainer
+                    if (isValidGame(holder.game.path)) R.attr.colorSurface else R.attr.colorErrorContainer
                 val itemView = holder.itemView
                 itemView.setBackgroundColor(
                     MaterialColors.getColor(
@@ -177,7 +181,7 @@ class GameAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapte
      */
     override fun onClick(view: View) {
         val holder = view.tag as GameViewHolder
-        launch((view.context as FragmentActivity), holder.path, holder.title)
+        launch((view.context as FragmentActivity), holder.game.path, holder.game.title)
     }
 
     private fun isValidGame(path: String): Boolean {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
index 1fa7b2e0b..fca2f2155 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
@@ -9,7 +9,6 @@ import android.content.IntentFilter
 import android.os.Bundle
 import android.view.Menu
 import android.view.View
-import android.widget.FrameLayout
 import android.widget.Toast
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
@@ -18,11 +17,11 @@ import androidx.core.view.WindowCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.updatePadding
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
-import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.google.android.material.progressindicator.LinearProgressIndicator
 import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
+import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
 import org.yuzu.yuzu_emu.features.settings.model.Settings
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsFragment.Companion.newInstance
 import org.yuzu.yuzu_emu.utils.*
@@ -31,11 +30,15 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
     private val presenter = SettingsActivityPresenter(this)
     private var dialog: AlertDialog? = null
 
+    private lateinit var binding: ActivitySettingsBinding
+
     override fun onCreate(savedInstanceState: Bundle?) {
         ThemeHelper.setTheme(this)
 
         super.onCreate(savedInstanceState)
-        setContentView(R.layout.activity_settings)
+
+        binding = ActivitySettingsBinding.inflate(layoutInflater)
+        setContentView(binding.root)
 
         WindowCompat.setDecorFitsSystemWindows(window, false)
 
@@ -45,7 +48,7 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
         presenter.onCreate(savedInstanceState, menuTag!!, gameID!!)
 
         // Show "Back" button in the action bar for navigation
-        setSupportActionBar(findViewById(R.id.toolbar_settings))
+        setSupportActionBar(binding.toolbarSettings)
         supportActionBar!!.setDisplayHomeAsUpEnabled(true)
 
         setInsets()
@@ -138,13 +141,12 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
 
     override fun showLoading() {
         if (dialog == null) {
-            val root = layoutInflater.inflate(R.layout.dialog_progress_bar, null)
-            val progressBar = root.findViewById<LinearProgressIndicator>(R.id.progress_bar)
-            progressBar.isIndeterminate = true
+            val loadingBinding = DialogProgressBarBinding.inflate(layoutInflater)
+            loadingBinding.progressBar.isIndeterminate = true
 
             dialog = MaterialAlertDialogBuilder(this)
                 .setTitle(R.string.load_settings)
-                .setView(root)
+                .setView(loadingBinding.root)
                 .setCancelable(false)
                 .create()
         }
@@ -195,12 +197,10 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
         get() = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as SettingsFragment?
 
     private fun setInsets() {
-        val appBar = findViewById<AppBarLayout>(R.id.appbar_settings)
-        val frame = findViewById<FrameLayout>(R.id.frame_content)
-        ViewCompat.setOnApplyWindowInsetsListener(frame) { view: View, windowInsets: WindowInsetsCompat ->
+        ViewCompat.setOnApplyWindowInsetsListener(binding.frameContent) { view: View, windowInsets: WindowInsetsCompat ->
             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
             view.updatePadding(left = insets.left, right = insets.right)
-            InsetsHelper.insetAppBar(insets, appBar)
+            InsetsHelper.insetAppBar(insets, binding.appbarSettings)
             windowInsets
         }
     }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
index 1b8a0a5ea..1f81f6e62 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
@@ -9,7 +9,6 @@ import android.icu.util.Calendar
 import android.icu.util.TimeZone
 import android.text.format.DateFormat
 import android.view.LayoutInflater
-import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
 import androidx.appcompat.app.AlertDialog
@@ -20,6 +19,10 @@ import com.google.android.material.slider.Slider
 import com.google.android.material.timepicker.MaterialTimePicker
 import com.google.android.material.timepicker.TimeFormat
 import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.DialogSliderBinding
+import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
+import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
+import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding
 import org.yuzu.yuzu_emu.features.settings.model.FloatSetting
 import org.yuzu.yuzu_emu.features.settings.model.view.*
 import org.yuzu.yuzu_emu.features.settings.ui.viewholder.*
@@ -43,37 +46,29 @@ class SettingsAdapter(
     }
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SettingViewHolder {
-        val view: View
         val inflater = LayoutInflater.from(parent.context)
         return when (viewType) {
             SettingsItem.TYPE_HEADER -> {
-                view = inflater.inflate(R.layout.list_item_settings_header, parent, false)
-                HeaderViewHolder(view, this)
+                HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
             }
-            SettingsItem.TYPE_CHECKBOX -> {
-                view = inflater.inflate(R.layout.list_item_setting_switch, parent, false)
-                SwitchSettingViewHolder(view, this)
+            SettingsItem.TYPE_SWITCH -> {
+                SwitchSettingViewHolder(ListItemSettingSwitchBinding.inflate(inflater), this)
             }
             SettingsItem.TYPE_SINGLE_CHOICE, SettingsItem.TYPE_STRING_SINGLE_CHOICE -> {
-                view = inflater.inflate(R.layout.list_item_setting, parent, false)
-                SingleChoiceViewHolder(view, this)
+                SingleChoiceViewHolder(ListItemSettingBinding.inflate(inflater), this)
             }
             SettingsItem.TYPE_SLIDER -> {
-                view = inflater.inflate(R.layout.list_item_setting, parent, false)
-                SliderViewHolder(view, this)
+                SliderViewHolder(ListItemSettingBinding.inflate(inflater), this)
             }
             SettingsItem.TYPE_SUBMENU -> {
-                view = inflater.inflate(R.layout.list_item_setting, parent, false)
-                SubmenuViewHolder(view, this)
+                SubmenuViewHolder(ListItemSettingBinding.inflate(inflater), this)
             }
             SettingsItem.TYPE_DATETIME_SETTING -> {
-                view = inflater.inflate(R.layout.list_item_setting, parent, false)
-                DateTimeViewHolder(view, this)
+                DateTimeViewHolder(ListItemSettingBinding.inflate(inflater), this)
             }
             else -> {
                 // TODO: Create an error view since we can't return null now
-                view = inflater.inflate(R.layout.list_item_settings_header, parent, false)
-                HeaderViewHolder(view, this)
+                HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
             }
         }
     }
@@ -191,15 +186,13 @@ class SettingsAdapter(
         sliderProgress = item.selectedValue
 
         val inflater = LayoutInflater.from(context)
-        val sliderLayout = inflater.inflate(R.layout.dialog_slider, null)
-        val sliderView = sliderLayout.findViewById<Slider>(R.id.slider)
+        val sliderBinding = DialogSliderBinding.inflate(inflater)
 
-        textSliderValue = sliderLayout.findViewById(R.id.text_value)
+        textSliderValue = sliderBinding.textValue
         textSliderValue!!.text = sliderProgress.toString()
-        val units = sliderLayout.findViewById<TextView>(R.id.text_units)
-        units.text = item.units
+        sliderBinding.textUnits.text = item.units
 
-        sliderView.apply {
+        sliderBinding.slider.apply {
             valueFrom = item.min.toFloat()
             valueTo = item.max.toFloat()
             value = sliderProgress.toFloat()
@@ -211,11 +204,11 @@ class SettingsAdapter(
 
         dialog = MaterialAlertDialogBuilder(context)
             .setTitle(item.nameId)
-            .setView(sliderLayout)
+            .setView(sliderBinding.root)
             .setPositiveButton(android.R.string.ok, this)
             .setNegativeButton(android.R.string.cancel, defaultCancelListener)
             .setNeutralButton(R.string.slider_default) { dialog: DialogInterface, which: Int ->
-                sliderView.value = item.defaultValue.toFloat()
+                sliderBinding.slider.value = item.defaultValue.toFloat()
                 onClick(dialog, which)
             }
             .show()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
index bef5b9705..e2e07ee8b 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
@@ -14,9 +14,8 @@ import androidx.core.view.updatePadding
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentActivity
 import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
 import com.google.android.material.divider.MaterialDividerItemDecoration
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
 import org.yuzu.yuzu_emu.features.settings.model.Setting
 import org.yuzu.yuzu_emu.features.settings.model.Settings
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
@@ -26,9 +25,10 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
 
     private val presenter = SettingsFragmentPresenter(this)
     private var activityView: SettingsActivityView? = null
-    private var adapter: SettingsAdapter? = null
+    private var settingsAdapter: SettingsAdapter? = null
 
-    private lateinit var recyclerView: RecyclerView
+    private var _binding: FragmentSettingsBinding? = null
+    private val binding get() = _binding!!
 
     override fun onAttach(context: Context) {
         super.onAttach(context)
@@ -41,7 +41,6 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
         super.onCreate(savedInstanceState)
         val menuTag = requireArguments().getString(ARGUMENT_MENU_TAG)
         val gameId = requireArguments().getString(ARGUMENT_GAME_ID)
-        adapter = SettingsAdapter(this, requireActivity())
         presenter.onCreate(menuTag!!, gameId!!)
     }
 
@@ -49,18 +48,20 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?
-    ): View? {
-        return inflater.inflate(R.layout.fragment_settings, container, false)
+    ): View {
+        _binding = FragmentSettingsBinding.inflate(layoutInflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        val manager = LinearLayoutManager(activity)
-        recyclerView = view.findViewById(R.id.list_settings)
-        recyclerView.adapter = adapter
-        recyclerView.layoutManager = manager
+        settingsAdapter = SettingsAdapter(this, requireActivity())
         val dividerDecoration = MaterialDividerItemDecoration(requireContext(), LinearLayoutManager.VERTICAL)
         dividerDecoration.isLastItemDecorated = false
-        recyclerView.addItemDecoration(dividerDecoration)
+        binding.listSettings.apply {
+            adapter = settingsAdapter
+            layoutManager = LinearLayoutManager(activity)
+            addItemDecoration(dividerDecoration)
+        }
         val activity = activity as SettingsActivityView?
         presenter.onViewCreated(activity!!.settings)
 
@@ -70,8 +71,8 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
     override fun onDetach() {
         super.onDetach()
         activityView = null
-        if (adapter != null) {
-            adapter!!.closeDialog()
+        if (settingsAdapter != null) {
+            settingsAdapter!!.closeDialog()
         }
     }
 
@@ -86,7 +87,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
     }
 
     override fun showSettingsList(settingsList: ArrayList<SettingsItem>) {
-        adapter!!.setSettings(settingsList)
+        settingsAdapter!!.setSettings(settingsList)
     }
 
     override fun loadDefaultSettings() {
@@ -114,7 +115,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
     }
 
     private fun setInsets() {
-        ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { view: View, windowInsets: WindowInsetsCompat ->
+        ViewCompat.setOnApplyWindowInsetsListener(binding.listSettings) { view: View, windowInsets: WindowInsetsCompat ->
             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
             view.updatePadding(bottom = insets.bottom)
             windowInsets
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt
index ddbeb3487..5702fc0eb 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt
@@ -4,31 +4,23 @@
 package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
-import android.widget.TextView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class DateTimeViewHolder(itemView: View, adapter: SettingsAdapter) :
-    SettingViewHolder(itemView, adapter) {
+class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
     private lateinit var item: DateTimeSetting
-    private lateinit var textSettingName: TextView
-    private lateinit var textSettingDescription: TextView
-
-    override fun findViews(root: View) {
-        textSettingName = root.findViewById(R.id.text_setting_name)
-        textSettingDescription = root.findViewById(R.id.text_setting_description)
-    }
 
     override fun bind(item: SettingsItem) {
         this.item = item as DateTimeSetting
-        textSettingName.setText(item.nameId)
+        binding.textSettingName.setText(item.nameId)
         if (item.descriptionId!! > 0) {
-            textSettingDescription.setText(item.descriptionId)
-            textSettingDescription.visibility = View.VISIBLE
+            binding.textSettingDescription.setText(item.descriptionId)
+            binding.textSettingDescription.visibility = View.VISIBLE
         } else {
-            textSettingDescription.visibility = View.GONE
+            binding.textSettingDescription.visibility = View.GONE
         }
     }
 
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/HeaderViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/HeaderViewHolder.kt
index dd186552a..1ac00dbfc 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/HeaderViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/HeaderViewHolder.kt
@@ -4,25 +4,19 @@
 package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
-import android.widget.TextView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class HeaderViewHolder(itemView: View, adapter: SettingsAdapter) :
-    SettingViewHolder(itemView, adapter) {
-    private lateinit var headerName: TextView
+class HeaderViewHolder(val binding: ListItemSettingsHeaderBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
 
     init {
         itemView.setOnClickListener(null)
     }
 
-    override fun findViews(root: View) {
-        headerName = root.findViewById(R.id.text_header_name)
-    }
-
     override fun bind(item: SettingsItem) {
-        headerName.setText(item.nameId)
+        binding.textHeaderName.setText(item.nameId)
     }
 
     override fun onClick(clicked: View) {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SettingViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SettingViewHolder.kt
index 6468af331..73375e757 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SettingViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SettingViewHolder.kt
@@ -13,16 +13,8 @@ abstract class SettingViewHolder(itemView: View, protected val adapter: Settings
 
     init {
         itemView.setOnClickListener(this)
-        findViews(itemView)
     }
 
-    /**
-     * Gets handles to all this ViewHolder's child views using their XML-defined identifiers.
-     *
-     * @param root The newly inflated top-level view.
-     */
-    protected abstract fun findViews(root: View)
-
     /**
      * Called by the adapter to set this ViewHolder's child views to display the list item
      * it must now represent.
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt
index f6c8e3a7d..a82f49f44 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SingleChoiceViewHolder.kt
@@ -4,40 +4,32 @@
 package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
-import android.widget.TextView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting
 import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class SingleChoiceViewHolder(itemView: View, adapter: SettingsAdapter) :
-    SettingViewHolder(itemView, adapter) {
+class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
     private lateinit var item: SettingsItem
-    private lateinit var textSettingName: TextView
-    private lateinit var textSettingDescription: TextView
-
-    override fun findViews(root: View) {
-        textSettingName = root.findViewById(R.id.text_setting_name)
-        textSettingDescription = root.findViewById(R.id.text_setting_description)
-    }
 
     override fun bind(item: SettingsItem) {
         this.item = item
-        textSettingName.setText(item.nameId)
-        textSettingDescription.visibility = View.VISIBLE
+        binding.textSettingName.setText(item.nameId)
+        binding.textSettingDescription.visibility = View.VISIBLE
         if (item.descriptionId!! > 0) {
-            textSettingDescription.setText(item.descriptionId)
+            binding.textSettingDescription.setText(item.descriptionId)
         } else if (item is SingleChoiceSetting) {
-            val resMgr = textSettingDescription.context.resources
+            val resMgr = binding.textSettingDescription.context.resources
             val values = resMgr.getIntArray(item.valuesId)
             for (i in values.indices) {
                 if (values[i] == item.selectedValue) {
-                    textSettingDescription.text = resMgr.getStringArray(item.choicesId)[i]
+                    binding.textSettingDescription.text = resMgr.getStringArray(item.choicesId)[i]
                 }
             }
         } else {
-            textSettingDescription.visibility = View.GONE
+            binding.textSettingDescription.visibility = View.GONE
         }
     }
 
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt
index 2213f3c16..2d9fd11f9 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SliderViewHolder.kt
@@ -4,30 +4,23 @@
 package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
-import android.widget.TextView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class SliderViewHolder(itemView: View, adapter: SettingsAdapter) : SettingViewHolder(itemView, adapter) {
+class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
     private lateinit var item: SliderSetting
-    private lateinit var textSettingName: TextView
-    private lateinit var textSettingDescription: TextView
-
-    override fun findViews(root: View) {
-        textSettingName = root.findViewById(R.id.text_setting_name)
-        textSettingDescription = root.findViewById(R.id.text_setting_description)
-    }
 
     override fun bind(item: SettingsItem) {
         this.item = item as SliderSetting
-        textSettingName.setText(item.nameId)
+        binding.textSettingName.setText(item.nameId)
         if (item.descriptionId!! > 0) {
-            textSettingDescription.setText(item.descriptionId)
-            textSettingDescription.visibility = View.VISIBLE
+            binding.textSettingDescription.setText(item.descriptionId)
+            binding.textSettingDescription.visibility = View.VISIBLE
         } else {
-            textSettingDescription.visibility = View.GONE
+            binding.textSettingDescription.visibility = View.GONE
         }
     }
 
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
index 75656215a..8125fd865 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
@@ -4,31 +4,23 @@
 package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
-import android.widget.TextView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class SubmenuViewHolder(itemView: View, adapter: SettingsAdapter) :
-    SettingViewHolder(itemView, adapter) {
+class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
     private lateinit var item: SubmenuSetting
-    private lateinit var textSettingName: TextView
-    private lateinit var textSettingDescription: TextView
-
-    override fun findViews(root: View) {
-        textSettingName = root.findViewById(R.id.text_setting_name)
-        textSettingDescription = root.findViewById(R.id.text_setting_description)
-    }
 
     override fun bind(item: SettingsItem) {
         this.item = item as SubmenuSetting
-        textSettingName.setText(item.nameId)
+        binding.textSettingName.setText(item.nameId)
         if (item.descriptionId!! > 0) {
-            textSettingDescription.setText(item.descriptionId)
-            textSettingDescription.visibility = View.VISIBLE
+            binding.textSettingDescription.setText(item.descriptionId)
+            binding.textSettingDescription.visibility = View.VISIBLE
         } else {
-            textSettingDescription.visibility = View.GONE
+            binding.textSettingDescription.visibility = View.GONE
         }
     }
 
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
index f8b229830..3fedb4969 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
@@ -5,43 +5,31 @@ package org.yuzu.yuzu_emu.features.settings.ui.viewholder
 
 import android.view.View
 import android.widget.CompoundButton
-import android.widget.TextView
-import com.google.android.material.materialswitch.MaterialSwitch
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
 import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting
 import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
 
-class SwitchSettingViewHolder(itemView: View, adapter: SettingsAdapter) :
-    SettingViewHolder(itemView, adapter) {
-    private lateinit var item: SwitchSetting
-    private lateinit var textSettingName: TextView
-    private lateinit var textSettingDescription: TextView
-    private lateinit var switch: MaterialSwitch
-
-    override fun findViews(root: View) {
-        textSettingName = root.findViewById(R.id.text_setting_name)
-        textSettingDescription = root.findViewById(R.id.text_setting_description)
-        switch = root.findViewById(R.id.switch_widget)
-    }
+class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) :
+    SettingViewHolder(binding.root, adapter) {
 
     override fun bind(item: SettingsItem) {
-        this.item = item as SwitchSetting
-        textSettingName.setText(item.nameId)
+        val setting = item as SwitchSetting
+        binding.textSettingName.setText(item.nameId)
         if (item.descriptionId!! > 0) {
-            textSettingDescription.setText(item.descriptionId)
-            textSettingDescription.visibility = View.VISIBLE
+            binding.textSettingDescription.setText(item.descriptionId)
+            binding.textSettingDescription.visibility = View.VISIBLE
         } else {
-            textSettingDescription.text = ""
-            textSettingDescription.visibility = View.GONE
+            binding.textSettingDescription.text = ""
+            binding.textSettingDescription.visibility = View.GONE
         }
-        switch.isChecked = this.item.isChecked
-        switch.setOnCheckedChangeListener { _: CompoundButton, _: Boolean ->
-            adapter.onBooleanClick(item, bindingAdapterPosition, switch.isChecked)
+        binding.switchWidget.isChecked = setting.isChecked
+        binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean ->
+            adapter.onBooleanClick(item, bindingAdapterPosition, binding.switchWidget.isChecked)
         }
     }
 
     override fun onClick(clicked: View) {
-        switch.toggle()
+        binding.switchWidget.toggle()
     }
 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index c75ad580e..37469302d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -10,8 +10,6 @@ import android.graphics.Color
 import android.os.Bundle
 import android.os.Handler
 import android.view.*
-import android.widget.Button
-import android.widget.TextView
 import android.widget.Toast
 import androidx.fragment.app.Fragment
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
@@ -20,8 +18,8 @@ import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
 import org.yuzu.yuzu_emu.YuzuApplication
 import org.yuzu.yuzu_emu.activities.EmulationActivity
+import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
 import org.yuzu.yuzu_emu.features.settings.model.Settings
-import org.yuzu.yuzu_emu.overlay.InputOverlay
 import org.yuzu.yuzu_emu.utils.DirectoryInitialization
 import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState
 import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver
@@ -29,13 +27,14 @@ import org.yuzu.yuzu_emu.utils.Log
 
 class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback {
     private lateinit var preferences: SharedPreferences
-    private var inputOverlay: InputOverlay? = null
     private lateinit var emulationState: EmulationState
     private var directoryStateReceiver: DirectoryStateReceiver? = null
     private var emulationActivity: EmulationActivity? = null
-    private lateinit var perfStats: TextView
     private var perfStatsUpdater: (() -> Unit)? = null
 
+    private var _binding: FragmentEmulationBinding? = null
+    private val binding get() = _binding!!
+
     override fun onAttach(context: Context) {
         super.onAttach(context)
         if (context is EmulationActivity) {
@@ -66,22 +65,19 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?
-    ): View? {
-        val contents = inflater.inflate(R.layout.fragment_emulation, container, false)
-        val surfaceView = contents.findViewById<SurfaceView>(R.id.surface_emulation)
-        surfaceView.holder.addCallback(this)
-        inputOverlay = contents.findViewById(R.id.surface_input_overlay)
-        perfStats = contents.findViewById(R.id.show_fps_text)
-        perfStats.setTextColor(Color.YELLOW)
-        val doneButton = contents.findViewById<Button>(R.id.done_control_config)
-        doneButton?.setOnClickListener { stopConfiguringControls() }
+    ): View {
+        _binding = FragmentEmulationBinding.inflate(layoutInflater)
+        return binding.root
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        binding.surfaceEmulation.holder.addCallback(this)
+        binding.showFpsText.setTextColor(Color.YELLOW)
+        binding.doneControlConfig.setOnClickListener { stopConfiguringControls() }
 
         // Setup overlay.
         resetInputOverlay()
         updateShowFpsOverlay()
-
-        // The new Surface created here will get passed to the native code via onSurfaceChanged.
-        return contents
     }
 
     override fun onResume() {
@@ -108,6 +104,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
         super.onPause()
     }
 
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+
     override fun onDetach() {
         NativeLibrary.clearEmulationActivity()
         super.onDetach()
@@ -144,7 +145,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
     }
 
     fun refreshInputOverlay() {
-        inputOverlay!!.refreshControls()
+        binding.surfaceInputOverlay.refreshControls()
     }
 
     fun resetInputOverlay() {
@@ -152,7 +153,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
         preferences.edit()
             .putInt(Settings.PREF_CONTROL_SCALE, 50)
             .apply()
-        inputOverlay!!.resetButtonPlacement()
+        binding.surfaceInputOverlay.resetButtonPlacement()
     }
 
     private fun updateShowFpsOverlay() {
@@ -165,17 +166,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
             perfStatsUpdater = {
                 val perfStats = NativeLibrary.GetPerfStats()
                 if (perfStats[FPS] > 0) {
-                    this.perfStats.text = String.format("FPS: %.1f", perfStats[FPS])
+                    binding.showFpsText.text = String.format("FPS: %.1f", perfStats[FPS])
                 }
                 perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 100)
             }
             perfStatsUpdateHandler.post(perfStatsUpdater!!)
-            perfStats.visibility = View.VISIBLE
+            binding.showFpsText.visibility = View.VISIBLE
         } else {
             if (perfStatsUpdater != null) {
                 perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!)
             }
-            perfStats.visibility = View.GONE
+            binding.showFpsText.visibility = View.GONE
         }
     }
 
@@ -203,18 +204,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
     }
 
     fun startConfiguringControls() {
-        requireView().findViewById<View>(R.id.done_control_config).visibility =
-            View.VISIBLE
-        inputOverlay!!.setIsInEditMode(true)
+        binding.doneControlConfig.visibility = View.VISIBLE
+        binding.surfaceInputOverlay.setIsInEditMode(true)
     }
 
     fun stopConfiguringControls() {
-        requireView().findViewById<View>(R.id.done_control_config).visibility = View.GONE
-        inputOverlay!!.setIsInEditMode(false)
+        binding.doneControlConfig.visibility = View.GONE
+        binding.surfaceInputOverlay.setIsInEditMode(false)
     }
 
     val isConfiguringControls: Boolean
-        get() = inputOverlay!!.isInEditMode
+        get() = binding.surfaceInputOverlay.isInEditMode
 
     private class EmulationState(private val mGamePath: String?) {
         private var state: State
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index f87f13463..c5259a13d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -10,30 +10,29 @@ import android.os.Bundle
 import android.view.Menu
 import android.view.MenuItem
 import android.view.View
-import android.widget.FrameLayout
 import android.widget.Toast
 import androidx.appcompat.app.AppCompatActivity
-import androidx.appcompat.widget.Toolbar
 import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.updatePadding
-import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import org.yuzu.yuzu_emu.NativeLibrary
 import org.yuzu.yuzu_emu.R
 import org.yuzu.yuzu_emu.activities.EmulationActivity
+import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
 import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
 import org.yuzu.yuzu_emu.model.GameProvider
 import org.yuzu.yuzu_emu.ui.platform.PlatformGamesFragment
 import org.yuzu.yuzu_emu.utils.*
 
 class MainActivity : AppCompatActivity(), MainView {
-    private lateinit var toolbar: Toolbar
     private var platformGamesFragment: PlatformGamesFragment? = null
     private val presenter = MainPresenter(this)
 
+    private lateinit var binding: ActivityMainBinding
+
     override fun onCreate(savedInstanceState: Bundle?) {
         val splashScreen = installSplashScreen()
         splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady() }
@@ -41,12 +40,13 @@ class MainActivity : AppCompatActivity(), MainView {
         ThemeHelper.setTheme(this)
 
         super.onCreate(savedInstanceState)
-        setContentView(R.layout.activity_main)
+
+        binding = ActivityMainBinding.inflate(layoutInflater)
+        setContentView(binding.root)
 
         WindowCompat.setDecorFitsSystemWindows(window, false)
 
-        findViews()
-        setSupportActionBar(toolbar)
+        setSupportActionBar(binding.toolbarMain)
         presenter.onCreate()
         if (savedInstanceState == null) {
             StartupHandler.handleInit(this)
@@ -81,11 +81,6 @@ class MainActivity : AppCompatActivity(), MainView {
         presenter.addDirIfNeeded(AddDirectoryHelper(this))
     }
 
-    // TODO: Replace with view binding
-    private fun findViews() {
-        toolbar = findViewById(R.id.toolbar_main)
-    }
-
     override fun onCreateOptionsMenu(menu: Menu): Boolean {
         menuInflater.inflate(R.menu.menu_game_grid, menu)
         return true
@@ -95,7 +90,7 @@ class MainActivity : AppCompatActivity(), MainView {
      * MainView
      */
     override fun setVersionString(version: String) {
-        toolbar.subtitle = version
+        binding.toolbarMain.subtitle = version
     }
 
     override fun refresh() {
@@ -247,12 +242,10 @@ class MainActivity : AppCompatActivity(), MainView {
     }
 
     private fun setInsets() {
-        val appBar = findViewById<AppBarLayout>(R.id.appbar_main)
-        val frame = findViewById<FrameLayout>(R.id.games_platform_frame)
-        ViewCompat.setOnApplyWindowInsetsListener(frame) { view: View, windowInsets: WindowInsetsCompat ->
+        ViewCompat.setOnApplyWindowInsetsListener(binding.gamesPlatformFrame) { view: View, windowInsets: WindowInsetsCompat ->
             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
             view.updatePadding(left = insets.left, right = insets.right)
-            InsetsHelper.insetAppBar(insets, appBar)
+            InsetsHelper.insetAppBar(insets, binding.appbarMain)
             windowInsets
         }
     }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
index 40e902a37..775f4ed9e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
@@ -9,35 +9,33 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewTreeObserver.OnGlobalLayoutListener
-import android.widget.TextView
 import androidx.appcompat.app.AppCompatActivity
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.updatePadding
 import androidx.fragment.app.Fragment
 import androidx.recyclerview.widget.GridLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
 import com.google.android.material.color.MaterialColors
 import org.yuzu.yuzu_emu.R
 import org.yuzu.yuzu_emu.YuzuApplication
 import org.yuzu.yuzu_emu.adapters.GameAdapter
+import org.yuzu.yuzu_emu.databinding.FragmentGridBinding
 
 class PlatformGamesFragment : Fragment(), PlatformGamesView {
     private val presenter = PlatformGamesPresenter(this)
     private var adapter: GameAdapter? = null
-    private lateinit var recyclerView: RecyclerView
-    private lateinit var textView: TextView
+
+    private var _binding: FragmentGridBinding? = null
+    private val binding get() = _binding!!
 
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?
-    ): View? {
-        val rootView = inflater.inflate(R.layout.fragment_grid, container, false)
-        findViews(rootView)
+    ): View {
         presenter.onCreateView()
-        return rootView
+        _binding = FragmentGridBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -58,30 +56,34 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
                         }
                         view.viewTreeObserver.removeOnGlobalLayoutListener(this)
                         val layoutManager = GridLayoutManager(activity, columns)
-                        recyclerView.layoutManager = layoutManager
-                        recyclerView.adapter = adapter
+                        binding.gridGames.layoutManager = layoutManager
+                        binding.gridGames.adapter = adapter
                     }
                 })
         }
 
         // Add swipe down to refresh gesture
-        val pullToRefresh = view.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh)
-        pullToRefresh.setOnRefreshListener {
+        binding.swipeRefresh.setOnRefreshListener {
             refresh()
-            pullToRefresh.isRefreshing = false
+            binding.swipeRefresh.isRefreshing = false
         }
 
         // Set theme color to the refresh animation's background
-        pullToRefresh.setProgressBackgroundColorSchemeColor(
-            MaterialColors.getColor(pullToRefresh, R.attr.colorPrimary)
+        binding.swipeRefresh.setProgressBackgroundColorSchemeColor(
+            MaterialColors.getColor(binding.swipeRefresh, R.attr.colorPrimary)
         )
-        pullToRefresh.setColorSchemeColors(
-            MaterialColors.getColor(pullToRefresh, R.attr.colorOnPrimary)
+        binding.swipeRefresh.setColorSchemeColors(
+            MaterialColors.getColor(binding.swipeRefresh, R.attr.colorOnPrimary)
         )
 
         setInsets()
     }
 
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+
     override fun refresh() {
         val databaseHelper = YuzuApplication.databaseHelper
         databaseHelper!!.scanLibrary(databaseHelper.writableDatabase)
@@ -97,17 +99,12 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
     }
 
     private fun updateTextView() {
-        textView.visibility =
+        binding.gamelistEmptyText.visibility =
             if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE
     }
 
-    private fun findViews(root: View) {
-        recyclerView = root.findViewById(R.id.grid_games)
-        textView = root.findViewById(R.id.gamelist_empty_text)
-    }
-
     private fun setInsets() {
-        ViewCompat.setOnApplyWindowInsetsListener(recyclerView) { view: View, windowInsets: WindowInsetsCompat ->
+        ViewCompat.setOnApplyWindowInsetsListener(binding.gridGames) { view: View, windowInsets: WindowInsetsCompat ->
             val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
             view.updatePadding(bottom = insets.bottom)
             windowInsets
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/viewholders/GameViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/viewholders/GameViewHolder.kt
index cef4e49d6..51420448f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/viewholders/GameViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/viewholders/GameViewHolder.kt
@@ -3,33 +3,14 @@
 
 package org.yuzu.yuzu_emu.viewholders
 
-import android.view.View
-import android.widget.ImageView
-import android.widget.TextView
 import androidx.recyclerview.widget.RecyclerView
-import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.databinding.CardGameBinding
+import org.yuzu.yuzu_emu.model.Game
 
-/**
- * A simple class that stores references to views so that the GameAdapter doesn't need to
- * keep calling findViewById(), which is expensive.
- */
-class GameViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-    var imageIcon: ImageView
-    var textGameTitle: TextView
-    var textGameCaption: TextView
-    var gameId: String? = null
-
-    // TODO Not need any of this stuff. Currently only the properties dialog needs it.
-    var path: String? = null
-    var title: String? = null
-    var description: String? = null
-    var regions: String? = null
-    var company: String? = null
+class GameViewHolder(val binding: CardGameBinding) : RecyclerView.ViewHolder(binding.root) {
+    lateinit var game: Game
 
     init {
         itemView.tag = this
-        imageIcon = itemView.findViewById(R.id.image_game_screen)
-        textGameTitle = itemView.findViewById(R.id.text_game_title)
-        textGameCaption = itemView.findViewById(R.id.text_game_caption)
     }
 }