fix content padding in nested scroll views

This commit is contained in:
Phillip Thelen 2025-02-11 12:57:16 +01:00
parent eb00e4c8c2
commit be77530a09
32 changed files with 97 additions and 24 deletions

View file

@ -31,6 +31,7 @@
android:scrollbars="vertical">
<LinearLayout
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"

View file

@ -18,6 +18,7 @@
android:orientation="horizontal"
android:background="?colorPrimaryOffset"
android:clipToPadding="false"
android:clipChildren="false"
android:baselineAligned="false">
<com.habitrpg.android.habitica.ui.RoundedFrameLayout
@ -69,6 +70,7 @@
android:id="@+id/notificationsButtonWrapper"
android:layout_width="33dp"
android:layout_height="33dp"
android:clipChildren="false"
android:layout_marginStart="16dp">
<ImageView
@ -104,6 +106,8 @@
android:id="@+id/messagesButtonWrapper"
android:layout_width="33dp"
android:layout_height="33dp"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginStart="8dp">
<ImageView
@ -138,7 +142,7 @@
<RelativeLayout
android:id="@+id/settingsButtonWrapper"
android:layout_width="43dp"
android:layout_height="wrap_content"
android:layout_height="33dp"
android:paddingStart="8dp"
android:paddingEnd="0dp">

View file

@ -7,6 +7,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"

View file

@ -9,6 +9,7 @@
android:scrollbars="vertical">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -6,6 +6,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"

View file

@ -10,6 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">

View file

@ -14,6 +14,7 @@
android:scrollbars="vertical">
<LinearLayout
android:id="@+id/scroll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

View file

@ -10,6 +10,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -6,6 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:id="@+id/content_wrapper"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
android:id="@+id/content_wrapper"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -5,6 +5,7 @@
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorContentBackground"

View file

@ -4,6 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/scroll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -165,6 +166,7 @@
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/reset_tutorial_button_wrapper"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/colorContentBackgroundOffset"/>

View file

@ -1,9 +1,32 @@
package com.habitrpg.android.habitica.extensions
import android.os.Build
import android.view.View
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
fun consumeWindowInsetsAbove30(insets: WindowInsetsCompat): WindowInsetsCompat {
if (Build.VERSION.SDK_INT >= 30) return WindowInsetsCompat.CONSUMED
return insets
}
fun applyScrollContentWindowInsets(view: View,
applyTop: Boolean = false,
applyBottom: Boolean = true,
applyLeft: Boolean = true,
applyRight: Boolean = true) {
val topPadding = view.paddingTop
val leftPadding = view.paddingLeft
val rightPadding = view.paddingRight
val bottomPadding = view.paddingBottom
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars() + WindowInsetsCompat.Type.displayCutout())
v.updatePadding(
top = (if (applyTop) insets.top else 0) + topPadding,
left = (if (applyLeft) insets.left else 0) + leftPadding,
right = (if (applyRight) insets.right else 0) + rightPadding,
bottom = (if (applyBottom) insets.bottom else 0) + bottomPadding)
consumeWindowInsetsAbove30(windowInsets)
}
}

View file

