mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
fix: manually resize editor content when ime state changes
This commit is contained in:
@@ -70,8 +70,7 @@
|
||||
<activity
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:launchMode="singleTop"
|
||||
android:name=".activities.editor.EditorActivityKt"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
android:name=".activities.editor.EditorActivityKt"/>
|
||||
<activity android:name=".activities.PreferencesActivity" />
|
||||
<activity android:name=".activities.AboutActivity" />
|
||||
<activity android:name=".activities.ContributorsActivity" />
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.itsaky.androidide.activities
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
@@ -27,6 +26,7 @@ import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePaddingRelative
|
||||
import com.blankj.utilcode.util.ClipboardUtils
|
||||
import com.blankj.utilcode.util.SizeUtils
|
||||
@@ -101,8 +101,7 @@ class AboutActivity : EdgeToEdgeIDEActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInsetsUpdated(insets: Rect) {
|
||||
super.onInsetsUpdated(insets)
|
||||
override fun onApplySystemBarInsets(insets: Insets) {
|
||||
binding.toolbar.apply {
|
||||
setPaddingRelative(
|
||||
paddingStart + insets.left,
|
||||
@@ -126,53 +125,65 @@ class AboutActivity : EdgeToEdgeIDEActivity() {
|
||||
|
||||
private fun createSocialItems(): List<IconTitleDescriptionItem> {
|
||||
return mutableListOf<IconTitleDescriptionItem>().apply {
|
||||
add(createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_WEBSITE,
|
||||
R.drawable.ic_website,
|
||||
R.string.about_option_website,
|
||||
BuildInfo.PROJECT_SITE
|
||||
))
|
||||
add(createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_EMAIL,
|
||||
R.drawable.ic_email,
|
||||
R.string.about_option_email,
|
||||
BaseApplication.EMAIL
|
||||
))
|
||||
add(createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_TG_GROUP,
|
||||
R.drawable.ic_telegram,
|
||||
R.string.discussions_on_telegram,
|
||||
BaseApplication.TELEGRAM_GROUP_URL
|
||||
))
|
||||
add(createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_TG_CHANNEL,
|
||||
R.drawable.ic_telegram,
|
||||
R.string.official_tg_channel,
|
||||
BaseApplication.TELEGRAM_CHANNEL_URL
|
||||
))
|
||||
add(
|
||||
createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_WEBSITE,
|
||||
R.drawable.ic_website,
|
||||
R.string.about_option_website,
|
||||
BuildInfo.PROJECT_SITE
|
||||
)
|
||||
)
|
||||
add(
|
||||
createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_EMAIL,
|
||||
R.drawable.ic_email,
|
||||
R.string.about_option_email,
|
||||
BaseApplication.EMAIL
|
||||
)
|
||||
)
|
||||
add(
|
||||
createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_TG_GROUP,
|
||||
R.drawable.ic_telegram,
|
||||
R.string.discussions_on_telegram,
|
||||
BaseApplication.TELEGRAM_GROUP_URL
|
||||
)
|
||||
)
|
||||
add(
|
||||
createSimpleIconTextItem(
|
||||
this@AboutActivity,
|
||||
ACTION_TG_CHANNEL,
|
||||
R.drawable.ic_telegram,
|
||||
R.string.official_tg_channel,
|
||||
BaseApplication.TELEGRAM_CHANNEL_URL
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMiscItems(): List<IconTitleDescriptionItem> {
|
||||
return mutableListOf<IconTitleDescriptionItem>().apply {
|
||||
add(SimpleIconTitleDescriptionItem.create(
|
||||
this@AboutActivity,
|
||||
ACTION_CONTRIBUTE,
|
||||
R.drawable.ic_code,
|
||||
R.string.title_contribute,
|
||||
R.string.summary_contribute
|
||||
))
|
||||
add(SimpleIconTitleDescriptionItem.create(
|
||||
this@AboutActivity,
|
||||
ACTION_CONTRIBUTORS,
|
||||
R.drawable.ic_heart_outline,
|
||||
R.string.title_contributors,
|
||||
R.string.summary_contributors
|
||||
))
|
||||
add(
|
||||
SimpleIconTitleDescriptionItem.create(
|
||||
this@AboutActivity,
|
||||
ACTION_CONTRIBUTE,
|
||||
R.drawable.ic_code,
|
||||
R.string.title_contribute,
|
||||
R.string.summary_contribute
|
||||
)
|
||||
)
|
||||
add(
|
||||
SimpleIconTitleDescriptionItem.create(
|
||||
this@AboutActivity,
|
||||
ACTION_CONTRIBUTORS,
|
||||
R.drawable.ic_heart_outline,
|
||||
R.string.title_contributors,
|
||||
R.string.summary_contributors
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +255,8 @@ class AboutActivity : EdgeToEdgeIDEActivity() {
|
||||
appendForegroundSpan(
|
||||
builder,
|
||||
BuildInfoUtils.getBuildType(this).lowercase(),
|
||||
color)
|
||||
color
|
||||
)
|
||||
|
||||
builder.append(")")
|
||||
}
|
||||
@@ -254,7 +266,8 @@ class AboutActivity : EdgeToEdgeIDEActivity() {
|
||||
text: CharSequence,
|
||||
color: Int
|
||||
) {
|
||||
builder.append(text,
|
||||
builder.append(
|
||||
text,
|
||||
ForegroundColorSpan(color),
|
||||
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
package com.itsaky.androidide.activities
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import com.itsaky.androidide.R
|
||||
import com.itsaky.androidide.adapters.ContributorsGridAdapter
|
||||
@@ -92,8 +92,8 @@ class ContributorsActivity : EdgeToEdgeIDEActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInsetsUpdated(insets: Rect) {
|
||||
super.onInsetsUpdated(insets)
|
||||
override fun onApplySystemBarInsets(insets: Insets) {
|
||||
super.onApplySystemBarInsets(insets)
|
||||
binding.toolbar.apply {
|
||||
setPaddingRelative(
|
||||
paddingStart + insets.left,
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
package com.itsaky.androidide.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.transition.doOnEnd
|
||||
@@ -98,9 +98,13 @@ class MainActivity : EdgeToEdgeIDEActivity() {
|
||||
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
||||
}
|
||||
|
||||
override fun onInsetsUpdated(insets: Rect) {
|
||||
super.onInsetsUpdated(insets)
|
||||
binding.fragmentContainersParent.setPadding(insets.left, 0, insets.right, insets.bottom)
|
||||
override fun onApplySystemBarInsets(insets: Insets) {
|
||||
binding.fragmentContainersParent.setPadding(
|
||||
insets.left,
|
||||
0,
|
||||
insets.right,
|
||||
insets.bottom
|
||||
)
|
||||
}
|
||||
|
||||
private fun onScreenChanged(screen: Int?) {
|
||||
@@ -109,7 +113,8 @@ class MainActivity : EdgeToEdgeIDEActivity() {
|
||||
// template list -> template details
|
||||
// ------- OR -------
|
||||
// template details -> template list
|
||||
val setAxisToX = (previous == SCREEN_TEMPLATE_LIST || previous == SCREEN_TEMPLATE_DETAILS) && (screen == SCREEN_TEMPLATE_LIST || screen == SCREEN_TEMPLATE_DETAILS)
|
||||
val setAxisToX =
|
||||
(previous == SCREEN_TEMPLATE_LIST || previous == SCREEN_TEMPLATE_DETAILS) && (screen == SCREEN_TEMPLATE_LIST || screen == SCREEN_TEMPLATE_DETAILS)
|
||||
|
||||
val axis = if (setAxisToX) {
|
||||
MaterialSharedAxis.X
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
*/
|
||||
package com.itsaky.androidide.activities
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.itsaky.androidide.R
|
||||
import com.itsaky.androidide.app.EdgeToEdgeIDEActivity
|
||||
@@ -64,9 +64,7 @@ class PreferencesActivity : EdgeToEdgeIDEActivity() {
|
||||
loadFragment(rootFragment)
|
||||
}
|
||||
|
||||
override fun onInsetsUpdated(insets: Rect) {
|
||||
super.onInsetsUpdated(insets)
|
||||
|
||||
override fun onApplySystemBarInsets(insets: Insets) {
|
||||
val toolbar: View = binding.toolbar
|
||||
toolbar.setPadding(
|
||||
toolbar.paddingLeft + insets.left,
|
||||
@@ -86,7 +84,8 @@ class PreferencesActivity : EdgeToEdgeIDEActivity() {
|
||||
|
||||
override fun bindLayout(): View {
|
||||
_binding = ActivityPreferencesBinding.inflate(
|
||||
layoutInflater)
|
||||
layoutInflater
|
||||
)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ package com.itsaky.androidide.activities.editor
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller.SessionCallback
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.os.Process
|
||||
@@ -41,7 +40,9 @@ import androidx.annotation.GravityInt
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.collection.MutableIntIntMap
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.core.view.updatePaddingRelative
|
||||
@@ -186,6 +187,7 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
}
|
||||
}
|
||||
|
||||
private var contentCardRealHeight: Int? = null
|
||||
private val editorSurfaceContainerBackground by lazy {
|
||||
resolveAttr(R.attr.colorSurfaceDim)
|
||||
}
|
||||
@@ -262,8 +264,18 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
return this.binding.root
|
||||
}
|
||||
|
||||
override fun onInsetsUpdated(insets: Rect) {
|
||||
super.onInsetsUpdated(insets)
|
||||
override fun onApplyWindowInsets(insets: WindowInsetsCompat) {
|
||||
super.onApplyWindowInsets(insets)
|
||||
val height = contentCardRealHeight ?: return
|
||||
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
|
||||
_binding?.content?.bottomSheet?.setImeVisible(imeInsets.bottom > 0)
|
||||
_binding?.contentCard?.updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
this.height = height - imeInsets.bottom
|
||||
}
|
||||
}
|
||||
|
||||
override fun onApplySystemBarInsets(insets: Insets) {
|
||||
super.onApplySystemBarInsets(insets)
|
||||
this._binding?.apply {
|
||||
drawerSidebar.getFragment<EditorSidebarFragment>()
|
||||
.onApplyWindowInsets(insets)
|
||||
@@ -307,7 +319,8 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_PROJECT_PATH)) {
|
||||
ProjectManagerImpl.getInstance().projectPath = savedInstanceState.getString(
|
||||
KEY_PROJECT_PATH)!!
|
||||
KEY_PROJECT_PATH
|
||||
)!!
|
||||
}
|
||||
|
||||
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
|
||||
@@ -324,8 +337,10 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
setupContainers()
|
||||
setupDiagnosticInfo()
|
||||
|
||||
uiDesignerResultLauncher = registerForActivityResult(StartActivityForResult(),
|
||||
this::handleUiDesignerResult)
|
||||
uiDesignerResultLauncher = registerForActivityResult(
|
||||
StartActivityForResult(),
|
||||
this::handleUiDesignerResult
|
||||
)
|
||||
|
||||
setupMemUsageChart()
|
||||
watchMemory()
|
||||
@@ -334,7 +349,7 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
private fun onSwipeRevealDragProgress(progress: Float) {
|
||||
_binding?.apply {
|
||||
contentCard.progress = progress
|
||||
val insetsTop = lastWindowInsets?.top ?: 0
|
||||
val insetsTop = systemBarInsets?.top ?: 0
|
||||
content.editorAppBarLayout.updatePadding(
|
||||
top = (insetsTop * (1f - progress)).roundToInt()
|
||||
)
|
||||
@@ -377,8 +392,10 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
protected fun resetMemUsageChart() {
|
||||
val processes = memoryUsageWatcher.getMemoryUsages()
|
||||
val datasets = Array(processes.size) { index ->
|
||||
LineDataSet(List(MemoryUsageWatcher.MAX_USAGE_ENTRIES) { Entry(it.toFloat(), 0f) },
|
||||
processes[index].pname)
|
||||
LineDataSet(
|
||||
List(MemoryUsageWatcher.MAX_USAGE_ENTRIES) { Entry(it.toFloat(), 0f) },
|
||||
processes[index].pname
|
||||
)
|
||||
}
|
||||
|
||||
val bgColor = editorSurfaceContainerBackground
|
||||
@@ -535,7 +552,8 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
}
|
||||
|
||||
val index = content.bottomSheet.pagerAdapter.findIndexOfFragmentByClass(
|
||||
SearchResultFragment::class.java)
|
||||
SearchResultFragment::class.java
|
||||
)
|
||||
|
||||
if (index >= 0 && index < content.bottomSheet.binding.tabs.tabCount) {
|
||||
content.bottomSheet.binding.tabs.getTabAt(index)?.select()
|
||||
@@ -559,7 +577,8 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
open fun getFileTreeFragment(): FileTreeFragment? {
|
||||
if (filesTreeFragment == null) {
|
||||
filesTreeFragment = supportFragmentManager.findFragmentByTag(
|
||||
FileTreeFragment.TAG) as FileTreeFragment?
|
||||
FileTreeFragment.TAG
|
||||
) as FileTreeFragment?
|
||||
}
|
||||
return filesTreeFragment
|
||||
}
|
||||
@@ -585,8 +604,10 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
|
||||
private fun handleUiDesignerResult(result: ActivityResult) {
|
||||
if (result.resultCode != RESULT_OK || result.data == null) {
|
||||
log.warn("UI Designer returned invalid result: resultCode={}, data={}", result.resultCode,
|
||||
result.data)
|
||||
log.warn(
|
||||
"UI Designer returned invalid result: resultCode={}, data={}", result.resultCode,
|
||||
result.data
|
||||
)
|
||||
return
|
||||
}
|
||||
val generated = result.data!!.getStringExtra(UIDesignerActivity.RESULT_GENERATED_XML)
|
||||
@@ -604,8 +625,10 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
}
|
||||
|
||||
private fun setupDrawers() {
|
||||
val toggle = ActionBarDrawerToggle(this, binding.editorDrawerLayout, content.editorToolbar,
|
||||
string.app_name, string.app_name)
|
||||
val toggle = ActionBarDrawerToggle(
|
||||
this, binding.editorDrawerLayout, content.editorToolbar,
|
||||
string.app_name, string.app_name
|
||||
)
|
||||
|
||||
binding.editorDrawerLayout.addDrawerListener(toggle)
|
||||
toggle.syncState()
|
||||
@@ -621,7 +644,8 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
|
||||
private fun onBuildStatusChanged() {
|
||||
log.debug(
|
||||
"onBuildStatusChanged: isInitializing: ${editorViewModel.isInitializing}, isBuildInProgress: ${editorViewModel.isBuildInProgress}")
|
||||
"onBuildStatusChanged: isInitializing: ${editorViewModel.isInitializing}, isBuildInProgress: ${editorViewModel.isBuildInProgress}"
|
||||
)
|
||||
val visible = editorViewModel.isBuildInProgress || editorViewModel.isInitializing
|
||||
content.progressIndicator.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
invalidateOptionsMenu()
|
||||
@@ -650,7 +674,8 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
setupBottomSheet()
|
||||
|
||||
if (!app.prefManager.getBoolean(
|
||||
KEY_BOTTOM_SHEET_SHOWN) && editorBottomSheet?.state != BottomSheetBehavior.STATE_EXPANDED
|
||||
KEY_BOTTOM_SHEET_SHOWN
|
||||
) && editorBottomSheet?.state != BottomSheetBehavior.STATE_EXPANDED
|
||||
) {
|
||||
editorBottomSheet?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
ThreadUtils.runOnUiThreadDelayed({
|
||||
@@ -727,10 +752,12 @@ abstract class BaseEditorActivity : EdgeToEdgeIDEActivity(), TabLayout.OnTabSele
|
||||
|
||||
val observer: OnGlobalLayoutListener = object : OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
contentCardRealHeight = binding.contentCard.height
|
||||
content.also {
|
||||
it.realContainer.pivotX = it.realContainer.width.toFloat() / 2f
|
||||
it.realContainer.pivotY = (it.realContainer.height.toFloat() / 2f) + (lastWindowInsets?.height()
|
||||
?: 0)
|
||||
it.realContainer.pivotY =
|
||||
(it.realContainer.height.toFloat() / 2f) + (systemBarInsets?.run { bottom - top }
|
||||
?: 0)
|
||||
it.viewContainer.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,10 @@ import android.os.PersistableBundle
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.doOnAttach
|
||||
import com.itsaky.androidide.utils.EdgeToEdgeUtils
|
||||
import com.itsaky.androidide.utils.getSystemBarInsets
|
||||
@@ -70,7 +72,7 @@ abstract class EdgeToEdgeIDEActivity : IDEActivity() {
|
||||
/**
|
||||
* Last window insets.
|
||||
*/
|
||||
protected open var lastWindowInsets: Rect? = null
|
||||
protected open var systemBarInsets: Insets? = null
|
||||
|
||||
override var enableSystemBarTheming: Boolean
|
||||
get() = false
|
||||
@@ -82,9 +84,10 @@ abstract class EdgeToEdgeIDEActivity : IDEActivity() {
|
||||
|
||||
@SuppressLint("WrongConstant")
|
||||
private val onApplyWindowInsetsListener = OnApplyWindowInsetsListener { v, insets ->
|
||||
onApplyWindowInsets(insets)
|
||||
if (!eteUpdateDecorViewPaddingInLandscape ||
|
||||
v.resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||
) {
|
||||
v.resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
|
||||
) {
|
||||
decorViewPadding?.also { p ->
|
||||
// when switching from landscape to portrait, restore the original padding
|
||||
v.setPadding(p.left, p.top, p.right, p.bottom)
|
||||
@@ -104,18 +107,21 @@ abstract class EdgeToEdgeIDEActivity : IDEActivity() {
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val systemBarInsets = insets.getInsets(WindowInsets.Type.systemBars())
|
||||
v.setPadding(
|
||||
insets.getInsets(WindowInsets.Type.systemBars()).left,
|
||||
systemBarInsets.left,
|
||||
0,
|
||||
insets.getInsets(WindowInsets.Type.systemBars()).right,
|
||||
insets.getInsets(WindowInsets.Type.systemBars()).bottom)
|
||||
systemBarInsets.right,
|
||||
systemBarInsets.bottom
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
v.setPadding(
|
||||
insets.stableInsetLeft,
|
||||
0,
|
||||
insets.stableInsetRight,
|
||||
insets.stableInsetBottom)
|
||||
insets.stableInsetBottom
|
||||
)
|
||||
}
|
||||
|
||||
insets
|
||||
@@ -146,12 +152,21 @@ abstract class EdgeToEdgeIDEActivity : IDEActivity() {
|
||||
this.onApplyWindowInsetsListener
|
||||
)
|
||||
|
||||
this.window.decorView.doOnAttach { decorView -> onInsetsUpdated(getSystemBarInsets(decorView)) }
|
||||
this.window.decorView.doOnAttach { onApplySystemBarInsets(getSystemBarInsets(it)) }
|
||||
}
|
||||
|
||||
/** Called whenever insets are updated */
|
||||
/**
|
||||
* Called when the window insets change.
|
||||
*
|
||||
* @param insets The window insets. These insets are not expected to be consumed.
|
||||
*/
|
||||
@CallSuper
|
||||
protected open fun onInsetsUpdated(insets: Rect) {
|
||||
this.lastWindowInsets = insets
|
||||
protected open fun onApplyWindowInsets(insets: WindowInsetsCompat) {
|
||||
this.systemBarInsets = getSystemBarInsets(insets)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with the system bar insets when the decor view is attached to the window.
|
||||
*/
|
||||
protected open fun onApplySystemBarInsets(insets: Insets) {}
|
||||
}
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
|
||||
package com.itsaky.androidide.fragments.sidebar
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.marginBottom
|
||||
import androidx.core.view.marginTop
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updateMarginsRelative
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.core.view.updatePaddingRelative
|
||||
import com.itsaky.androidide.databinding.FragmentEditorSidebarBinding
|
||||
import com.itsaky.androidide.fragments.FragmentWithBinding
|
||||
import com.itsaky.androidide.utils.EditorSidebarActions
|
||||
@@ -40,7 +39,7 @@ class EditorSidebarFragment : FragmentWithBinding<FragmentEditorSidebarBinding>(
|
||||
FragmentEditorSidebarBinding::inflate
|
||||
) {
|
||||
|
||||
internal fun onApplyWindowInsets(insets: Rect) {
|
||||
internal fun onApplyWindowInsets(insets: Insets) {
|
||||
_binding?.apply {
|
||||
title.updateLayoutParams<MarginLayoutParams> {
|
||||
updateMarginsRelative(
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.itsaky.androidide.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.TextUtils
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
@@ -60,7 +59,6 @@ import com.itsaky.androidide.tasks.TaskExecutor.executeAsyncProvideError
|
||||
import com.itsaky.androidide.utils.IntentUtils.shareFile
|
||||
import com.itsaky.androidide.utils.Symbols.forFile
|
||||
import com.itsaky.androidide.utils.flashError
|
||||
import com.itsaky.androidide.utils.resolveAttr
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@@ -89,13 +87,24 @@ constructor(
|
||||
val localContext = getContext() ?: return@lazy 0f
|
||||
localContext.resources.getDimension(R.dimen.editor_sheet_collapsed_height)
|
||||
}
|
||||
private val behavior: BottomSheetBehavior<EditorBottomSheet> by lazy {
|
||||
BottomSheetBehavior.from(this).apply {
|
||||
isFitToContents = false
|
||||
skipCollapsed = true
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
var binding: LayoutEditorBottomSheetBinding
|
||||
val pagerAdapter: EditorBottomSheetTabAdapter
|
||||
|
||||
private var anchorOffset = 0
|
||||
private var isImeVisible = false
|
||||
private var windowInsets: Insets? = null
|
||||
|
||||
private val insetBottom: Int
|
||||
get() = if (isImeVisible) 0 else windowInsets?.bottom ?: 0
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LoggerFactory.getLogger(EditorBottomSheet::class.java)
|
||||
@@ -165,9 +174,8 @@ constructor(
|
||||
}
|
||||
|
||||
binding.headerContainer.setOnClickListener {
|
||||
val sheet = BottomSheetBehavior.from(this)
|
||||
if (sheet.state != BottomSheetBehavior.STATE_EXPANDED) {
|
||||
sheet.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
if (behavior.state != BottomSheetBehavior.STATE_EXPANDED) {
|
||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,23 +201,26 @@ constructor(
|
||||
initialize(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the input method is visible.
|
||||
*/
|
||||
fun setImeVisible(isVisible: Boolean) {
|
||||
isImeVisible = isVisible
|
||||
behavior.isGestureInsetBottomIgnored = isVisible
|
||||
}
|
||||
|
||||
fun setOffsetAnchor(view: View) {
|
||||
val listener =
|
||||
object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
val sheet = BottomSheetBehavior.from(this@EditorBottomSheet)
|
||||
val offset = view.height + SizeUtils.dp2px(1f)
|
||||
val collapsedHeight = collapsedHeight
|
||||
|
||||
sheet.isFitToContents = false
|
||||
sheet.skipCollapsed = true
|
||||
sheet.isGestureInsetBottomIgnored = false
|
||||
sheet.peekHeight = collapsedHeight.roundToInt()
|
||||
sheet.expandedOffset = offset
|
||||
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
anchorOffset = view.height + SizeUtils.dp2px(1f)
|
||||
|
||||
val insetBottom = windowInsets?.bottom ?: 0
|
||||
binding.root.updatePadding(bottom = offset + insetBottom)
|
||||
behavior.peekHeight = collapsedHeight.roundToInt()
|
||||
behavior.expandedOffset = anchorOffset
|
||||
behavior.isGestureInsetBottomIgnored = isImeVisible
|
||||
|
||||
binding.root.updatePadding(bottom = anchorOffset + insetBottom)
|
||||
binding.headerContainer.apply {
|
||||
updatePaddingRelative(bottom = paddingBottom + insetBottom)
|
||||
updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
@@ -229,19 +240,14 @@ constructor(
|
||||
1f
|
||||
}
|
||||
|
||||
val paddingScale = if (sheetOffset <= COLLAPSE_HEADER_AT_OFFSET) {
|
||||
val paddingScale = if (!isImeVisible && sheetOffset <= COLLAPSE_HEADER_AT_OFFSET) {
|
||||
((1f - sheetOffset) * 2f) - 1f
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
|
||||
val insetBottom = windowInsets?.bottom ?: 0
|
||||
|
||||
val padding = insetBottom * paddingScale
|
||||
binding.headerContainer.apply {
|
||||
var color = Color.valueOf(context.resolveAttr(R.attr.colorSurface))
|
||||
color = Color.valueOf(color.red(), color.green(), color.blue(), (1f - paddingScale))
|
||||
setBackgroundColor(color.toArgb())
|
||||
|
||||
updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
height = ((collapsedHeight + padding) * heightScale).roundToInt()
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
android:id="@+id/header_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_below="@id/border"
|
||||
android:layout_height="@dimen/editor_sheet_collapsed_height">
|
||||
android:layout_height="@dimen/editor_sheet_collapsed_height"
|
||||
android:background="?attr/colorSurface">
|
||||
|
||||
<include
|
||||
layout="@layout/layout_editor_build_status"
|
||||
|
||||
@@ -17,50 +17,43 @@
|
||||
|
||||
package com.itsaky.androidide.utils
|
||||
|
||||
import android.graphics.Insets
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
|
||||
/**
|
||||
* Acquires screen insets
|
||||
*
|
||||
* @param view Any View that is currently attached to a Window
|
||||
*
|
||||
* @return [Rect] containing acquired insets
|
||||
* Acquires screen insets.
|
||||
*
|
||||
* @param view Any View that is currently attached to a Window.
|
||||
* @return [Insets] containing acquired insets.
|
||||
* @author Smooth E
|
||||
*/
|
||||
fun getSystemBarInsets(view: View): Rect {
|
||||
val insets: Rect
|
||||
fun getSystemBarInsets(view: View): Insets {
|
||||
val rootWindowInsets = view.rootWindowInsets
|
||||
return getSystemBarInsets(WindowInsetsCompat.toWindowInsetsCompat(rootWindowInsets))
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
|
||||
val receivedInsets: Insets = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val typeMask = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
|
||||
rootWindowInsets.getInsetsIgnoringVisibility(typeMask)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
view.rootWindowInsets.stableInsets
|
||||
}
|
||||
|
||||
insets = Rect(
|
||||
receivedInsets.left,
|
||||
receivedInsets.top,
|
||||
receivedInsets.right,
|
||||
receivedInsets.bottom
|
||||
)
|
||||
} else {
|
||||
/**
|
||||
* Acquires system bar and display cutout insets.
|
||||
*
|
||||
* @param insets The window insets.
|
||||
* @return [Insets] containing acquired insets.
|
||||
*/
|
||||
fun getSystemBarInsets(insets: WindowInsetsCompat): Insets {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
@Suppress("DEPRECATION")
|
||||
insets = Rect(
|
||||
rootWindowInsets.stableInsetLeft,
|
||||
rootWindowInsets.stableInsetTop,
|
||||
rootWindowInsets.stableInsetRight,
|
||||
rootWindowInsets.stableInsetBottom
|
||||
)
|
||||
return insets.stableInsets
|
||||
}
|
||||
|
||||
return insets
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||
@Suppress("DEPRECATION")
|
||||
return insets.stableInsets
|
||||
}
|
||||
|
||||
val typeMask = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
|
||||
|
||||
// noinspection WrongConstant
|
||||
return insets.getInsetsIgnoringVisibility(typeMask)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user