-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Declare and implement a new v2.ScrollbarAdapter #368
Conversation
I will probably also add tests (or a way to test) whether implementations of the old |
@@ -128,9 +127,10 @@ fun defaultScrollbarStyle() = ScrollbarStyle( | |||
* @param interactionSource [MutableInteractionSource] that will be used to dispatch | |||
* [DragInteraction.Start] when this Scrollbar is being dragged. | |||
*/ | |||
@Deprecated("Use androidx.compose.foundation.v2.VerticalScrollbar instead") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to add replaceWith
, so IDEA can replace automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried, but it doesn't work well. If I use
replaceWith = ReplaceWith(
expression = "androidx.compose.foundation.v2.VerticalScrollbar"
)
or
replaceWith = ReplaceWith(
expression = "androidx.compose.foundation.v2.VerticalScrollbar(adapter, modifier, reverseLayout, style, interactionSource)"
)
it breaks the code completely.
If I use
replaceWith = ReplaceWith(
expression = "VerticalScrollbar(adapter, modifier, reverseLayout, style, interactionSource)",
"androidx.compose.foundation.v2.VerticalScrollbar"
)
It updates the code "correctly" (only re-arranging the order of arguments), but it doesn't even add (much less replace) the import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have an idea. Nevertheless what we decide to do with JvmName
approach - we don't create androidx.compose.foundation.v2.VerticalScrollbar
, we just add overload androidx.compose.foundation.VerticalScrollbar(androidx.compose.foundation.v2.ScrollbarAdapter)
In this case, users can just replace rememberScrollbarAdapter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I we don't add JvmName's, I would describe the proper migration guide in rememberScrollbarAdapter
message: Edit -> Find -> Replace in file -> replace "androidx.compose.foundation.rememberScrollbarAdapter" to "androidx.compose.foundation.v2.rememberScrollbarAdapter"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the latest code.
compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
Show resolved
Hide resolved
@@ -174,9 +174,10 @@ fun VerticalScrollbar( | |||
* @param interactionSource [MutableInteractionSource] that will be used to dispatch | |||
* [DragInteraction.Start] when this Scrollbar is being dragged. | |||
*/ | |||
@Deprecated("Use androidx.compose.foundation.v2.HorizontalScrollbar instead") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, replace deprecated API in our internal example (example1/Main.jvm.kt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need, after the changes to VerticalScrollbar
and rememberScrollbarAdapter
.
* limitations under the License. | ||
*/ | ||
|
||
package androidx.compose.foundation.v2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have an idea. We can use JvmName
to not force users to change their code.
We can keep the old names and package, and still preserve the backward compatibility on binary level:
package androidx.compose.foundation
@JvmName("ScrollbarAdapter")
@Deprecated
interface ScrollbarAdapter1
@JvmName("ScrollbarAdapter2")
interface ScrollbarAdapter
We lose source compatibility though, but only in few cases, when users use custom implementation of ScrollbarAdapter
. After they update version of Compose, they have to change interface to ScrollbarAdapter1, or provide viewportSize
somehow. But it is better than forcing the majority of users who don't use custom adapters to replace deprecated calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea but unfortunately JvmName
doesn't currently work for interfaces: https://youtrack.jetbrains.com/issue/KT-31420/Support-JvmName-on-interface-or-provide-other-interface-evolution-mechanism
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use it for just rememberScrollbarAdapter/VerticalScrollbar, and create only v2.ScrollbarAdapter
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -650,11 +695,12 @@ class ScrollbarTest { | |||
} | |||
} | |||
|
|||
@Suppress("DEPRECATION") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will probably also add tests (or a way to test) whether implementations of the old ScrollbarAdapter interface still work correctly.
It seems we still test the old functions here? How does thumb size on scrollbar smaller than viewport
pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually using the new implementation behind the scenes.
ScrollbarAdapter(state)
returns NewAdapterAsOld(NewScrollbarAdapter(scrollState))
and then when you pass it to Scrollbar
, it just unwraps the new adapter:
private fun ScrollbarAdapter.asNewAdapter(trackSize: Int) =
if (this is NewAdapterAsOld)
this.newAdapter // Just unwrap
else
OldAdapterAsNew(this, trackSize)
So existing code will automatically use the new implementation, and will enjoy the fix (unless it actually implements the old ScrollbarAdapter
itself).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also means that I need to come up with a good way to test whether the old adapter really works when it's wrapped into OldAdapterAsNew
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice trick :).
Let's change code to the new API though, it is always better to test what users will use directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now testing both new and old code.
…ish between scrollbar (track) size and scrollable viewport size.
… than Float, to allow for very large content.
…alues do not necessarily represent pixels.
571728b
to
19783c2
Compare
…rollbarAdapter and ScrollbarAdapter creator functions.
Added testing of "old" The only remaining untested code is
|
…wportSize after it's merged upstream.
/** | ||
* Size of the viewport on the scrollable axis, or -1 if still unknown. | ||
*/ | ||
internal var viewportSize: Int by mutableStateOf(-1, structuralEqualityPolicy()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0 is more appropriate here, it won't mess with calculations that we can perform before the layout stage. We don't perform such calculations though (and shouldn't), so it is just a minor issue. If we would make it public, then it definitely should be not -1, it always hard to reason about magic constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started with 0 at first, but then I thought that -1 would be better as it lets the developer know that it's not a known value yet. 0 is theoretically a legal value for the viewport size, so he wouldn't be able to tell between "unknown" and "known and is 0".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I noticed that I wasn't checking it correctly for -1, so I should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to 0, as the Googler(s) also preferred it.
…barAdapter (#368) Declare and implement a new, v2.ScrollbarAdapter in order to distinguish between scrollbar (track) size and scrollable viewport size.
... in order to distinguish between scrollbar (track) size and scrollable viewport size.
Proposed Changes
ScrollbarAdapter
interface inandroidx.compose.foundation.v2
contentSize
andviewportSize
.maxScrollOffset
will be implemented as an extension function.ScrollState.viewportSize
in order to support the newScrollbarAdapter
implementation for a regular scrollable container.ScrollbarAdapter
forScrollState
and forLazyListState
.Copy all public functions inandroidx.compose.foundation.Scrollbar
to the newandroidx.compose.foundation.v2.Scrollbar
and mark all the old ones as deprecated.@JvmName
and partial source backwards compatibility by naming the new functions the same as the old ones. The only exception is the scrollbar adapter interface itself, for which the users will need to change the import fromandroidx.compose.foundation
toandroidx.compose.foundation.v2
Testing
Test: Manually and with new unit tests.
Issues Fixed
Fixes: JetBrains/compose-multiplatform#2605