@ -14,6 +14,7 @@ import androidx.core.view.updatePadding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityAdventureGuideBinding
import com.habitrpg.android.habitica.databinding.AdventureGuideItemBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.models.user.User
@ -78,19 +79,7 @@ class AdventureGuideActivity : BaseActivity() {
override fun onAttachedToWindow() {
super.onAttachedToWindow()
ViewCompat.setOnApplyWindowInsetsListener(binding.nestedScrollView) { v, insets ->
val bars = insets.getInsets(
WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
)
v.updatePadding(
top = bars.top,
bottom = bars.bottom,
left = bars.left,
right = bars.right
)
consumeWindowInsetsAbove30(insets)
}
applyScrollContentWindowInsets(binding.scrollContent)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

View file

@ -48,6 +48,7 @@ import com.habitrpg.android.habitica.data.TaskRepository
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
@ -433,11 +434,7 @@ class TaskFormActivity : BaseActivity() {
override fun onAttachedToWindow() {
super.onAttachedToWindow()
ViewCompat.setOnApplyWindowInsetsListener(binding.mainFormContent) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
v.updatePadding(bottom = insets.bottom)
consumeWindowInsetsAbove30(windowInsets)
}
applyScrollContentWindowInsets(binding.mainFormContent)
}
override fun onResume() {

View file

@ -5,8 +5,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import javax.inject.Inject
@ -29,6 +31,14 @@ abstract class BasePreferencesFragment : PreferenceFragmentCompat() {
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<RecyclerView>(R.id.recycler_view)?.let {
applyScrollContentWindowInsets(it)
}
}
override fun onDestroy() {
userRepository.close()
super.onDestroy()

View file

@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SetupCustomizationRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentSetupAvatarBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.models.SetupCustomization
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.activities.SetupActivity
@ -113,6 +114,7 @@ class AvatarSetupFragment : BaseFragment<FragmentSetupAvatarBinding>() {
if (this.user != null) {
this.updateAvatar()
}
binding?.contentWrapper?.let { applyScrollContentWindowInsets(it) }
}
override fun onResume() {

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.FragmentSetupTasksBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.models.tasks.Days
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.android.habitica.models.user.User
@ -63,6 +64,8 @@ class TaskSetupFragment : BaseFragment<FragmentSetupTasksBinding>() {
HabiticaIconsHelper.imageOfHeartLightBg()
)
)
binding?.contentWrapper?.let { applyScrollContentWindowInsets(it) }
}
override fun onResume() {

View file

@ -16,6 +16,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentChatBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.social.ChatMessage
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
@ -136,6 +137,7 @@ open class ChatFragment : BaseFragment<FragmentChatBinding>() {
}
}
}
binding?.chatBarView?.let { applyScrollContentWindowInsets(it) }
}
override fun onResume() {

View file

@ -21,6 +21,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentInboxMessageListBinding
import com.habitrpg.android.habitica.extensions.addOkButton
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.social.ChatMessage
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
@ -134,6 +135,7 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
}
}
}
binding?.chatBarView?.let { applyScrollContentWindowInsets(it) }
}
override fun onResume() {

View file

@ -15,6 +15,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentQuestDetailBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
import com.habitrpg.android.habitica.models.inventory.Quest
import com.habitrpg.android.habitica.models.inventory.QuestContent
@ -100,6 +101,7 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
updateQuestContent(it)
}
}
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun updateParty(group: Group?) {

View file

@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.DialogChallengeDetailTaskGroupBinding
import com.habitrpg.android.habitica.databinding.FragmentChallengeDetailBinding
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.models.social.Challenge
import com.habitrpg.android.habitica.models.tasks.Task
@ -165,7 +166,7 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
}
}
binding?.leaveButton?.setOnClickListener { showChallengeLeaveDialog() }
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
refresh()
}

View file

@ -7,6 +7,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
@ -15,6 +18,8 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ChallengeRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentGuildDetailBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.models.social.Challenge
@ -89,6 +94,8 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
MainNavigationController.navigate(profileDirections)
}
}
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun setLeader(leader: Member?) {

View file

@ -17,6 +17,7 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentNoPartyBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
@ -144,6 +145,8 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
}
}
}
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private val groupFormResult =

View file

@ -20,6 +20,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentPartyDetailBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
import com.habitrpg.android.habitica.models.inventory.QuestContent
@ -161,6 +162,8 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
binding?.questMechanicsButton?.setOnClickListener {
showQuestMechanicsDialog()
}
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun refreshParty() {

View file

@ -13,6 +13,7 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.FragmentSupportBugFixBinding
import com.habitrpg.android.habitica.databinding.KnownIssueBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@ -80,6 +81,7 @@ class BugFixFragment : BaseMainFragment<FragmentSupportBugFixBinding>() {
}
binding?.knownIssuesLayout?.addView(issueBinding.root)
}
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private val versionName: String by lazy {

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentFaqDetailBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.common.habitica.helpers.MarkdownParser
import com.habitrpg.common.habitica.helpers.launchCatching
@ -60,5 +61,6 @@ class FAQDetailFragment : BaseMainFragment<FragmentFaqDetailBinding>() {
}
binding?.answerTextView?.movementMethod = LinkMovementMethod.getInstance()
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
}

View file

@ -24,6 +24,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentFaqOverviewBinding
import com.habitrpg.android.habitica.databinding.SupportFaqItemBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@ -171,6 +172,8 @@ class FAQOverviewFragment : BaseMainFragment<FragmentFaqOverviewBinding>() {
binding?.moreHelpTextView?.movementMethod = LinkMovementMethod.getInstance()
this.loadArticles()
binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
override fun onDestroy() {

View file

@ -10,6 +10,7 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentSupportMainBinding
import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
@ -75,6 +76,8 @@ class SupportMainFragment : BaseMainFragment<FragmentSupportMainBinding>() {
)
}
}
binding?.resetTutorialButtonWrapper?.let { applyScrollContentWindowInsets(it) }
}
override fun onDestroy() {

View file

@ -116,7 +116,7 @@ constructor(
ViewCompat.setOnApplyWindowInsetsListener(binding.itemWrapper) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
v.updatePadding(bottom = insets.bottom)
v.updatePadding(bottom = insets.bottom, left = insets.left, right = insets.right)
consumeWindowInsetsAbove30(windowInsets)
}
binding.addButton.setOnTouchListener { _, event ->

View file

@ -1,2 +1,2 @@
NAME=4.7.0
CODE=10351
CODE=12351