mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-23 07:59:18 +01:00
Fix RecyclerView
height in CoordinatorLayout
for non touch-mode
Any `RecyclerView`s with an app bar in a `CoordinatorLayout` would end up going off-screen due to the layout behavior implementing an offset by using a transform which would not correctly handle focusing on off-screen objects. This has now been fixed by manually adjusting height to be clipped to what is visible on the screen.
This commit is contained in:
parent
3ae62c7fcc
commit
e2cae74425
@ -8,7 +8,9 @@ package emu.skyline
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import emu.skyline.databinding.SettingsActivityBinding
|
||||
@ -33,8 +35,33 @@ class SettingsActivity : AppCompatActivity() {
|
||||
setSupportActionBar(binding.titlebar.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
window.decorView.findViewById<View>(android.R.id.content).viewTreeObserver.addOnTouchModeChangeListener { isInTouchMode ->
|
||||
if (!isInTouchMode) binding.titlebar.appBarLayout.setExpanded(false)
|
||||
var layoutDone = false // Tracks if the layout is complete to avoid retrieving invalid attributes
|
||||
binding.coordinatorLayout.viewTreeObserver.addOnTouchModeChangeListener { isTouchMode ->
|
||||
val layoutUpdate = { ->
|
||||
val params = binding.settings.layoutParams as CoordinatorLayout.LayoutParams
|
||||
if (!isTouchMode) {
|
||||
binding.titlebar.appBarLayout.setExpanded(true)
|
||||
params.height = binding.coordinatorLayout.height - binding.titlebar.toolbar.height
|
||||
} else {
|
||||
params.height = CoordinatorLayout.LayoutParams.MATCH_PARENT
|
||||
}
|
||||
|
||||
binding.settings.layoutParams = params
|
||||
binding.settings.requestLayout()
|
||||
}
|
||||
|
||||
if (!layoutDone) {
|
||||
binding.coordinatorLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
// We need to wait till the layout is done to get the correct height of the toolbar
|
||||
binding.coordinatorLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
layoutUpdate()
|
||||
layoutDone = true
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layoutUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
supportFragmentManager
|
||||
|
@ -9,7 +9,10 @@ import android.content.Intent
|
||||
import android.graphics.Canvas
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.marginTop
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@ -182,13 +185,34 @@ class ControllerActivity : AppCompatActivity() {
|
||||
binding.controllerList.layoutManager = layoutManager
|
||||
binding.controllerList.adapter = adapter
|
||||
|
||||
binding.controllerList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView : RecyclerView, dx : Int, dy : Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
var layoutDone = false // Tracks if the layout is complete to avoid retrieving invalid attributes
|
||||
binding.coordinatorLayout.viewTreeObserver.addOnTouchModeChangeListener { isTouchMode ->
|
||||
val layoutUpdate = { ->
|
||||
val params = binding.controllerList.layoutParams as CoordinatorLayout.LayoutParams
|
||||
if (!isTouchMode) {
|
||||
binding.titlebar.appBarLayout.setExpanded(true)
|
||||
params.height = binding.coordinatorLayout.height - binding.titlebar.toolbar.height
|
||||
} else {
|
||||
params.height = CoordinatorLayout.LayoutParams.MATCH_PARENT
|
||||
}
|
||||
|
||||
if (layoutManager.findLastCompletelyVisibleItemPosition() == adapter.itemCount - 1) binding.titlebar.appBarLayout.setExpanded(false)
|
||||
binding.controllerList.layoutParams = params
|
||||
binding.controllerList.requestLayout()
|
||||
}
|
||||
|
||||
if (!layoutDone) {
|
||||
binding.coordinatorLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
// We need to wait till the layout is done to get the correct height of the toolbar
|
||||
binding.coordinatorLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
layoutUpdate()
|
||||
layoutDone = true
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layoutUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
val dividerItemDecoration = object : DividerItemDecoration(this, DividerItemDecoration.VERTICAL) {
|
||||
override fun onDraw(canvas : Canvas, parent : RecyclerView, state : RecyclerView.State) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".input.ControllerActivity">
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
Loading…
Reference in New Issue
Block a user