Merge "Carry TextMeasurer parameters to CompositionLocal reads in rememberTextMeasurer." into androidx-main
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index 9a367b3..3d2edd4 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -725,10 +725,6 @@
// handled by the application.
applyApplicationSpecificConfig(false,
/* isLocalesApplicationRequired */ false);
-
- // We may have just changed the resource configuration. Make sure that everyone after us
- // sees the same configuration by modifying the parameter's internal state.
- newConfig.updateFrom(mContext.getResources().getConfiguration());
}
@Override
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
index ec6723c..01cb197 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
@@ -600,7 +600,8 @@
}
boolean contentsChanged = true;
- if (existBefore && existAfter && contentBefore.equals(contentAfter)) {
+ if (contentBefore != null
+ && contentBefore.equals(contentAfter)) {
contentsChanged = false;
}
@@ -993,7 +994,7 @@
} finally {
mReadWriteLock.writeLock().unlock();
- if (logger != null) {
+ if (pStatsBuilder != null && logger != null) {
long totalEndTimeMillis = SystemClock.elapsedRealtime();
pStatsBuilder.setTotalLatencyMillis(
(int) (totalEndTimeMillis - totalStartTimeMillis));
@@ -1112,7 +1113,8 @@
DocumentProto.Builder documentBuilder = documentProto.toBuilder();
removePrefixesFromDocument(documentBuilder);
String prefix = createPrefix(packageName, databaseName);
- Map<String, SchemaTypeConfigProto> schemaTypeMap = mSchemaMapLocked.get(prefix);
+ Map<String, SchemaTypeConfigProto> schemaTypeMap =
+ Preconditions.checkNotNull(mSchemaMapLocked.get(prefix));
return GenericDocumentToProtoConverter.toGenericDocument(documentBuilder.build(),
prefix, schemaTypeMap);
} finally {
@@ -1153,7 +1155,8 @@
// The schema type map cannot be null at this point. It could only be null if no
// schema had ever been set for that prefix. Given we have retrieved a document from
// the index, we know a schema had to have been set.
- Map<String, SchemaTypeConfigProto> schemaTypeMap = mSchemaMapLocked.get(prefix);
+ Map<String, SchemaTypeConfigProto> schemaTypeMap =
+ Preconditions.checkNotNull(mSchemaMapLocked.get(prefix));
return GenericDocumentToProtoConverter.toGenericDocument(documentBuilder.build(),
prefix, schemaTypeMap);
} finally {
@@ -1250,7 +1253,7 @@
if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
// Client wanted to query over some packages that weren't its own. This isn't
// allowed through local query so we can return early with no results.
- if (logger != null) {
+ if (sStatsBuilder != null && logger != null) {
sStatsBuilder.setStatusCode(AppSearchResult.RESULT_SECURITY_ERROR);
}
return new SearchResultPage(Bundle.EMPTY);
@@ -1274,7 +1277,7 @@
return searchResultPage;
} finally {
mReadWriteLock.readLock().unlock();
- if (logger != null) {
+ if (sStatsBuilder != null && logger != null) {
sStatsBuilder.setTotalLatencyMillis(
(int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
logger.logStats(sStatsBuilder.build());
@@ -1353,7 +1356,7 @@
} finally {
mReadWriteLock.readLock().unlock();
- if (logger != null) {
+ if (sStatsBuilder != null && logger != null) {
sStatsBuilder.setTotalLatencyMillis(
(int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
logger.logStats(sStatsBuilder.build());
@@ -1560,7 +1563,9 @@
// Since the new token is 0, this is the last page. We should remove the old token
// from our cache since it no longer refers to this query.
synchronized (mNextPageTokensLocked) {
- mNextPageTokensLocked.get(packageName).remove(nextPageToken);
+ Set<Long> nextPageTokensForPackage =
+ Preconditions.checkNotNull(mNextPageTokensLocked.get(packageName));
+ nextPageTokensForPackage.remove(nextPageToken);
}
}
long rewriteSearchResultLatencyStartMillis = SystemClock.elapsedRealtime();
@@ -2196,8 +2201,11 @@
for (String databaseName : databaseNames) {
String removedPrefix = createPrefix(packageName, databaseName);
Map<String, SchemaTypeConfigProto> removedSchemas =
- mSchemaMapLocked.remove(removedPrefix);
- mVisibilityStoreLocked.removeVisibility(removedSchemas.keySet());
+ Preconditions.checkNotNull(mSchemaMapLocked.remove(removedPrefix));
+ if (mVisibilityStoreLocked != null) {
+ mVisibilityStoreLocked.removeVisibility(removedSchemas.keySet());
+ }
+
mNamespaceMapLocked.remove(removedPrefix);
}
}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
index a139d3b..c6731d1 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -184,8 +184,9 @@
documentBuilder.setPropertyDocument(name, values);
} else {
// TODO(b/184966497): Optimize by caching PropertyConfigProto
- setEmptyProperty(name, documentBuilder,
- schemaTypeMap.get(prefixedSchemaType));
+ SchemaTypeConfigProto schema =
+ Preconditions.checkNotNull(schemaTypeMap.get(prefixedSchemaType));
+ setEmptyProperty(name, documentBuilder, schema);
}
}
return documentBuilder.build();
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
index de42623..e985c52 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
@@ -28,6 +28,7 @@
import androidx.appsearch.app.SearchResult;
import androidx.appsearch.app.SearchResultPage;
import androidx.appsearch.exceptions.AppSearchException;
+import androidx.core.util.Preconditions;
import com.google.android.icing.proto.DocumentProto;
import com.google.android.icing.proto.SchemaTypeConfigProto;
@@ -88,7 +89,8 @@
DocumentProto.Builder documentBuilder = proto.getDocument().toBuilder();
String prefix = removePrefixesFromDocument(documentBuilder);
- Map<String, SchemaTypeConfigProto> schemaTypeMap = schemaMap.get(prefix);
+ Map<String, SchemaTypeConfigProto> schemaTypeMap =
+ Preconditions.checkNotNull(schemaMap.get(prefix));
GenericDocument document =
GenericDocumentToProtoConverter.toGenericDocument(documentBuilder, prefix,
schemaTypeMap);
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
index 537fd81..e3be791 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
@@ -95,7 +95,7 @@
*/
@NonNull
String[] getPackageNames() {
- return getPropertyStringArray(PACKAGE_NAME_PROPERTY);
+ return Preconditions.checkNotNull(getPropertyStringArray(PACKAGE_NAME_PROPERTY));
}
/**
@@ -105,7 +105,7 @@
*/
@NonNull
byte[][] getSha256Certs() {
- return getPropertyBytesArray(SHA_256_CERT_PROPERTY);
+ return Preconditions.checkNotNull(getPropertyBytesArray(SHA_256_CERT_PROPERTY));
}
/**
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
index edff437..bf1b987 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
@@ -29,6 +29,7 @@
import androidx.appsearch.localstorage.AppSearchImpl;
import androidx.appsearch.localstorage.util.PrefixUtil;
import androidx.collection.ArrayMap;
+import androidx.core.util.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
@@ -203,15 +204,19 @@
.getPropertyDocumentArray(DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY);
if (deprecatedPackageDocuments != null) {
for (GenericDocument deprecatedPackageDocument : deprecatedPackageDocuments) {
- String prefixedSchemaType = deprecatedPackageDocument
- .getPropertyString(DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY);
- VisibilityDocumentV1.Builder visibilityBuilder = getOrCreateBuilder(
- documentBuilderMap, prefixedSchemaType);
- visibilityBuilder.addVisibleToPackage(new PackageIdentifier(
+ String prefixedSchemaType = Preconditions.checkNotNull(
deprecatedPackageDocument.getPropertyString(
- DEPRECATED_PACKAGE_NAME_PROPERTY),
+ DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY));
+ VisibilityDocumentV1.Builder visibilityBuilder =
+ getOrCreateBuilder(documentBuilderMap, prefixedSchemaType);
+ String packageName = Preconditions.checkNotNull(
+ deprecatedPackageDocument.getPropertyString(
+ DEPRECATED_PACKAGE_NAME_PROPERTY));
+ byte[] sha256Cert = Preconditions.checkNotNull(
deprecatedPackageDocument.getPropertyBytes(
- DEPRECATED_SHA_256_CERT_PROPERTY)));
+ DEPRECATED_SHA_256_CERT_PROPERTY));
+ visibilityBuilder.addVisibleToPackage(
+ new PackageIdentifier(packageName, sha256Cert));
}
}
}
diff --git a/benchmark/gradle-plugin/build.gradle b/benchmark/gradle-plugin/build.gradle
index f668861..2ef57d1 100644
--- a/benchmark/gradle-plugin/build.gradle
+++ b/benchmark/gradle-plugin/build.gradle
@@ -39,7 +39,7 @@
SdkResourceGenerator.generateForHostTest(project)
-def buildOnServer = tasks.register("buildOnServer", SingleFileCopy.class) {
+def copyLockClocks = tasks.register("copyLockClocks", SingleFileCopy.class) {
def source = project.file("src/main/resources/scripts/lockClocks.sh")
if (!source.exists()) {
throw new GradleException(source.toString() + " does not exist")
@@ -47,6 +47,7 @@
it.sourceFile = source
it.destinationFile = new File(BuildServerConfigurationKt.getDistributionDirectory(rootProject), "lockClocks.sh")
}
+BuildOnServerKt.addToBuildOnServer(project, copyLockClocks)
gradlePlugin {
plugins {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index 373b053..a64d17c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -59,6 +59,7 @@
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
+import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.JavaVersion.VERSION_11
import org.gradle.api.JavaVersion.VERSION_1_8
@@ -110,6 +111,7 @@
AndroidXMultiplatformExtension.EXTENSION_NAME,
project
)
+ project.tasks.register(BUILD_ON_SERVER_TASK, DefaultTask::class.java)
// Perform different actions based on which plugins have been applied to the project.
// Many of the actions overlap, ex. API tracking.
project.plugins.all { plugin ->
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/BuildOnServer.kt b/buildSrc/public/src/main/kotlin/androidx/build/BuildOnServer.kt
index b6a8938..666dfb8 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/BuildOnServer.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/BuildOnServer.kt
@@ -26,7 +26,7 @@
* Configures the root project's buildOnServer task to run the specified task.
*/
fun <T : Task> Project.addToBuildOnServer(taskProvider: TaskProvider<T>) {
- rootProject.tasks.named(BUILD_ON_SERVER_TASK).configure {
+ tasks.named(BUILD_ON_SERVER_TASK).configure {
it.dependsOn(taskProvider)
}
}
@@ -35,7 +35,7 @@
* Configures the root project's buildOnServer task to run the specified task.
*/
fun <T : Task> Project.addToBuildOnServer(taskPath: String) {
- rootProject.tasks.named(BUILD_ON_SERVER_TASK).configure {
+ tasks.named(BUILD_ON_SERVER_TASK).configure {
it.dependsOn(taskPath)
}
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/SanityCheckCodegenTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/SanityCheckCodegenTests.kt
index 6c1f46b..572245b 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/SanityCheckCodegenTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/SanityCheckCodegenTests.kt
@@ -90,4 +90,29 @@
"""
)
}
+
+ // Regression test for KT-52843
+ fun testParameterInlineCaptureLambda() = ensureSetup {
+ testCompile(
+ """
+ import androidx.compose.runtime.Composable
+ import androidx.compose.ui.graphics.Color
+
+ @Composable
+ inline fun InlineWidget(
+ propagateMinConstraints: Boolean = false,
+ content: () -> Unit
+ ) {
+ }
+
+ @Composable
+ fun DarkThemeSample() {
+ val color = Color.Black
+ InlineWidget {
+ println(color)
+ }
+ }
+ """
+ )
+ }
}
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/OverscrollBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/OverscrollBenchmark.kt
new file mode 100644
index 0000000..82f9b23
--- /dev/null
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/OverscrollBenchmark.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.foundation.benchmark
+
+import android.view.MotionEvent
+import android.view.View
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.benchmark.lazy.MotionEventHelper
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.ScrollableDefaults
+import androidx.compose.foundation.gestures.scrollable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.overscroll
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.ToggleableTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkDrawPerf
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.compose.testutils.benchmark.benchmarkLayoutPerf
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkDraw
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkLayout
+import androidx.compose.testutils.benchmark.toggleStateBenchmarkMeasure
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class OverscrollBenchmark {
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val overscrollTestCase = { OverscrollTestCase() }
+
+ @Test
+ fun first_compose() {
+ benchmarkRule.benchmarkFirstCompose(overscrollTestCase)
+ }
+
+ @Test
+ fun first_measure() {
+ benchmarkRule.benchmarkFirstMeasure(overscrollTestCase)
+ }
+
+ @Test
+ fun first_layout() {
+ benchmarkRule.benchmarkFirstLayout(overscrollTestCase)
+ }
+
+ @Test
+ fun first_draw() {
+ benchmarkRule.benchmarkFirstDraw(overscrollTestCase)
+ }
+
+ @Test
+ fun overscroll_measure() {
+ benchmarkRule.toggleStateBenchmarkMeasure(overscrollTestCase, false)
+ }
+
+ @Test
+ fun overscroll_layout() {
+ benchmarkRule.toggleStateBenchmarkLayout(overscrollTestCase, false)
+ }
+
+ @Test
+ fun overscroll_draw() {
+ benchmarkRule.toggleStateBenchmarkDraw(overscrollTestCase, false)
+ }
+
+ @Test
+ fun layout() {
+ benchmarkRule.benchmarkLayoutPerf(overscrollTestCase)
+ }
+
+ @Test
+ fun draw() {
+ benchmarkRule.benchmarkDrawPerf(overscrollTestCase)
+ }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+private class OverscrollTestCase : LayeredComposeTestCase(), ToggleableTestCase {
+
+ private lateinit var view: View
+ private lateinit var motionEventHelper: MotionEventHelper
+
+ private var showingOverscroll = false
+
+ @Composable
+ override fun MeasuredContent() {
+ view = LocalView.current
+ if (!::motionEventHelper.isInitialized) motionEventHelper = MotionEventHelper(view)
+ val scrollState = rememberScrollState()
+ val overscrollEffect = ScrollableDefaults.overscrollEffect().apply { isEnabled = true }
+ Box(
+ Modifier
+ .scrollable(
+ scrollState,
+ orientation = Orientation.Vertical,
+ reverseDirection = true,
+ overscrollEffect = overscrollEffect
+ )
+ .overscroll(overscrollEffect)
+ .fillMaxSize()
+ ) {
+ Box(
+ Modifier
+ .offset { IntOffset(0, scrollState.value) }
+ .background(color = Color.Red)
+ .fillMaxWidth()
+ .height(100.dp))
+ }
+ }
+
+ override fun toggleState() {
+ if (!showingOverscroll) {
+ val height = view.measuredHeight
+ motionEventHelper.sendEvent(MotionEvent.ACTION_DOWN, Offset(x = 0f, y = height / 4f))
+ motionEventHelper.sendEvent(MotionEvent.ACTION_MOVE, Offset(x = 0f, y = height / 8f))
+ showingOverscroll = true
+ } else {
+ motionEventHelper.sendEvent(MotionEvent.ACTION_UP, Offset.Zero)
+ showingOverscroll = false
+ }
+ }
+}
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
index 578c8622..d3f66c9 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyListScrollingBenchmark.kt
@@ -41,6 +41,7 @@
import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
import androidx.compose.testutils.doFramesUntilNoChangesPending
import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
@@ -276,6 +277,7 @@
private lateinit var listState: LazyListState
private lateinit var view: View
+ private lateinit var motionEventHelper: MotionEventHelper
private var touchSlop: Float = 0f
private var scrollBy: Int = 0
@@ -292,6 +294,7 @@
5
}
view = LocalView.current
+ if (!::motionEventHelper.isInitialized) motionEventHelper = MotionEventHelper(view)
touchSlop = LocalViewConfiguration.current.touchSlop
listState = rememberLazyListState()
content(listState)
@@ -308,8 +311,8 @@
}
if (usePointerInput) {
val size = if (isVertical) view.measuredHeight else view.measuredWidth
- sendEvent(MotionEvent.ACTION_DOWN, size / 2f)
- sendEvent(MotionEvent.ACTION_MOVE, touchSlop)
+ motionEventHelper.sendEvent(MotionEvent.ACTION_DOWN, (size / 2f).toSingleAxisOffset())
+ motionEventHelper.sendEvent(MotionEvent.ACTION_MOVE, touchSlop.toSingleAxisOffset())
}
assertEquals(0, listState.firstVisibleItemIndex)
assertEquals(0, listState.firstVisibleItemScrollOffset)
@@ -317,7 +320,8 @@
fun toggle() {
if (usePointerInput) {
- sendEvent(MotionEvent.ACTION_MOVE, -scrollBy.toFloat())
+ motionEventHelper
+ .sendEvent(MotionEvent.ACTION_MOVE, -scrollBy.toFloat().toSingleAxisOffset())
} else {
runBlocking {
listState.scrollBy(scrollBy.toFloat())
@@ -329,25 +333,35 @@
assertEquals(0, listState.firstVisibleItemIndex)
assertEquals(scrollBy, listState.firstVisibleItemScrollOffset)
if (usePointerInput) {
- sendEvent(MotionEvent.ACTION_UP, 0f)
+ motionEventHelper.sendEvent(MotionEvent.ACTION_UP, Offset.Zero)
}
}
- private var time = 0L
- private var lastCoord: Float? = null
+ private fun Float.toSingleAxisOffset(): Offset =
+ Offset(x = if (isVertical) 0f else this, y = if (isVertical) this else 0f)
+}
- private fun sendEvent(
+data class ListItem(val index: Int)
+
+/**
+ * Helper for dispatching simple [MotionEvent]s to a [view] for use in scrolling benchmarks.
+ */
+class MotionEventHelper(private val view: View) {
+ private var time = 0L
+ private var lastCoord: Offset? = null
+
+ fun sendEvent(
action: Int,
- delta: Float
+ delta: Offset
) {
time += 10L
- val coord = delta + (lastCoord ?: 0f)
+ val coord = delta + (lastCoord ?: Offset.Zero)
- if (action == MotionEvent.ACTION_UP) {
- lastCoord = null
+ lastCoord = if (action == MotionEvent.ACTION_UP) {
+ null
} else {
- lastCoord = coord
+ coord
}
val locationOnScreen = IntArray(2) { 0 }
@@ -361,8 +375,8 @@
arrayOf(MotionEvent.PointerProperties()),
arrayOf(
MotionEvent.PointerCoords().apply {
- this.x = locationOnScreen[0] + if (!isVertical) coord else 1f
- this.y = locationOnScreen[1] + if (isVertical) coord else 1f
+ x = locationOnScreen[0] + coord.x.coerceAtLeast(1f)
+ y = locationOnScreen[1] + coord.y.coerceAtLeast(1f)
}
),
0,
@@ -380,5 +394,3 @@
view.dispatchTouchEvent(motionEvent)
}
}
-
-data class ListItem(val index: Int)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
index 471a5f4..3b0461a 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
@@ -34,7 +34,6 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -51,12 +50,17 @@
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.layout
+import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.toSize
import kotlin.math.roundToInt
@Preview(showBackground = true)
@@ -92,11 +96,13 @@
FocusGrabber(Modifier.fillMaxWidth())
+ var maxViewportSize by remember { mutableStateOf(IntSize.Zero) }
Resizable(
resizableState,
Modifier
.weight(1f)
.fillMaxWidth()
+ .onSizeChanged { maxViewportSize = it }
) {
Box(
Modifier
@@ -106,9 +112,11 @@
) {
Box(
Modifier
- .size(300.dp)
+ // Ensure there's always something to scroll by making the scrollable
+ // content a multiple of the available screen space.
+ .size { maxViewportSize.toSize() * 1.5f }
.background(Color.LightGray)
- .wrapContentSize(align = Alignment.BottomEnd)
+ .wrapContentSize(align = Alignment.Center)
) {
FocusGrabber()
}
@@ -248,4 +256,15 @@
drawLine(Color.Black, Offset(x2, startY), Offset(x2, endY), lineWeight)
}
}
+}
+
+/** Measures the modified node to be the size returned from [size]. */
+private fun Modifier.size(size: () -> Size): Modifier = layout { measurable, _ ->
+ val constraints = size().let {
+ Constraints.fixed(it.width.roundToInt(), it.height.roundToInt())
+ }
+ val placeable = measurable.measure(constraints)
+ layout(placeable.width, placeable.height) {
+ placeable.place(IntOffset.Zero)
+ }
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyNearestItemsRange.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyNearestItemsRange.kt
index c602a6c..7b6d6ae 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyNearestItemsRange.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyNearestItemsRange.kt
@@ -18,10 +18,12 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
-import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.structuralEqualityPolicy
+import androidx.compose.runtime.snapshotFlow
+import androidx.compose.runtime.snapshots.Snapshot
/**
* Calculate and memoize range of indexes which contains at least [extraItemCount] items near
@@ -41,17 +43,34 @@
firstVisibleItemIndex: () -> Int,
slidingWindowSize: () -> Int,
extraItemCount: () -> Int
-): State<IntRange> =
- remember(firstVisibleItemIndex, slidingWindowSize, extraItemCount) {
- derivedStateOf(structuralEqualityPolicy()) {
+): State<IntRange> {
+ val state = remember(firstVisibleItemIndex, slidingWindowSize, extraItemCount) {
+ Snapshot.withoutReadObservation {
+ mutableStateOf(
+ calculateNearestItemsRange(
+ firstVisibleItemIndex(),
+ slidingWindowSize(),
+ extraItemCount()
+ )
+ )
+ }
+ }
+
+ LaunchedEffect(state) {
+ snapshotFlow {
calculateNearestItemsRange(
firstVisibleItemIndex(),
slidingWindowSize(),
extraItemCount()
)
+ }.collect {
+ state.value = it
}
}
+ return state
+}
+
/**
* Returns a range of indexes which contains at least [extraItemCount] items near
* the first visible item. It is optimized to return the same range for small changes in the
diff --git a/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/ui/specification/SpecificationTopAppBar.kt b/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/ui/specification/SpecificationTopAppBar.kt
index deee833..93f2baf 100644
--- a/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/ui/specification/SpecificationTopAppBar.kt
+++ b/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/ui/specification/SpecificationTopAppBar.kt
@@ -16,6 +16,7 @@
package androidx.compose.material.catalog.ui.specification
+import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.only
@@ -23,14 +24,18 @@
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
+import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -38,10 +43,12 @@
title: String,
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
- val backgroundColors = TopAppBarDefaults.centerAlignedTopAppBarColors()
- val backgroundColor = backgroundColors.containerColor(
- colorTransitionFraction = scrollBehavior?.state?.overlappedFraction ?: 0f
- ).value
+ val backgroundColor = lerp(
+ MaterialTheme.colorScheme.surface,
+ MaterialTheme.colorScheme.surfaceColorAtElevation(elevation = 3.dp),
+ FastOutLinearInEasing.transform(scrollBehavior?.state?.overlappedFraction ?: 0f)
+ )
+
val foregroundColors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SelectionControlsDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SelectionControlsDemo.kt
index 127a3dc..c8343cf 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SelectionControlsDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/SelectionControlsDemo.kt
@@ -21,6 +21,7 @@
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
+import androidx.compose.material.samples.FocusedCheckboxSample
import androidx.compose.material.samples.RadioButtonSample
import androidx.compose.material.samples.RadioGroupSample
import androidx.compose.material.samples.SwitchSample
@@ -40,6 +41,10 @@
TriStateCheckboxSample()
}
item {
+ Text(text = "Programmatically focused checkbox", style = headerStyle)
+ FocusedCheckboxSample()
+ }
+ item {
Text(text = "Switch", style = headerStyle)
SwitchSample()
}
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
index af94e92..8550650 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
@@ -24,8 +24,10 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.foundation.layout.Box
import androidx.compose.material.Checkbox
import androidx.compose.material.CheckboxDefaults
import androidx.compose.material.MaterialTheme
@@ -35,14 +37,20 @@
import androidx.compose.material.TriStateCheckbox
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode.Companion.Keyboard
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.ExperimentalComposeUiApi
@Sampled
@Composable
@@ -81,6 +89,29 @@
}
}
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun FocusedCheckboxSample() {
+ Text("The gray circle around this checkbox means it's non-touch focused. Press Tab to move it")
+
+ val focusRequester = FocusRequester()
+ Box(Modifier.wrapContentSize(Alignment.TopStart)) {
+ Checkbox(
+ modifier = Modifier.wrapContentSize(Alignment.TopStart)
+ .focusRequester(focusRequester),
+ checked = true,
+ onCheckedChange = { }
+ )
+ }
+
+ val localInputModeManager = LocalInputModeManager.current
+ LaunchedEffect(Unit) {
+ if (localInputModeManager.requestInputMode(Keyboard)) {
+ focusRequester.requestFocus()
+ }
+ }
+}
+
@Sampled
@Composable
fun CheckboxSample() {
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonScreenshotTest.kt
index a6b23b8..3843974 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonScreenshotTest.kt
@@ -20,10 +20,13 @@
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.hasClickAction
@@ -123,21 +126,22 @@
@Test
fun focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent {
+ localInputModeManager = LocalInputModeManager.current
Box(Modifier.requiredSize(200.dp, 100.dp).wrapContentSize()) {
Button(
onClick = { },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) { }
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxScreenshotTest.kt
index 7a60df7..09788e3 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxScreenshotTest.kt
@@ -21,10 +21,13 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.test.ExperimentalTestApi
@@ -229,14 +232,13 @@
@Test
fun checkBoxTest_focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
Checkbox(
modifier = wrap
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester),
checked = true,
onCheckedChange = { }
@@ -245,6 +247,8 @@
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonScreenshotTest.kt
index 47e9598..d292d7e 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonScreenshotTest.kt
@@ -22,10 +22,13 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.hasClickAction
@@ -144,15 +147,14 @@
@Test
fun focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent {
+ localInputModeManager = LocalInputModeManager.current
Box(Modifier.requiredSize(100.dp, 100.dp).wrapContentSize()) {
FloatingActionButton(
onClick = { },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Icon(Icons.Filled.Favorite, contentDescription = null)
@@ -161,6 +163,8 @@
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonScreenshotTest.kt
index 927efa9..41269e3 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonScreenshotTest.kt
@@ -23,10 +23,14 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputMode.Companion.Keyboard
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
@@ -116,25 +120,28 @@
@Test
fun radioButtonTest_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
RadioButton(
selected = false,
onClick = {},
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
)
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
+ rule.waitForIdle()
+
assertSelectableAgainstGolden("radioButton_focused")
}
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
index 1727e8c..413caf8 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
@@ -25,10 +25,13 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
@@ -256,22 +259,23 @@
@Test
fun switchTest_focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent {
+ localInputModeManager = LocalInputModeManager.current
Box(wrapperModifier) {
Switch(
checked = true,
onCheckedChange = { },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
)
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 20967a5..f0037a4 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -49,15 +49,7 @@
field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
}
- public static final class BottomAppBarDefaults.BottomAppBarFabElevation implements androidx.compose.material3.FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- field public static final androidx.compose.material3.BottomAppBarDefaults.BottomAppBarFabElevation INSTANCE;
- }
-
- @androidx.compose.runtime.Stable public interface ButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class ButtonColors {
}
public final class ButtonDefaults {
@@ -98,9 +90,7 @@
field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface ButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public final class ButtonElevation {
}
public final class ButtonKt {
@@ -111,9 +101,7 @@
method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CardColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class CardColors {
}
public final class CardDefaults {
@@ -133,9 +121,7 @@
field public static final androidx.compose.material3.CardDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface CardElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
+ @androidx.compose.runtime.Immutable public final class CardElevation {
}
public final class CardKt {
@@ -144,10 +130,7 @@
method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CheckboxColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> boxColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> checkmarkColor(androidx.compose.ui.state.ToggleableState state);
+ @androidx.compose.runtime.Immutable public final class CheckboxColors {
}
public final class CheckboxDefaults {
@@ -266,6 +249,7 @@
}
public final class FloatingActionButtonDefaults {
+ method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
@@ -283,9 +267,7 @@
field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
}
public final class FloatingActionButtonKt {
@@ -296,9 +278,7 @@
method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface IconButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class IconButtonColors {
}
public final class IconButtonDefaults {
@@ -336,9 +316,7 @@
method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
}
- @androidx.compose.runtime.Stable public interface IconToggleButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
}
public final class IncludeFontPaddingHelper_androidKt {
@@ -368,10 +346,7 @@
field public static final androidx.compose.material3.MenuDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface MenuItemColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class MenuItemColors {
}
public final class MenuKt {
@@ -385,11 +360,7 @@
field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationBarItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
}
public final class NavigationBarItemDefaults {
@@ -411,11 +382,7 @@
field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationRailItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
}
public final class NavigationRailItemDefaults {
@@ -452,8 +419,7 @@
method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
}
- @androidx.compose.runtime.Stable public interface RadioButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> radioColor(boolean enabled, boolean selected);
+ @androidx.compose.runtime.Immutable public final class RadioButtonColors {
}
public final class RadioButtonDefaults {
@@ -500,10 +466,7 @@
public final class ShapesKt {
}
- @androidx.compose.runtime.Stable public interface SliderColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+ @androidx.compose.runtime.Immutable public final class SliderColors {
}
public final class SliderDefaults {
@@ -592,11 +555,7 @@
public final class SwipeableKt {
}
- @androidx.compose.runtime.Stable public interface SwitchColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class SwitchColors {
}
public final class SwitchDefaults {
@@ -640,6 +599,9 @@
method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
}
+ @androidx.compose.runtime.Immutable public final class TextFieldColors {
+ }
+
public final class TextFieldDefaultsKt {
}
@@ -660,11 +622,7 @@
public final class TonalPaletteKt {
}
- @androidx.compose.runtime.Stable public interface TopAppBarColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> actionIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> navigationIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> titleContentColor(float colorTransitionFraction);
+ @androidx.compose.runtime.Stable public final class TopAppBarColors {
}
public final class TopAppBarDefaults {
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index 9982e90..506f98f 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -77,15 +77,7 @@
field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
}
- public static final class BottomAppBarDefaults.BottomAppBarFabElevation implements androidx.compose.material3.FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- field public static final androidx.compose.material3.BottomAppBarDefaults.BottomAppBarFabElevation INSTANCE;
- }
-
- @androidx.compose.runtime.Stable public interface ButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class ButtonColors {
}
public final class ButtonDefaults {
@@ -126,9 +118,7 @@
field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface ButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public final class ButtonElevation {
}
public final class ButtonKt {
@@ -139,9 +129,7 @@
method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CardColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class CardColors {
}
public final class CardDefaults {
@@ -161,9 +149,7 @@
field public static final androidx.compose.material3.CardDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface CardElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
+ @androidx.compose.runtime.Immutable public final class CardElevation {
}
public final class CardKt {
@@ -175,10 +161,7 @@
method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CheckboxColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> boxColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> checkmarkColor(androidx.compose.ui.state.ToggleableState state);
+ @androidx.compose.runtime.Immutable public final class CheckboxColors {
}
public final class CheckboxDefaults {
@@ -191,20 +174,13 @@
method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface ChipBorder {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.foundation.BorderStroke> borderStroke(boolean enabled);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ChipBorder {
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface ChipColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconContentColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconContentColor(boolean enabled);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ChipColors {
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface ChipElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ChipElevation {
}
public final class ChipKt {
@@ -412,6 +388,7 @@
}
public final class FloatingActionButtonDefaults {
+ method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
@@ -429,9 +406,7 @@
field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
}
public final class FloatingActionButtonKt {
@@ -442,9 +417,7 @@
method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface IconButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class IconButtonColors {
}
public final class IconButtonDefaults {
@@ -482,9 +455,7 @@
method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
}
- @androidx.compose.runtime.Stable public interface IconToggleButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
}
public final class IncludeFontPaddingHelper_androidKt {
@@ -505,13 +476,7 @@
field public static final androidx.compose.material3.InputChipDefaults INSTANCE;
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface ListItemColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> headlineColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> overlineColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> supportingColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class ListItemColors {
}
@androidx.compose.material3.ExperimentalMaterial3Api public final class ListItemDefaults {
@@ -552,10 +517,7 @@
field public static final androidx.compose.material3.MenuDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface MenuItemColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class MenuItemColors {
}
public final class MenuKt {
@@ -569,11 +531,7 @@
field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationBarItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
}
public final class NavigationBarItemDefaults {
@@ -617,11 +575,7 @@
field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationRailItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
}
public final class NavigationRailItemDefaults {
@@ -660,8 +614,7 @@
method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
}
- @androidx.compose.runtime.Stable public interface RadioButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> radioColor(boolean enabled, boolean selected);
+ @androidx.compose.runtime.Immutable public final class RadioButtonColors {
}
public final class RadioButtonDefaults {
@@ -677,20 +630,13 @@
method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional long containerColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableChipBorder {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.foundation.BorderStroke> borderStroke(boolean enabled, boolean selected);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipBorder {
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableChipColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled, boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconContentColor(boolean enabled, boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconContentColor(boolean enabled, boolean selected);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipColors {
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableChipElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, boolean selected, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, boolean selected, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
}
public final class ShapeDefaults {
@@ -725,10 +671,7 @@
public final class ShapesKt {
}
- @androidx.compose.runtime.Stable public interface SliderColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+ @androidx.compose.runtime.Immutable public final class SliderColors {
}
public final class SliderDefaults {
@@ -837,11 +780,7 @@
public final class SwipeableKt {
}
- @androidx.compose.runtime.Stable public interface SwitchColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class SwitchColors {
}
public final class SwitchDefaults {
@@ -885,17 +824,7 @@
method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
}
- @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface TextFieldColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> cursorColor(boolean isError);
- method @androidx.compose.runtime.Composable public androidx.compose.foundation.text.selection.TextSelectionColors getSelectionColors();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> indicatorColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> placeholderColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- property @androidx.compose.runtime.Composable public abstract androidx.compose.foundation.text.selection.TextSelectionColors selectionColors;
+ @androidx.compose.runtime.Immutable public final class TextFieldColors {
}
@androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
@@ -945,11 +874,7 @@
public final class TonalPaletteKt {
}
- @androidx.compose.runtime.Stable public interface TopAppBarColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> actionIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> navigationIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> titleContentColor(float colorTransitionFraction);
+ @androidx.compose.runtime.Stable public final class TopAppBarColors {
}
public final class TopAppBarDefaults {
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 20967a5..f0037a4 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -49,15 +49,7 @@
field public static final androidx.compose.material3.BottomAppBarDefaults INSTANCE;
}
- public static final class BottomAppBarDefaults.BottomAppBarFabElevation implements androidx.compose.material3.FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.MutableState<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- field public static final androidx.compose.material3.BottomAppBarDefaults.BottomAppBarFabElevation INSTANCE;
- }
-
- @androidx.compose.runtime.Stable public interface ButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class ButtonColors {
}
public final class ButtonDefaults {
@@ -98,9 +90,7 @@
field public static final androidx.compose.material3.ButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface ButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public final class ButtonElevation {
}
public final class ButtonKt {
@@ -111,9 +101,7 @@
method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CardColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class CardColors {
}
public final class CardDefaults {
@@ -133,9 +121,7 @@
field public static final androidx.compose.material3.CardDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface CardElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource? interactionSource);
+ @androidx.compose.runtime.Immutable public final class CardElevation {
}
public final class CardKt {
@@ -144,10 +130,7 @@
method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface CheckboxColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> boxColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> checkmarkColor(androidx.compose.ui.state.ToggleableState state);
+ @androidx.compose.runtime.Immutable public final class CheckboxColors {
}
public final class CheckboxDefaults {
@@ -266,6 +249,7 @@
}
public final class FloatingActionButtonDefaults {
+ method public androidx.compose.material3.FloatingActionButtonElevation bottomAppBarFabElevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getExtendedFabShape();
@@ -283,9 +267,7 @@
field public static final androidx.compose.material3.FloatingActionButtonDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> shadowElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> tonalElevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+ @androidx.compose.runtime.Stable public class FloatingActionButtonElevation {
}
public final class FloatingActionButtonKt {
@@ -296,9 +278,7 @@
method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
- @androidx.compose.runtime.Stable public interface IconButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class IconButtonColors {
}
public final class IconButtonDefaults {
@@ -336,9 +316,7 @@
method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
}
- @androidx.compose.runtime.Stable public interface IconToggleButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
}
public final class IncludeFontPaddingHelper_androidKt {
@@ -368,10 +346,7 @@
field public static final androidx.compose.material3.MenuDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface MenuItemColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled);
+ @androidx.compose.runtime.Immutable public final class MenuItemColors {
}
public final class MenuKt {
@@ -385,11 +360,7 @@
field public static final androidx.compose.material3.NavigationBarDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationBarItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
}
public final class NavigationBarItemDefaults {
@@ -411,11 +382,7 @@
field public static final androidx.compose.material3.NavigationRailDefaults INSTANCE;
}
- @androidx.compose.runtime.Stable public interface NavigationRailItemColors {
- method @androidx.compose.runtime.Composable public long getIndicatorColor();
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean selected);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean selected);
- property @androidx.compose.runtime.Composable public abstract long indicatorColor;
+ @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
}
public final class NavigationRailItemDefaults {
@@ -452,8 +419,7 @@
method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long trackColor);
}
- @androidx.compose.runtime.Stable public interface RadioButtonColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> radioColor(boolean enabled, boolean selected);
+ @androidx.compose.runtime.Immutable public final class RadioButtonColors {
}
public final class RadioButtonDefaults {
@@ -500,10 +466,7 @@
public final class ShapesKt {
}
- @androidx.compose.runtime.Stable public interface SliderColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+ @androidx.compose.runtime.Immutable public final class SliderColors {
}
public final class SliderDefaults {
@@ -592,11 +555,7 @@
public final class SwipeableKt {
}
- @androidx.compose.runtime.Stable public interface SwitchColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> iconColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
+ @androidx.compose.runtime.Immutable public final class SwitchColors {
}
public final class SwitchDefaults {
@@ -640,6 +599,9 @@
method @androidx.compose.runtime.Composable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material3.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
}
+ @androidx.compose.runtime.Immutable public final class TextFieldColors {
+ }
+
public final class TextFieldDefaultsKt {
}
@@ -660,11 +622,7 @@
public final class TonalPaletteKt {
}
- @androidx.compose.runtime.Stable public interface TopAppBarColors {
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> actionIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> containerColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> navigationIconContentColor(float colorTransitionFraction);
- method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> titleContentColor(float colorTransitionFraction);
+ @androidx.compose.runtime.Stable public final class TopAppBarColors {
}
public final class TopAppBarDefaults {
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/common/CatalogTopAppBar.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/common/CatalogTopAppBar.kt
index 72bcdfc..2241a8b 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/common/CatalogTopAppBar.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/common/CatalogTopAppBar.kt
@@ -16,6 +16,7 @@
package androidx.compose.material3.catalog.library.ui.common
+import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
@@ -39,6 +40,7 @@
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.catalog.library.R
+import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -46,9 +48,11 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -67,10 +71,11 @@
onLicensesClick: () -> Unit = {}
) {
var moreMenuExpanded by remember { mutableStateOf(false) }
- val backgroundColors = TopAppBarDefaults.smallTopAppBarColors()
- val backgroundColor = backgroundColors.containerColor(
- colorTransitionFraction = scrollBehavior?.state?.overlappedFraction ?: 0f
- ).value
+ val backgroundColor = lerp(
+ MaterialTheme.colorScheme.surface,
+ MaterialTheme.colorScheme.surfaceColorAtElevation(elevation = 3.dp),
+ FastOutLinearInEasing.transform(scrollBehavior?.state?.overlappedFraction ?: 0f)
+ )
val foregroundColors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/AppBarSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/AppBarSamples.kt
index e1199d8..78f9c38 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/AppBarSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/AppBarSamples.kt
@@ -33,6 +33,7 @@
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
@@ -445,7 +446,7 @@
FloatingActionButton(
onClick = { /* do something */ },
containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
- elevation = BottomAppBarDefaults.BottomAppBarFabElevation
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
) {
Icon(Icons.Filled.Add, "Localized description")
}
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TextFieldSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TextFieldSamples.kt
index f9d6b30..a26aea6 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TextFieldSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TextFieldSamples.kt
@@ -372,7 +372,7 @@
onValueChange = onValueChange,
modifier = modifier
.background(
- color = colors.containerColor(enabled).value,
+ color = MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(
topStart = 4.0.dp,
topEnd = 4.0.dp,
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarScreenshotTest.kt
index faea010..972e48c 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarScreenshotTest.kt
@@ -315,7 +315,7 @@
FloatingActionButton(
onClick = { /* do something */ },
containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
- elevation = BottomAppBarDefaults.BottomAppBarFabElevation
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
) {
Icon(Icons.Filled.Add, "Localized description")
}
@@ -347,7 +347,7 @@
FloatingActionButton(
onClick = { /* do something */ },
containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
- elevation = BottomAppBarDefaults.BottomAppBarFabElevation
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
) {
Icon(Icons.Filled.Add, "Localized description")
}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarTest.kt
index b3c0b8f..ba376e4 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/AppBarTest.kt
@@ -178,29 +178,23 @@
FakeIcon(Modifier.testTag(NavigationIconTestTag))
navigationIconColor = LocalContentColor.current
expectedNavigationIconColor =
- TopAppBarDefaults.smallTopAppBarColors()
- .navigationIconContentColor(colorTransitionFraction = 0f).value
+ TopAppBarDefaults.smallTopAppBarColors().navigationIconContentColor
// fraction = 0f to indicate no scroll.
expectedContainerColor = TopAppBarDefaults
.smallTopAppBarColors()
.containerColor(colorTransitionFraction = 0f)
- .value
},
title = {
Text("Title", Modifier.testTag(TitleTestTag))
titleColor = LocalContentColor.current
expectedTitleColor = TopAppBarDefaults
- .smallTopAppBarColors()
- .titleContentColor(colorTransitionFraction = 0f)
- .value
+ .smallTopAppBarColors().titleContentColor
},
actions = {
FakeIcon(Modifier.testTag(ActionsTestTag))
actionsColor = LocalContentColor.current
expectedActionsColor = TopAppBarDefaults
- .smallTopAppBarColors()
- .actionIconContentColor(colorTransitionFraction = 0f)
- .value
+ .smallTopAppBarColors().actionIconContentColor
}
)
}
@@ -230,7 +224,7 @@
// fraction = 1f to indicate a scroll.
expectedScrolledContainerColor =
TopAppBarDefaults.smallTopAppBarColors()
- .containerColor(colorTransitionFraction = 1f).value
+ .containerColor(colorTransitionFraction = 1f)
},
scrollBehavior = scrollBehavior
)
@@ -392,25 +386,25 @@
navigationIconColor = LocalContentColor.current
expectedNavigationIconColor =
TopAppBarDefaults.centerAlignedTopAppBarColors()
- .navigationIconContentColor(colorTransitionFraction = 0f).value
+ .navigationIconContentColor
// fraction = 0f to indicate no scroll.
expectedContainerColor =
TopAppBarDefaults.centerAlignedTopAppBarColors()
- .containerColor(colorTransitionFraction = 0f).value
+ .containerColor(colorTransitionFraction = 0f)
},
title = {
Text("Title", Modifier.testTag(TitleTestTag))
titleColor = LocalContentColor.current
expectedTitleColor =
TopAppBarDefaults.centerAlignedTopAppBarColors()
- .titleContentColor(colorTransitionFraction = 0f).value
+ .titleContentColor
},
actions = {
FakeIcon(Modifier.testTag(ActionsTestTag))
actionsColor = LocalContentColor.current
expectedActionsColor =
TopAppBarDefaults.centerAlignedTopAppBarColors()
- .actionIconContentColor(colorTransitionFraction = 0f).value
+ .actionIconContentColor
}
)
}
@@ -441,7 +435,7 @@
// fraction = 1f to indicate a scroll.
expectedScrolledContainerColor =
TopAppBarDefaults.centerAlignedTopAppBarColors()
- .containerColor(colorTransitionFraction = 1f).value
+ .containerColor(colorTransitionFraction = 1f)
},
scrollBehavior = scrollBehavior
)
@@ -817,7 +811,7 @@
FloatingActionButton(
onClick = { /* do something */ },
containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
- elevation = BottomAppBarDefaults.BottomAppBarFabElevation
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
) {
Icon(Icons.Filled.Add, "Localized description")
}
@@ -869,7 +863,7 @@
onClick = { /* do something */ },
modifier = Modifier.testTag("FAB"),
containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
- elevation = BottomAppBarDefaults.BottomAppBarFabElevation
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
) {
Icon(Icons.Filled.Add, "Localized description")
}
@@ -1141,16 +1135,15 @@
// current content color settings are the same.
oneThirdCollapsedContainerColor =
TopAppBarDefaults.mediumTopAppBarColors()
- .containerColor(colorTransitionFraction = 1 / 3f).value
+ .containerColor(colorTransitionFraction = 1 / 3f)
fullyCollapsedContainerColor =
TopAppBarDefaults.mediumTopAppBarColors()
- .containerColor(colorTransitionFraction = 1f).value
+ .containerColor(colorTransitionFraction = 1f)
// Resolve the title's content color. The default implementation returns the same color
// regardless of the fraction, and the color is applied later with alpha.
titleContentColor =
- TopAppBarDefaults.mediumTopAppBarColors()
- .titleContentColor(colorTransitionFraction = 1f).value
+ TopAppBarDefaults.mediumTopAppBarColors().titleContentColor
with(LocalDensity.current) {
oneThirdCollapsedHeightOffsetPx = oneThirdCollapsedOffsetDp.toPx()
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CardScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CardScreenshotTest.kt
index 0db6e1b..c95c2ba 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CardScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CardScreenshotTest.kt
@@ -22,10 +22,13 @@
import androidx.compose.foundation.layout.size
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
@@ -427,14 +430,13 @@
@Test
fun filledCard_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag), contentAlignment = Alignment.Center) {
Card(
onClick = {},
Modifier.size(width = 180.dp, height = 100.dp)
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Box(Modifier.fillMaxSize()) {
@@ -447,7 +449,11 @@
}
}
- rule.runOnIdle { focusRequester.requestFocus() }
+ rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
+ focusRequester.requestFocus()
+ }
rule.waitForIdle()
assertAgainstGolden("filledCard_focus")
@@ -456,14 +462,13 @@
@Test
fun elevatedCard_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag), contentAlignment = Alignment.Center) {
ElevatedCard(
onClick = {},
Modifier.size(width = 180.dp, height = 100.dp)
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Box(Modifier.fillMaxSize()) {
@@ -476,7 +481,11 @@
}
}
- rule.runOnIdle { focusRequester.requestFocus() }
+ rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
+ focusRequester.requestFocus()
+ }
rule.waitForIdle()
assertAgainstGolden("elevatedCard_focused")
@@ -485,14 +494,13 @@
@Test
fun outlinedCard_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag), contentAlignment = Alignment.Center) {
OutlinedCard(
onClick = {},
Modifier.size(width = 180.dp, height = 100.dp)
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Box(Modifier.fillMaxSize()) {
@@ -505,7 +513,11 @@
}
}
- rule.runOnIdle { focusRequester.requestFocus() }
+ rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
+ focusRequester.requestFocus()
+ }
rule.waitForIdle()
assertAgainstGolden("outlinedCard_focused")
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CheckboxScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CheckboxScreenshotTest.kt
index 3d6aa94..07f862f 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CheckboxScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CheckboxScreenshotTest.kt
@@ -21,10 +21,13 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.test.ExperimentalTestApi
@@ -241,14 +244,13 @@
@Test
fun checkBox_focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(scheme.colorScheme) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
Checkbox(
modifier = wrap
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester),
checked = true,
onCheckedChange = { }
@@ -257,6 +259,8 @@
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/FloatingActionButtonScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/FloatingActionButtonScreenshotTest.kt
index 861e2439..dffaf04 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/FloatingActionButtonScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/FloatingActionButtonScreenshotTest.kt
@@ -25,10 +25,13 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.hasClickAction
@@ -282,15 +285,14 @@
@Test
fun focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(Modifier.requiredSize(100.dp, 100.dp).wrapContentSize()) {
FloatingActionButton(
onClick = { },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Icon(Icons.Filled.Favorite, contentDescription = null)
@@ -299,6 +301,8 @@
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/IconButtonScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/IconButtonScreenshotTest.kt
index e84d266..34a9efc 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/IconButtonScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/IconButtonScreenshotTest.kt
@@ -24,10 +24,13 @@
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
@@ -142,14 +145,13 @@
@Test
fun iconButton_lightTheme_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
IconButton(onClick = { /* doSomething() */ },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
) {
Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
@@ -158,6 +160,8 @@
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/RadioButtonScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/RadioButtonScreenshotTest.kt
index 06f365b..81f44e1 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/RadioButtonScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/RadioButtonScreenshotTest.kt
@@ -23,10 +23,13 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.captureToImage
@@ -175,22 +178,23 @@
@Test
fun radioButton_lightTheme_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
RadioButton(
selected = false,
onClick = {},
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
)
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
@@ -200,22 +204,23 @@
@Test
fun radioButton_darkTheme_focused() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
rule.setMaterialContent(darkColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrap.testTag(wrapperTestTag)) {
RadioButton(
selected = false,
onClick = {},
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
)
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
index 3d80b1c..30162ba 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
@@ -29,10 +29,13 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertAgainstGolden
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.input.InputMode
+import androidx.compose.ui.input.InputModeManager
+import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
@@ -248,21 +251,23 @@
@Test
fun switchTest_focus() {
val focusRequester = FocusRequester()
+ var localInputModeManager: InputModeManager? = null
+
rule.setMaterialContent(lightColorScheme()) {
+ localInputModeManager = LocalInputModeManager.current
Box(wrapperModifier) {
Switch(
checked = true,
onCheckedChange = { },
modifier = Modifier
- // Normally this is only focusable in non-touch mode, so let's force it to
- // always be focusable so we can test how it appears
- .focusProperties { canFocus = true }
.focusRequester(focusRequester)
)
}
}
rule.runOnIdle {
+ @OptIn(ExperimentalComposeUiApi::class)
+ localInputModeManager!!.requestInputMode(InputMode.Keyboard)
focusRequester.requestFocus()
}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
index dff4547..bd77c9f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
@@ -27,7 +27,6 @@
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
-import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -49,10 +48,8 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
@@ -441,67 +438,6 @@
val nestedScrollConnection: NestedScrollConnection
}
-/**
- * Represents the colors used by a top app bar in different states.
- *
- * Each app bar has their own default implementation available in [TopAppBarDefaults], such as
- * [TopAppBarDefaults.smallTopAppBarColors] for [SmallTopAppBar].
- */
-@Stable
-interface TopAppBarColors {
- /**
- * Represents the container color used for the top app bar.
- *
- * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
- * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
- * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
- *
- * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
- * percentage
- */
- @Composable
- fun containerColor(colorTransitionFraction: Float): State<Color>
-
- /**
- * Represents the content color used for the top app bar's navigation icon.
- *
- * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
- * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
- * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
- *
- * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
- * percentage
- */
- @Composable
- fun navigationIconContentColor(colorTransitionFraction: Float): State<Color>
-
- /**
- * Represents the content color used for the top app bar's title.
- *
- * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
- * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
- * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
- *
- * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
- * percentage
- */
- @Composable
- fun titleContentColor(colorTransitionFraction: Float): State<Color>
-
- /**
- * Represents the content color used for the top app bar's action icons.
- *
- * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
- * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
- * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
- *
- * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
- * percentage
- */
- @Composable
- fun actionIconContentColor(colorTransitionFraction: Float): State<Color>
-}
-
/** Contains default values used for the top app bar implementations. */
object TopAppBarDefaults {
@@ -526,23 +462,14 @@
navigationIconContentColor: Color = TopAppBarSmallTokens.LeadingIconColor.toColor(),
titleContentColor: Color = TopAppBarSmallTokens.HeadlineColor.toColor(),
actionIconContentColor: Color = TopAppBarSmallTokens.TrailingIconColor.toColor(),
- ): TopAppBarColors {
- return remember(
+ ): TopAppBarColors =
+ TopAppBarColors(
containerColor,
scrolledContainerColor,
navigationIconContentColor,
titleContentColor,
actionIconContentColor
- ) {
- AnimatingTopAppBarColors(
- containerColor,
- scrolledContainerColor,
- navigationIconContentColor,
- titleContentColor,
- actionIconContentColor
- )
- }
- }
+ )
/**
* Creates a [TopAppBarColors] for center aligned top app bars. The default implementation
@@ -565,23 +492,14 @@
navigationIconContentColor: Color = TopAppBarSmallCenteredTokens.LeadingIconColor.toColor(),
titleContentColor: Color = TopAppBarSmallCenteredTokens.HeadlineColor.toColor(),
actionIconContentColor: Color = TopAppBarSmallCenteredTokens.TrailingIconColor.toColor(),
- ): TopAppBarColors {
- return remember(
+ ): TopAppBarColors =
+ TopAppBarColors(
containerColor,
scrolledContainerColor,
navigationIconContentColor,
titleContentColor,
actionIconContentColor
- ) {
- AnimatingTopAppBarColors(
- containerColor,
- scrolledContainerColor,
- navigationIconContentColor,
- titleContentColor,
- actionIconContentColor
- )
- }
- }
+ )
/**
* Creates a [TopAppBarColors] for medium top app bars. The default implementation interpolates
@@ -605,23 +523,14 @@
navigationIconContentColor: Color = TopAppBarMediumTokens.LeadingIconColor.toColor(),
titleContentColor: Color = TopAppBarMediumTokens.HeadlineColor.toColor(),
actionIconContentColor: Color = TopAppBarMediumTokens.TrailingIconColor.toColor(),
- ): TopAppBarColors {
- return remember(
+ ): TopAppBarColors =
+ TopAppBarColors(
containerColor,
scrolledContainerColor,
navigationIconContentColor,
titleContentColor,
actionIconContentColor
- ) {
- InterpolatingTopAppBarColors(
- containerColor,
- scrolledContainerColor,
- navigationIconContentColor,
- titleContentColor,
- actionIconContentColor
- )
- }
- }
+ )
/**
* Creates a [TopAppBarColors] for large top app bars. The default implementation interpolates
@@ -645,23 +554,14 @@
navigationIconContentColor: Color = TopAppBarLargeTokens.LeadingIconColor.toColor(),
titleContentColor: Color = TopAppBarLargeTokens.HeadlineColor.toColor(),
actionIconContentColor: Color = TopAppBarLargeTokens.TrailingIconColor.toColor(),
- ): TopAppBarColors {
- return remember(
+ ): TopAppBarColors =
+ TopAppBarColors(
containerColor,
scrolledContainerColor,
navigationIconContentColor,
titleContentColor,
actionIconContentColor
- ) {
- InterpolatingTopAppBarColors(
- containerColor,
- scrolledContainerColor,
- navigationIconContentColor,
- titleContentColor,
- actionIconContentColor
- )
- }
- }
+ )
/**
* Returns a pinned [TopAppBarScrollBehavior] that tracks nested-scroll callbacks and
@@ -874,21 +774,6 @@
end = BottomAppBarHorizontalPadding
)
- // Bottom App Bar FAB Defaults
- /**
- * Creates a [FloatingActionButtonElevation] that represents the default elevation of a
- * [FloatingActionButton] used for [BottomAppBar] in different states.
- */
- object BottomAppBarFabElevation : FloatingActionButtonElevation {
- private val elevation = mutableStateOf(0.dp)
-
- @Composable
- override fun shadowElevation(interactionSource: InteractionSource) = elevation
-
- @Composable
- override fun tonalElevation(interactionSource: InteractionSource) = elevation
- }
-
/** The color of a [BottomAppBar]'s [FloatingActionButton] */
val bottomAppBarFabColor: Color
@Composable get() =
@@ -940,7 +825,14 @@
// This may potentially animate or interpolate a transition between the container-color and the
// container's scrolled-color according to the app bar's scroll state.
val colorTransitionFraction = scrollBehavior?.state?.overlappedFraction ?: 0f
- val appBarContainerColor by colors.containerColor(colorTransitionFraction)
+ val fraction = if (colorTransitionFraction > 0.01f) 1f else 0f
+ val appBarContainerColor by animateColorAsState(
+ targetValue = colors.containerColor(fraction),
+ animationSpec = tween(
+ durationMillis = TopAppBarAnimationDurationMillis,
+ easing = LinearOutSlowInEasing
+ )
+ )
// Wrap the given actions in a Row.
val actionsRow = @Composable {
@@ -973,10 +865,9 @@
TopAppBarLayout(
modifier = Modifier,
heightPx = height,
- navigationIconContentColor =
- colors.navigationIconContentColor(colorTransitionFraction).value,
- titleContentColor = colors.titleContentColor(colorTransitionFraction).value,
- actionIconContentColor = colors.actionIconContentColor(colorTransitionFraction).value,
+ navigationIconContentColor = colors.navigationIconContentColor,
+ titleContentColor = colors.titleContentColor,
+ actionIconContentColor = colors.actionIconContentColor,
title = title,
titleTextStyle = titleTextStyle,
titleAlpha = 1f,
@@ -1042,7 +933,7 @@
// This will potentially animate or interpolate a transition between the container color and the
// container's scrolled color according to the app bar's scroll state.
val colorTransitionFraction = scrollBehavior?.state?.collapsedFraction ?: 0f
- val appBarContainerColor by colors.containerColor(colorTransitionFraction)
+ val appBarContainerColor by rememberUpdatedState(colors.containerColor(colorTransitionFraction))
// Wrap the given actions in a Row.
val actionsRow = @Composable {
@@ -1074,10 +965,10 @@
modifier = Modifier,
heightPx = pinnedHeightPx,
navigationIconContentColor =
- colors.navigationIconContentColor(colorTransitionFraction).value,
- titleContentColor = colors.titleContentColor(colorTransitionFraction).value,
+ colors.navigationIconContentColor,
+ titleContentColor = colors.titleContentColor,
actionIconContentColor =
- colors.actionIconContentColor(colorTransitionFraction).value,
+ colors.actionIconContentColor,
title = smallTitle,
titleTextStyle = smallTitleTextStyle,
titleAlpha = 1f - titleAlpha,
@@ -1093,10 +984,10 @@
heightPx = maxHeightPx - pinnedHeightPx + (scrollBehavior?.state?.heightOffset
?: 0f),
navigationIconContentColor =
- colors.navigationIconContentColor(colorTransitionFraction).value,
- titleContentColor = colors.titleContentColor(colorTransitionFraction).value,
+ colors.navigationIconContentColor,
+ titleContentColor = colors.titleContentColor,
actionIconContentColor =
- colors.actionIconContentColor(colorTransitionFraction).value,
+ colors.actionIconContentColor,
title = title,
titleTextStyle = titleTextStyle,
titleAlpha = titleAlpha,
@@ -1262,96 +1153,60 @@
}
/**
- * A [TopAppBarColors] implementation that animates the container color according to the top app
- * bar scroll state.
- *
- * This default implementation does not animate the leading, headline, or trailing colors.
+ * Represents the colors used by a top app bar in different states.
+ * This implementation animates the container color according to the top app bar scroll state. It
+ * does not animate the leading, headline, or trailing colors.
*/
@Stable
-private class AnimatingTopAppBarColors(
+class TopAppBarColors internal constructor(
private val containerColor: Color,
private val scrolledContainerColor: Color,
- navigationIconContentColor: Color,
- titleContentColor: Color,
- actionIconContentColor: Color
-) : TopAppBarColors {
+ internal val navigationIconContentColor: Color,
+ internal val titleContentColor: Color,
+ internal val actionIconContentColor: Color,
+) {
- // In this TopAppBarColors implementation, the following colors never change their value as the
- // app bar collapses.
- private val navigationIconColorState: State<Color> = mutableStateOf(navigationIconContentColor)
- private val titleColorState: State<Color> = mutableStateOf(titleContentColor)
- private val actionIconColorState: State<Color> = mutableStateOf(actionIconContentColor)
-
+ /**
+ * Represents the container color used for the top app bar.
+ *
+ * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
+ * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
+ * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
+ *
+ * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
+ * percentage
+ */
@Composable
- override fun containerColor(colorTransitionFraction: Float): State<Color> {
- return animateColorAsState(
- // Check if fraction is slightly over zero to overcome float precision issues.
- targetValue = if (colorTransitionFraction > 0.01f) {
- scrolledContainerColor
- } else {
- containerColor
- },
- animationSpec = tween(
- durationMillis = TopAppBarAnimationDurationMillis,
- easing = LinearOutSlowInEasing
- )
+ internal fun containerColor(colorTransitionFraction: Float): Color {
+ return lerp(
+ containerColor,
+ scrolledContainerColor,
+ FastOutLinearInEasing.transform(colorTransitionFraction)
)
}
- @Composable
- override fun navigationIconContentColor(colorTransitionFraction: Float): State<Color> =
- navigationIconColorState
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is TopAppBarColors) return false
- @Composable
- override fun titleContentColor(colorTransitionFraction: Float): State<Color> = titleColorState
+ if (containerColor != other.containerColor) return false
+ if (scrolledContainerColor != other.scrolledContainerColor) return false
+ if (navigationIconContentColor != other.navigationIconContentColor) return false
+ if (titleContentColor != other.titleContentColor) return false
+ if (actionIconContentColor != other.actionIconContentColor) return false
- @Composable
- override fun actionIconContentColor(colorTransitionFraction: Float): State<Color> =
- actionIconColorState
-}
-
-/**
- * A [TopAppBarColors] implementation that interpolates the container color according to the top
- * app bar scroll state percentage.
- *
- * This default implementation does not interpolate the leading, headline, or trailing colors.
- */
-@Stable
-private class InterpolatingTopAppBarColors(
- private val containerColor: Color,
- private val scrolledContainerColor: Color,
- navigationIconContentColor: Color,
- titleContentColor: Color,
- actionIconContentColor: Color
-) : TopAppBarColors {
-
- // In this TopAppBarColors implementation, the following colors never change their value as the
- // app bar collapses.
- private val navigationIconColorState: State<Color> = mutableStateOf(navigationIconContentColor)
- private val titleColorState: State<Color> = mutableStateOf(titleContentColor)
- private val actionIconColorState: State<Color> = mutableStateOf(actionIconContentColor)
-
- @Composable
- override fun containerColor(colorTransitionFraction: Float): State<Color> {
- return rememberUpdatedState(
- lerp(
- containerColor,
- scrolledContainerColor,
- FastOutLinearInEasing.transform(colorTransitionFraction)
- )
- )
+ return true
}
- @Composable
- override fun navigationIconContentColor(colorTransitionFraction: Float): State<Color> =
- navigationIconColorState
+ override fun hashCode(): Int {
+ var result = containerColor.hashCode()
+ result = 31 * result + scrolledContainerColor.hashCode()
+ result = 31 * result + navigationIconContentColor.hashCode()
+ result = 31 * result + titleContentColor.hashCode()
+ result = 31 * result + actionIconContentColor.hashCode()
- @Composable
- override fun titleContentColor(colorTransitionFraction: Float): State<Color> = titleColorState
-
- @Composable
- override fun actionIconContentColor(colorTransitionFraction: Float): State<Color> =
- actionIconColorState
+ return result
+ }
}
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
index d2e490c..4d3c0691 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
@@ -31,6 +31,20 @@
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.ButtonDefaults.ContentPadding
+import androidx.compose.material3.ButtonDefaults.IconSize
+import androidx.compose.material3.ButtonDefaults.IconSpacing
+import androidx.compose.material3.ButtonDefaults.MinHeight
+import androidx.compose.material3.ButtonDefaults.MinWidth
+import androidx.compose.material3.ButtonDefaults.TextButtonContentPadding
+import androidx.compose.material3.ButtonDefaults.buttonColors
+import androidx.compose.material3.ButtonDefaults.buttonElevation
+import androidx.compose.material3.ButtonDefaults.elevatedButtonColors
+import androidx.compose.material3.ButtonDefaults.elevatedButtonElevation
+import androidx.compose.material3.ButtonDefaults.filledTonalButtonColors
+import androidx.compose.material3.ButtonDefaults.filledTonalButtonElevation
+import androidx.compose.material3.ButtonDefaults.outlinedButtonColors
+import androidx.compose.material3.ButtonDefaults.textButtonColors
import androidx.compose.material3.tokens.ElevatedButtonTokens
import androidx.compose.material3.tokens.FilledButtonTokens
import androidx.compose.material3.tokens.FilledTonalButtonTokens
@@ -538,14 +552,13 @@
FilledButtonTokens.DisabledContainerColor.toColor()
.copy(alpha = FilledButtonTokens.DisabledContainerOpacity),
disabledContentColor: Color = FilledButtonTokens.DisabledLabelTextColor.toColor()
- .copy(alpha = FilledButtonTokens.DisabledLabelTextOpacity),
- ): ButtonColors =
- DefaultButtonColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ .copy(alpha = FilledButtonTokens.DisabledLabelTextOpacity),
+ ): ButtonColors = ButtonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [ButtonColors] that represents the default container and content colors used in an
@@ -566,13 +579,12 @@
disabledContentColor: Color = ElevatedButtonTokens.DisabledLabelTextColor
.toColor()
.copy(alpha = ElevatedButtonTokens.DisabledLabelTextOpacity),
- ): ButtonColors =
- DefaultButtonColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ ): ButtonColors = ButtonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [ButtonColors] that represents the default container and content colors used in an
@@ -593,13 +605,12 @@
disabledContentColor: Color = FilledTonalButtonTokens.DisabledLabelTextColor
.toColor()
.copy(alpha = FilledTonalButtonTokens.DisabledLabelTextOpacity),
- ): ButtonColors =
- DefaultButtonColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ ): ButtonColors = ButtonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [ButtonColors] that represents the default container and content colors used in an
@@ -618,13 +629,12 @@
disabledContentColor: Color = OutlinedButtonTokens.DisabledLabelTextColor
.toColor()
.copy(alpha = OutlinedButtonTokens.DisabledLabelTextOpacity),
- ): ButtonColors =
- DefaultButtonColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ ): ButtonColors = ButtonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [ButtonColors] that represents the default container and content colors used in a
@@ -643,13 +653,12 @@
disabledContentColor: Color = TextButtonTokens.DisabledLabelTextColor
.toColor()
.copy(alpha = TextButtonTokens.DisabledLabelTextOpacity),
- ): ButtonColors =
- DefaultButtonColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ ): ButtonColors = ButtonColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [ButtonElevation] that will animate between the provided values according to the
@@ -669,23 +678,13 @@
focusedElevation: Dp = FilledButtonTokens.FocusContainerElevation,
hoveredElevation: Dp = FilledButtonTokens.HoverContainerElevation,
disabledElevation: Dp = FilledButtonTokens.DisabledContainerElevation,
- ): ButtonElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- disabledElevation
- ) {
- DefaultButtonElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- disabledElevation = disabledElevation,
- )
- }
- }
+ ): ButtonElevation = ButtonElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ disabledElevation = disabledElevation,
+ )
/**
* Creates a [ButtonElevation] that will animate between the provided values according to the
@@ -705,23 +704,13 @@
focusedElevation: Dp = ElevatedButtonTokens.FocusContainerElevation,
hoveredElevation: Dp = ElevatedButtonTokens.HoverContainerElevation,
disabledElevation: Dp = ElevatedButtonTokens.DisabledContainerElevation
- ): ButtonElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- disabledElevation
- ) {
- DefaultButtonElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ButtonElevation = ButtonElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [ButtonElevation] that will animate between the provided values according to the
@@ -742,23 +731,13 @@
focusedElevation: Dp = FilledTonalButtonTokens.FocusContainerElevation,
hoveredElevation: Dp = FilledTonalButtonTokens.HoverContainerElevation,
disabledElevation: Dp = 0.dp
- ): ButtonElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- disabledElevation
- ) {
- DefaultButtonElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ButtonElevation = ButtonElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ disabledElevation = disabledElevation
+ )
/** The default [BorderStroke] used by [OutlinedButton]. */
val outlinedButtonBorder: BorderStroke
@@ -777,7 +756,13 @@
* [ElevatedButton].
*/
@Stable
-interface ButtonElevation {
+class ButtonElevation internal constructor(
+ private val defaultElevation: Dp,
+ private val pressedElevation: Dp,
+ private val focusedElevation: Dp,
+ private val hoveredElevation: Dp,
+ private val disabledElevation: Dp,
+) {
/**
* Represents the tonal elevation used in a button, depending on its [enabled] state and
* [interactionSource]. This should typically be the same value as the [shadowElevation].
@@ -792,7 +777,9 @@
* @param interactionSource the [InteractionSource] for this button
*/
@Composable
- fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
+ internal fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp> {
+ return animateElevation(enabled = enabled, interactionSource = interactionSource)
+ }
/**
* Represents the shadow elevation used in a button, depending on its [enabled] state and
@@ -806,51 +793,7 @@
* @param interactionSource the [InteractionSource] for this button
*/
@Composable
- fun shadowElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
-}
-
-/**
- * Represents the container and content colors used in a button in different states.
- *
- * - See [ButtonDefaults.buttonColors] for the default colors used in a [Button].
- * - See [ButtonDefaults.elevatedButtonColors] for the default colors used in a [ElevatedButton].
- * - See [ButtonDefaults.textButtonColors] for the default colors used in a [TextButton].
- */
-@Stable
-interface ButtonColors {
- /**
- * Represents the container color for this button, depending on [enabled].
- *
- * @param enabled whether the button is enabled
- */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the content color for this button, depending on [enabled].
- *
- * @param enabled whether the button is enabled
- */
- @Composable
- fun contentColor(enabled: Boolean): State<Color>
-}
-
-/** Default [ButtonElevation] implementation. */
-@Stable
-private class DefaultButtonElevation(
- private val defaultElevation: Dp,
- private val pressedElevation: Dp,
- private val focusedElevation: Dp,
- private val hoveredElevation: Dp,
- private val disabledElevation: Dp,
-) : ButtonElevation {
- @Composable
- override fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp> {
- return animateElevation(enabled = enabled, interactionSource = interactionSource)
- }
-
- @Composable
- override fun shadowElevation(
+ internal fun shadowElevation(
enabled: Boolean,
interactionSource: InteractionSource
): State<Dp> {
@@ -928,31 +871,67 @@
return animatable.asState()
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is ButtonElevation) return false
+
+ if (defaultElevation != other.defaultElevation) return false
+ if (pressedElevation != other.pressedElevation) return false
+ if (focusedElevation != other.focusedElevation) return false
+ if (hoveredElevation != other.hoveredElevation) return false
+ if (disabledElevation != other.disabledElevation) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = defaultElevation.hashCode()
+ result = 31 * result + pressedElevation.hashCode()
+ result = 31 * result + focusedElevation.hashCode()
+ result = 31 * result + hoveredElevation.hashCode()
+ result = 31 * result + disabledElevation.hashCode()
+ return result
+ }
}
-/** Default [ButtonColors] implementation. */
+/**
+ * Represents the container and content colors used in a button in different states.
+ *
+ * - See [ButtonDefaults.buttonColors] for the default colors used in a [Button].
+ * - See [ButtonDefaults.elevatedButtonColors] for the default colors used in a [ElevatedButton].
+ * - See [ButtonDefaults.textButtonColors] for the default colors used in a [TextButton].
+ */
@Immutable
-private class DefaultButtonColors(
+class ButtonColors internal constructor(
private val containerColor: Color,
private val contentColor: Color,
private val disabledContainerColor: Color,
private val disabledContentColor: Color,
-) : ButtonColors {
+) {
+ /**
+ * Represents the container color for this button, depending on [enabled].
+ *
+ * @param enabled whether the button is enabled
+ */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor)
}
+ /**
+ * Represents the content color for this button, depending on [enabled].
+ *
+ * @param enabled whether the button is enabled
+ */
@Composable
- override fun contentColor(enabled: Boolean): State<Color> {
+ internal fun contentColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) contentColor else disabledContentColor)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultButtonColors
+ if (other == null || other !is ButtonColors) return false
if (containerColor != other.containerColor) return false
if (contentColor != other.contentColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
index 563f3f1..ccdfa68 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
@@ -34,7 +34,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
@@ -348,72 +347,6 @@
)
/**
- * Represents the elevation for a card in different states.
- *
- * - See [CardDefaults.cardElevation] for the default elevation used in a [Card].
- * - See [CardDefaults.elevatedCardElevation] for the default elevation used in an [ElevatedCard].
- * - See [CardDefaults.outlinedCardElevation] for the default elevation used in an [OutlinedCard].
- */
-@Stable
-interface CardElevation {
- /**
- * Represents the tonal elevation used in a card, depending on its [enabled] state and
- * [interactionSource]. This should typically be the same value as the [shadowElevation].
- *
- * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
- * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
- * color in light theme and lighter color in dark theme.
- *
- * See [shadowElevation] which controls the elevation of the shadow drawn around the card.
- *
- * @param enabled whether the card is enabled
- * @param interactionSource the [InteractionSource] for this card
- */
- @Composable
- fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource?): State<Dp>
-
- /**
- * Represents the shadow elevation used in a card, depending on its [enabled] state and
- * [interactionSource]. This should typically be the same value as the [tonalElevation].
- *
- * Shadow elevation is used to apply a shadow around the card to give it higher emphasis.
- *
- * See [tonalElevation] which controls the elevation with a color shift to the surface.
- *
- * @param enabled whether the card is enabled
- * @param interactionSource the [InteractionSource] for this card
- */
- @Composable
- fun shadowElevation(enabled: Boolean, interactionSource: InteractionSource?): State<Dp>
-}
-
-/**
- * Represents the container and content colors used in a card in different states.
- *
- * - See [CardDefaults.cardColors] for the default colors used in a [Card].
- * - See [CardDefaults.elevatedCardColors] for the default colors used in a [ElevatedCard].
- * - See [CardDefaults.outlinedCardColors] for the default colors used in a [OutlinedCard].
- */
-@Stable
-interface CardColors {
- /**
- * Represents the container color for this card, depending on [enabled].
- *
- * @param enabled whether the card is enabled
- */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the content color for this card, depending on [enabled].
- *
- * @param enabled whether the card is enabled
- */
- @Composable
- fun contentColor(enabled: Boolean): State<Color>
-}
-
-/**
* Contains the default values used by all card types.
*/
object CardDefaults {
@@ -445,25 +378,14 @@
hoveredElevation: Dp = FilledCardTokens.HoverContainerElevation,
draggedElevation: Dp = FilledCardTokens.DraggedContainerElevation,
disabledElevation: Dp = FilledCardTokens.DisabledContainerElevation
- ): CardElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultCardElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): CardElevation = CardElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [CardElevation] that will animate between the provided values according to the
@@ -484,25 +406,14 @@
hoveredElevation: Dp = ElevatedCardTokens.HoverContainerElevation,
draggedElevation: Dp = ElevatedCardTokens.DraggedContainerElevation,
disabledElevation: Dp = ElevatedCardTokens.DisabledContainerElevation
- ): CardElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultCardElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): CardElevation = CardElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [CardElevation] that will animate between the provided values according to the
@@ -523,25 +434,14 @@
hoveredElevation: Dp = defaultElevation,
draggedElevation: Dp = OutlinedCardTokens.DraggedContainerElevation,
disabledElevation: Dp = OutlinedCardTokens.DisabledContainerElevation
- ): CardElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultCardElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): CardElevation = CardElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [CardColors] that represents the default container and content colors used in a
@@ -565,13 +465,12 @@
)
),
disabledContentColor: Color = contentColorFor(containerColor).copy(DisabledAlpha),
- ): CardColors =
- DefaultCardColors(
- containerColor = containerColor,
- contentColor = contentColor,
- disabledContainerColor = disabledContainerColor,
- disabledContentColor = disabledContentColor
- )
+ ): CardColors = CardColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
+ )
/**
* Creates a [CardColors] that represents the default container and content colors used in an
@@ -596,7 +495,7 @@
),
disabledContentColor: Color = contentColor.copy(DisabledAlpha),
): CardColors =
- DefaultCardColors(
+ CardColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -619,7 +518,7 @@
disabledContainerColor: Color = containerColor,
disabledContentColor: Color = contentColor.copy(DisabledAlpha),
): CardColors =
- DefaultCardColors(
+ CardColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -649,22 +548,36 @@
}
/**
- * Default [CardElevation] implementation.
+ * Represents the elevation for a card in different states.
*
- * This default implementation supports animating the elevation for pressed, focused, hovered, and
- * dragged interactions.
+ * - See [CardDefaults.cardElevation] for the default elevation used in a [Card].
+ * - See [CardDefaults.elevatedCardElevation] for the default elevation used in an [ElevatedCard].
+ * - See [CardDefaults.outlinedCardElevation] for the default elevation used in an [OutlinedCard].
*/
@Immutable
-private class DefaultCardElevation(
+class CardElevation internal constructor(
private val defaultElevation: Dp,
private val pressedElevation: Dp,
private val focusedElevation: Dp,
private val hoveredElevation: Dp,
private val draggedElevation: Dp,
private val disabledElevation: Dp
-) : CardElevation {
+) {
+ /**
+ * Represents the tonal elevation used in a card, depending on its [enabled] state and
+ * [interactionSource]. This should typically be the same value as the [shadowElevation].
+ *
+ * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
+ * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
+ * color in light theme and lighter color in dark theme.
+ *
+ * See [shadowElevation] which controls the elevation of the shadow drawn around the card.
+ *
+ * @param enabled whether the card is enabled
+ * @param interactionSource the [InteractionSource] for this card
+ */
@Composable
- override fun tonalElevation(
+ internal fun tonalElevation(
enabled: Boolean,
interactionSource: InteractionSource?
): State<Dp> {
@@ -674,8 +587,19 @@
return animateElevation(enabled = enabled, interactionSource = interactionSource)
}
+ /**
+ * Represents the shadow elevation used in a card, depending on its [enabled] state and
+ * [interactionSource]. This should typically be the same value as the [tonalElevation].
+ *
+ * Shadow elevation is used to apply a shadow around the card to give it higher emphasis.
+ *
+ * See [tonalElevation] which controls the elevation with a color shift to the surface.
+ *
+ * @param enabled whether the card is enabled
+ * @param interactionSource the [InteractionSource] for this card
+ */
@Composable
- override fun shadowElevation(
+ internal fun shadowElevation(
enabled: Boolean,
interactionSource: InteractionSource?
): State<Dp> {
@@ -767,31 +691,67 @@
return animatable.asState()
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is CardElevation) return false
+
+ if (defaultElevation != other.defaultElevation) return false
+ if (pressedElevation != other.pressedElevation) return false
+ if (focusedElevation != other.focusedElevation) return false
+ if (hoveredElevation != other.hoveredElevation) return false
+ if (disabledElevation != other.disabledElevation) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = defaultElevation.hashCode()
+ result = 31 * result + pressedElevation.hashCode()
+ result = 31 * result + focusedElevation.hashCode()
+ result = 31 * result + hoveredElevation.hashCode()
+ result = 31 * result + disabledElevation.hashCode()
+ return result
+ }
}
-/** Default [CardColors] implementation. */
+/**
+ * Represents the container and content colors used in a card in different states.
+ *
+ * - See [CardDefaults.cardColors] for the default colors used in a [Card].
+ * - See [CardDefaults.elevatedCardColors] for the default colors used in a [ElevatedCard].
+ * - See [CardDefaults.outlinedCardColors] for the default colors used in a [OutlinedCard].
+ */
@Immutable
-private class DefaultCardColors(
+class CardColors internal constructor(
private val containerColor: Color,
private val contentColor: Color,
private val disabledContainerColor: Color,
private val disabledContentColor: Color,
-) : CardColors {
+) {
+ /**
+ * Represents the container color for this card, depending on [enabled].
+ *
+ * @param enabled whether the card is enabled
+ */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor)
}
+ /**
+ * Represents the content color for this card, depending on [enabled].
+ *
+ * @param enabled whether the card is enabled
+ */
@Composable
- override fun contentColor(enabled: Boolean): State<Color> {
+ internal fun contentColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) contentColor else disabledContentColor)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultCardColors
+ if (other == null || other !is CardColors) return false
if (containerColor != other.containerColor) return false
if (contentColor != other.contentColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
index c521bd8..f5fde50 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
@@ -33,7 +33,6 @@
import androidx.compose.material3.tokens.CheckboxTokens
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -176,44 +175,6 @@
}
/**
- * Represents the colors used by the three different sections (checkmark, box, and border) of a
- * [Checkbox] or [TriStateCheckbox] in different states.
- *
- * See [CheckboxDefaults.colors] for the default implementation that follows Material
- * specifications.
- */
-@Stable
-interface CheckboxColors {
-
- /**
- * Represents the color used for the checkmark inside the checkbox, depending on [state].
- *
- * @param state the [ToggleableState] of the checkbox
- */
- @Composable
- fun checkmarkColor(state: ToggleableState): State<Color>
-
- /**
- * Represents the color used for the box (background) of the checkbox, depending on [enabled]
- * and [state].
- *
- * @param enabled whether the checkbox is enabled or not
- * @param state the [ToggleableState] of the checkbox
- */
- @Composable
- fun boxColor(enabled: Boolean, state: ToggleableState): State<Color>
-
- /**
- * Represents the color used for the border of the checkbox, depending on [enabled] and [state].
- *
- * @param enabled whether the checkbox is enabled or not
- * @param state the [ToggleableState] of the checkbox
- */
- @Composable
- fun borderColor(enabled: Boolean, state: ToggleableState): State<Color>
-}
-
-/**
* Defaults used in [Checkbox] and [TriStateCheckbox].
*/
object CheckboxDefaults {
@@ -248,30 +209,19 @@
.fromToken(CheckboxTokens.UnselectedDisabledOutlineColor)
.copy(alpha = CheckboxTokens.UnselectedDisabledContainerOpacity),
disabledIndeterminateColor: Color = disabledCheckedColor
- ): CheckboxColors {
- return remember(
- checkedColor,
- uncheckedColor,
- checkmarkColor,
- disabledCheckedColor,
- disabledUncheckedColor,
- disabledIndeterminateColor,
- ) {
- DefaultCheckboxColors(
- checkedBorderColor = checkedColor,
- checkedBoxColor = checkedColor,
- checkedCheckmarkColor = checkmarkColor,
- uncheckedCheckmarkColor = checkmarkColor.copy(alpha = 0f),
- uncheckedBoxColor = checkedColor.copy(alpha = 0f),
- disabledCheckedBoxColor = disabledCheckedColor,
- disabledUncheckedBoxColor = disabledUncheckedColor.copy(alpha = 0f),
- disabledIndeterminateBoxColor = disabledIndeterminateColor,
- uncheckedBorderColor = uncheckedColor,
- disabledBorderColor = disabledCheckedColor,
- disabledIndeterminateBorderColor = disabledIndeterminateColor,
- )
- }
- }
+ ): CheckboxColors = CheckboxColors(
+ checkedBorderColor = checkedColor,
+ checkedBoxColor = checkedColor,
+ checkedCheckmarkColor = checkmarkColor,
+ uncheckedCheckmarkColor = checkmarkColor.copy(alpha = 0f),
+ uncheckedBoxColor = checkedColor.copy(alpha = 0f),
+ disabledCheckedBoxColor = disabledCheckedColor,
+ disabledUncheckedBoxColor = disabledUncheckedColor.copy(alpha = 0f),
+ disabledIndeterminateBoxColor = disabledIndeterminateColor,
+ uncheckedBorderColor = uncheckedColor,
+ disabledBorderColor = disabledCheckedColor,
+ disabledIndeterminateBorderColor = disabledIndeterminateColor,
+ )
}
@Composable
@@ -418,10 +368,14 @@
)
/**
- * Default [CheckboxColors] implementation.
+ * Represents the colors used by the three different sections (checkmark, box, and border) of a
+ * [Checkbox] or [TriStateCheckbox] in different states.
+ *
+ * See [CheckboxDefaults.colors] for the default implementation that follows Material
+ * specifications.
*/
@Immutable
-private class DefaultCheckboxColors(
+class CheckboxColors internal constructor(
private val checkedCheckmarkColor: Color,
private val uncheckedCheckmarkColor: Color,
private val checkedBoxColor: Color,
@@ -433,9 +387,14 @@
private val uncheckedBorderColor: Color,
private val disabledBorderColor: Color,
private val disabledIndeterminateBorderColor: Color
-) : CheckboxColors {
+) {
+ /**
+ * Represents the color used for the checkmark inside the checkbox, depending on [state].
+ *
+ * @param state the [ToggleableState] of the checkbox
+ */
@Composable
- override fun checkmarkColor(state: ToggleableState): State<Color> {
+ internal fun checkmarkColor(state: ToggleableState): State<Color> {
val target = if (state == ToggleableState.Off) {
uncheckedCheckmarkColor
} else {
@@ -446,8 +405,15 @@
return animateColorAsState(target, tween(durationMillis = duration))
}
+ /**
+ * Represents the color used for the box (background) of the checkbox, depending on [enabled]
+ * and [state].
+ *
+ * @param enabled whether the checkbox is enabled or not
+ * @param state the [ToggleableState] of the checkbox
+ */
@Composable
- override fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {
+ internal fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {
val target = if (enabled) {
when (state) {
ToggleableState.On, ToggleableState.Indeterminate -> checkedBoxColor
@@ -471,8 +437,14 @@
}
}
+ /**
+ * Represents the color used for the border of the checkbox, depending on [enabled] and [state].
+ *
+ * @param enabled whether the checkbox is enabled or not
+ * @param state the [ToggleableState] of the checkbox
+ */
@Composable
- override fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {
+ internal fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {
val target = if (enabled) {
when (state) {
ToggleableState.On, ToggleableState.Indeterminate -> checkedBorderColor
@@ -497,9 +469,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultCheckboxColors
+ if (other == null || other !is CheckboxColors) return false
if (checkedCheckmarkColor != other.checkedCheckmarkColor) return false
if (uncheckedCheckmarkColor != other.uncheckedCheckmarkColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
index a66ff79..ecc4825 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
@@ -42,7 +42,6 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
@@ -618,211 +617,6 @@
)
/**
- * Represents the elevation for a chip in different states.
- */
-@Stable
-@ExperimentalMaterial3Api
-interface ChipElevation {
- /**
- * Represents the tonal elevation used in a chip, depending on its [enabled] state and
- * [interactionSource]. This should typically be the same value as the [shadowElevation].
- *
- * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
- * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
- * color in light theme and lighter color in dark theme.
- *
- * See [shadowElevation] which controls the elevation of the shadow drawn around the chip.
- *
- * @param enabled whether the chip is enabled
- * @param interactionSource the [InteractionSource] for this chip
- */
- @Composable
- fun tonalElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
-
- /**
- * Represents the shadow elevation used in a chip, depending on its [enabled] state and
- * [interactionSource]. This should typically be the same value as the [tonalElevation].
- *
- * Shadow elevation is used to apply a shadow around the chip to give it higher emphasis.
- *
- * See [tonalElevation] which controls the elevation with a color shift to the surface.
- *
- * @param enabled whether the chip is enabled
- * @param interactionSource the [InteractionSource] for this chip
- */
- @Composable
- fun shadowElevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
-}
-
-/**
- * Represents the elevation used in a selectable chip in different states.
- */
-@Stable
-@ExperimentalMaterial3Api
-interface SelectableChipElevation {
- /**
- * Represents the tonal elevation used in a chip, depending on [enabled], [selected], and
- * [interactionSource]. This should typically be the same value as the [shadowElevation].
- *
- * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
- * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
- * color in light theme and lighter color in dark theme.
- *
- * See [shadowElevation] which controls the elevation of the shadow drawn around the Chip.
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- * @param interactionSource the [InteractionSource] for this chip
- */
- @Composable
- fun tonalElevation(
- enabled: Boolean,
- selected: Boolean,
- interactionSource: InteractionSource
- ): State<Dp>
-
- /**
- * Represents the shadow elevation used in a chip, depending on [enabled], [selected], and
- * [interactionSource]. This should typically be the same value as the [tonalElevation].
- *
- * Shadow elevation is used to apply a shadow around the surface to give it higher emphasis.
- *
- * See [tonalElevation] which controls the elevation with a color shift to the surface.
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- * @param interactionSource the [InteractionSource] for this chip
- */
- @Composable
- fun shadowElevation(
- enabled: Boolean,
- selected: Boolean,
- interactionSource: InteractionSource
- ): State<Dp>
-}
-
-/**
- * Represents the container and content colors used in a clickable chip in different states.
- *
- * See [AssistChipDefaults], [InputChipDefaults], and [SuggestionChipDefaults] for the default
- * colors used in the various Chip configurations.
- */
-@Stable
-@ExperimentalMaterial3Api
-interface ChipColors {
- /**
- * Represents the container color for this chip, depending on [enabled].
- *
- * @param enabled whether the chip is enabled
- */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the label color for this chip, depending on [enabled].
- *
- * @param enabled whether the chip is enabled
- */
- @Composable
- fun labelColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the leading icon's content color for this chip, depending on [enabled].
- *
- * @param enabled whether the chip is enabled
- */
- @Composable
- fun leadingIconContentColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the trailing icon's content color for this chip, depending on [enabled].
- *
- * @param enabled whether the chip is enabled
- */
- @Composable
- fun trailingIconContentColor(enabled: Boolean): State<Color>
-}
-
-/**
- * Represents the container and content colors used in a selectable chip in different states.
- *
- * See [FilterChipDefaults.filterChipColors] and [FilterChipDefaults.elevatedFilterChipColors] for
- * the default colors used in [FilterChip].
- */
-@Stable
-@ExperimentalMaterial3Api
-interface SelectableChipColors {
- /**
- * Represents the container color for this chip, depending on [enabled] and [selected].
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- */
- @Composable
- fun containerColor(enabled: Boolean, selected: Boolean): State<Color>
-
- /**
- * Represents the label color for this chip, depending on [enabled] and [selected].
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- */
- @Composable
- fun labelColor(enabled: Boolean, selected: Boolean): State<Color>
-
- /**
- * Represents the leading icon color for this chip, depending on [enabled] and [selected].
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- */
- @Composable
- fun leadingIconContentColor(enabled: Boolean, selected: Boolean): State<Color>
-
- /**
- * Represents the trailing icon color for this chip, depending on [enabled] and [selected].
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- */
- @Composable
- fun trailingIconContentColor(enabled: Boolean, selected: Boolean): State<Color>
-}
-
-/**
- * Represents the border stroke used in a chip in different states.
- */
-@Stable
-@ExperimentalMaterial3Api
-interface ChipBorder {
-
- /**
- * Represents the [BorderStroke] for this chip, depending on [enabled].
- *
- * @param enabled whether the chip is enabled
- */
- @Composable
- fun borderStroke(enabled: Boolean): State<BorderStroke?>
-}
-
-/**
- * Represents the border stroke used used in a selectable chip in different states.
- */
-@Stable
-@ExperimentalMaterial3Api
-interface SelectableChipBorder {
- /**
- * Represents the [BorderStroke] stroke used for this chip, depending on [enabled] and
- * [selected].
- *
- * @param enabled whether the chip is enabled
- * @param selected whether the chip is selected
- */
- @Composable
- fun borderStroke(enabled: Boolean, selected: Boolean): State<BorderStroke?>
-}
-
-/**
* Contains the baseline values used by [AssistChip].
*/
@ExperimentalMaterial3Api
@@ -864,7 +658,7 @@
AssistChipTokens.DisabledIconColor.toColor()
.copy(alpha = AssistChipTokens.DisabledIconOpacity),
disabledTrailingIconContentColor: Color = disabledLeadingIconContentColor,
- ): ChipColors = DefaultChipColors(
+ ): ChipColors = ChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconContentColor = leadingIconContentColor,
@@ -895,25 +689,14 @@
hoveredElevation: Dp = defaultElevation,
draggedElevation: Dp = AssistChipTokens.DraggedContainerElevation,
disabledElevation: Dp = defaultElevation
- ): ChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ChipElevation = ChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [ChipBorder] that represents the default border used in a flat [AssistChip].
@@ -928,19 +711,11 @@
disabledBorderColor: Color = AssistChipTokens.FlatDisabledOutlineColor.toColor()
.copy(alpha = AssistChipTokens.FlatDisabledOutlineOpacity),
borderWidth: Dp = AssistChipTokens.FlatOutlineWidth,
- ): ChipBorder {
- return remember(
- borderColor,
- disabledBorderColor,
- borderWidth
- ) {
- DefaultChipBorder(
- borderColor = borderColor,
- disabledBorderColor = disabledBorderColor,
- borderWidth = borderWidth
- )
- }
- }
+ ): ChipBorder = ChipBorder(
+ borderColor = borderColor,
+ disabledBorderColor = disabledBorderColor,
+ borderWidth = borderWidth
+ )
/**
* Creates a [ChipColors] that represents the default container, label, and icon colors used in
@@ -969,7 +744,7 @@
AssistChipTokens.DisabledIconColor.toColor()
.copy(alpha = AssistChipTokens.DisabledIconOpacity),
disabledTrailingIconContentColor: Color = disabledLeadingIconContentColor,
- ): ChipColors = DefaultChipColors(
+ ): ChipColors = ChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconContentColor = leadingIconContentColor,
@@ -1000,25 +775,14 @@
hoveredElevation: Dp = AssistChipTokens.ElevatedHoverContainerElevation,
draggedElevation: Dp = AssistChipTokens.DraggedContainerElevation,
disabledElevation: Dp = AssistChipTokens.ElevatedDisabledContainerElevation
- ): ChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ChipElevation = ChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/** Default shape of an assist chip. */
val shape: Shape @Composable get() = AssistChipTokens.ContainerShape.toShape()
@@ -1076,7 +840,7 @@
selectedLabelColor: Color = FilterChipTokens.SelectedLabelTextColor.toColor(),
selectedLeadingIconColor: Color = FilterChipTokens.SelectedIconColor.toColor(),
selectedTrailingIconColor: Color = selectedLeadingIconColor
- ): SelectableChipColors = DefaultSelectableChipColors(
+ ): SelectableChipColors = SelectableChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconColor = iconColor,
@@ -1112,25 +876,14 @@
hoveredElevation: Dp = FilterChipTokens.FlatSelectedHoverContainerElevation,
draggedElevation: Dp = FilterChipTokens.DraggedContainerElevation,
disabledElevation: Dp = defaultElevation
- ): SelectableChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultSelectableChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): SelectableChipElevation = SelectableChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [SelectableChipBorder] that represents the default border used in a flat
@@ -1154,25 +907,14 @@
disabledSelectedBorderColor: Color = Color.Transparent,
borderWidth: Dp = FilterChipTokens.FlatUnselectedOutlineWidth,
selectedBorderWidth: Dp = FilterChipTokens.FlatSelectedOutlineWidth,
- ): SelectableChipBorder {
- return remember(
- borderColor,
- selectedBorderColor,
- disabledBorderColor,
- disabledSelectedBorderColor,
- borderWidth,
- selectedBorderWidth
- ) {
- DefaultSelectableChipBorder(
- borderColor = borderColor,
- selectedBorderColor = selectedBorderColor,
- disabledBorderColor = disabledBorderColor,
- disabledSelectedBorderColor = disabledSelectedBorderColor,
- borderWidth = borderWidth,
- selectedBorderWidth = selectedBorderWidth
- )
- }
- }
+ ): SelectableChipBorder = SelectableChipBorder(
+ borderColor = borderColor,
+ selectedBorderColor = selectedBorderColor,
+ disabledBorderColor = disabledBorderColor,
+ disabledSelectedBorderColor = disabledSelectedBorderColor,
+ borderWidth = borderWidth,
+ selectedBorderWidth = selectedBorderWidth
+ )
/**
* Creates a [SelectableChipColors] that represents the default container and content colors
@@ -1209,7 +951,7 @@
selectedLabelColor: Color = FilterChipTokens.SelectedLabelTextColor.toColor(),
selectedLeadingIconColor: Color = FilterChipTokens.SelectedIconColor.toColor(),
selectedTrailingIconColor: Color = selectedLeadingIconColor
- ): SelectableChipColors = DefaultSelectableChipColors(
+ ): SelectableChipColors = SelectableChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconColor = iconColor,
@@ -1245,25 +987,14 @@
hoveredElevation: Dp = FilterChipTokens.ElevatedHoverContainerElevation,
draggedElevation: Dp = FilterChipTokens.DraggedContainerElevation,
disabledElevation: Dp = FilterChipTokens.ElevatedDisabledContainerElevation
- ): SelectableChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultSelectableChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): SelectableChipElevation = SelectableChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/** Default shape of a filter chip. */
val shape: Shape @Composable get() = FilterChipTokens.ContainerShape.toShape()
@@ -1329,7 +1060,7 @@
selectedLabelColor: Color = InputChipTokens.SelectedLabelTextColor.toColor(),
selectedLeadingIconColor: Color = InputChipTokens.SelectedLeadingIconColor.toColor(),
selectedTrailingIconColor: Color = InputChipTokens.SelectedTrailingIconColor.toColor()
- ): SelectableChipColors = DefaultSelectableChipColors(
+ ): SelectableChipColors = SelectableChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconColor = leadingIconColor,
@@ -1365,25 +1096,14 @@
hoveredElevation: Dp = defaultElevation,
draggedElevation: Dp = InputChipTokens.DraggedContainerElevation,
disabledElevation: Dp = defaultElevation
- ): SelectableChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultSelectableChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): SelectableChipElevation = SelectableChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [SelectableChipBorder] that represents the default border used in an [InputChip].
@@ -1406,25 +1126,14 @@
disabledSelectedBorderColor: Color = Color.Transparent,
borderWidth: Dp = InputChipTokens.UnselectedOutlineWidth,
selectedBorderWidth: Dp = InputChipTokens.SelectedOutlineWidth,
- ): SelectableChipBorder {
- return remember(
- borderColor,
- selectedBorderColor,
- disabledBorderColor,
- disabledSelectedBorderColor,
- borderWidth,
- selectedBorderWidth
- ) {
- DefaultSelectableChipBorder(
- borderColor = borderColor,
- selectedBorderColor = selectedBorderColor,
- disabledBorderColor = disabledBorderColor,
- disabledSelectedBorderColor = disabledSelectedBorderColor,
- borderWidth = borderWidth,
- selectedBorderWidth = selectedBorderWidth
- )
- }
- }
+ ): SelectableChipBorder = SelectableChipBorder(
+ borderColor = borderColor,
+ selectedBorderColor = selectedBorderColor,
+ disabledBorderColor = disabledBorderColor,
+ disabledSelectedBorderColor = disabledSelectedBorderColor,
+ borderWidth = borderWidth,
+ selectedBorderWidth = selectedBorderWidth
+ )
/** Default shape of an input chip. */
val shape: Shape @Composable get() = InputChipTokens.ContainerShape.toShape()
@@ -1470,7 +1179,7 @@
.copy(alpha = SuggestionChipTokens.DisabledLabelTextOpacity),
// TODO(b/229778210): Read from the tokens when available.
disabledIconContentColor: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
- ): ChipColors = DefaultChipColors(
+ ): ChipColors = ChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconContentColor = iconContentColor,
@@ -1501,25 +1210,14 @@
hoveredElevation: Dp = defaultElevation,
draggedElevation: Dp = SuggestionChipTokens.DraggedContainerElevation,
disabledElevation: Dp = defaultElevation
- ): ChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ChipElevation = ChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/**
* Creates a [ChipBorder] that represents the default border used in a flat [SuggestionChip].
@@ -1534,17 +1232,11 @@
disabledBorderColor: Color = SuggestionChipTokens.FlatDisabledOutlineColor.toColor()
.copy(alpha = SuggestionChipTokens.FlatDisabledOutlineOpacity),
borderWidth: Dp = SuggestionChipTokens.FlatOutlineWidth,
- ): ChipBorder {
- return remember(
- borderColor, disabledBorderColor, borderWidth
- ) {
- DefaultChipBorder(
- borderColor = borderColor,
- disabledBorderColor = disabledBorderColor,
- borderWidth = borderWidth
- )
- }
- }
+ ): ChipBorder = ChipBorder(
+ borderColor = borderColor,
+ disabledBorderColor = disabledBorderColor,
+ borderWidth = borderWidth
+ )
/**
* Creates a [ChipColors] that represents the default container, label, and icon colors used in
@@ -1571,7 +1263,7 @@
.copy(alpha = SuggestionChipTokens.DisabledLabelTextOpacity),
// TODO(b/229778210): Read from the tokens when available.
disabledIconContentColor: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
- ): ChipColors = DefaultChipColors(
+ ): ChipColors = ChipColors(
containerColor = containerColor,
labelColor = labelColor,
leadingIconContentColor = iconContentColor,
@@ -1602,25 +1294,14 @@
hoveredElevation: Dp = SuggestionChipTokens.ElevatedHoverContainerElevation,
draggedElevation: Dp = SuggestionChipTokens.DraggedContainerElevation,
disabledElevation: Dp = SuggestionChipTokens.ElevatedDisabledContainerElevation
- ): ChipElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- draggedElevation,
- disabledElevation
- ) {
- DefaultChipElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- draggedElevation = draggedElevation,
- disabledElevation = disabledElevation
- )
- }
- }
+ ): ChipElevation = ChipElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ draggedElevation = draggedElevation,
+ disabledElevation = disabledElevation
+ )
/** Default shape of a suggestion chip. */
val shape: Shape @Composable get() = SuggestionChipTokens.ContainerShape.toShape()
@@ -1699,9 +1380,9 @@
enabled = enabled,
shape = shape,
color = colors.containerColor(enabled, selected).value,
- tonalElevation = elevation?.tonalElevation(enabled, selected, interactionSource)?.value
+ tonalElevation = elevation?.tonalElevation(enabled, interactionSource)?.value
?: 0.dp,
- shadowElevation = elevation?.shadowElevation(enabled, selected, interactionSource)?.value
+ shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value
?: 0.dp,
border = border,
interactionSource = interactionSource,
@@ -1764,27 +1445,53 @@
}
}
-/** Default [ChipElevation] implementation. */
+/**
+ * Represents the elevation for a chip in different states.
+ */
@ExperimentalMaterial3Api
@Immutable
-private class DefaultChipElevation(
+class ChipElevation internal constructor(
private val defaultElevation: Dp,
private val pressedElevation: Dp,
private val focusedElevation: Dp,
private val hoveredElevation: Dp,
private val draggedElevation: Dp,
private val disabledElevation: Dp
-) : ChipElevation {
+) {
+ /**
+ * Represents the tonal elevation used in a chip, depending on its [enabled] state and
+ * [interactionSource]. This should typically be the same value as the [shadowElevation].
+ *
+ * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
+ * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
+ * color in light theme and lighter color in dark theme.
+ *
+ * See [shadowElevation] which controls the elevation of the shadow drawn around the chip.
+ *
+ * @param enabled whether the chip is enabled
+ * @param interactionSource the [InteractionSource] for this chip
+ */
@Composable
- override fun tonalElevation(
+ internal fun tonalElevation(
enabled: Boolean,
interactionSource: InteractionSource
): State<Dp> {
return animateElevation(enabled = enabled, interactionSource = interactionSource)
}
+ /**
+ * Represents the shadow elevation used in a chip, depending on its [enabled] state and
+ * [interactionSource]. This should typically be the same value as the [tonalElevation].
+ *
+ * Shadow elevation is used to apply a shadow around the chip to give it higher emphasis.
+ *
+ * See [tonalElevation] which controls the elevation with a color shift to the surface.
+ *
+ * @param enabled whether the chip is enabled
+ * @param interactionSource the [InteractionSource] for this chip
+ */
@Composable
- override fun shadowElevation(
+ internal fun shadowElevation(
enabled: Boolean,
interactionSource: InteractionSource
): State<Dp> {
@@ -1870,10 +1577,32 @@
return animatable.asState()
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is ChipElevation) return false
+
+ if (defaultElevation != other.defaultElevation) return false
+ if (pressedElevation != other.pressedElevation) return false
+ if (focusedElevation != other.focusedElevation) return false
+ if (hoveredElevation != other.hoveredElevation) return false
+ if (disabledElevation != other.disabledElevation) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = defaultElevation.hashCode()
+ result = 31 * result + pressedElevation.hashCode()
+ result = 31 * result + focusedElevation.hashCode()
+ result = 31 * result + hoveredElevation.hashCode()
+ result = 31 * result + disabledElevation.hashCode()
+ return result
+ }
}
/**
- * Default [SelectableChipElevation] implementation.
+ * Represents the elevation used in a selectable chip in different states.
*
* Note that this default implementation does not take into consideration the `selectable` state
* passed into its [tonalElevation] and [shadowElevation]. If you wish to apply that state, use a
@@ -1881,27 +1610,49 @@
*/
@ExperimentalMaterial3Api
@Immutable
-private class DefaultSelectableChipElevation(
+class SelectableChipElevation internal constructor(
private val defaultElevation: Dp,
private val pressedElevation: Dp,
private val focusedElevation: Dp,
private val hoveredElevation: Dp,
private val draggedElevation: Dp,
private val disabledElevation: Dp
-) : SelectableChipElevation {
+) {
+ /**
+ * Represents the tonal elevation used in a chip, depending on [enabled], [selected], and
+ * [interactionSource]. This should typically be the same value as the [shadowElevation].
+ *
+ * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
+ * When surface's color is [ColorScheme.surface], a higher elevation will result in a darker
+ * color in light theme and lighter color in dark theme.
+ *
+ * See [shadowElevation] which controls the elevation of the shadow drawn around the Chip.
+ *
+ * @param enabled whether the chip is enabled
+ * @param interactionSource the [InteractionSource] for this chip
+ */
@Composable
- override fun tonalElevation(
+ internal fun tonalElevation(
enabled: Boolean,
- selected: Boolean,
interactionSource: InteractionSource
): State<Dp> {
return animateElevation(enabled = enabled, interactionSource = interactionSource)
}
+ /**
+ * Represents the shadow elevation used in a chip, depending on [enabled], [selected], and
+ * [interactionSource]. This should typically be the same value as the [tonalElevation].
+ *
+ * Shadow elevation is used to apply a shadow around the surface to give it higher emphasis.
+ *
+ * See [tonalElevation] which controls the elevation with a color shift to the surface.
+ *
+ * @param enabled whether the chip is enabled
+ * @param interactionSource the [InteractionSource] for this chip
+ */
@Composable
- override fun shadowElevation(
+ internal fun shadowElevation(
enabled: Boolean,
- selected: Boolean,
interactionSource: InteractionSource
): State<Dp> {
return animateElevation(enabled = enabled, interactionSource = interactionSource)
@@ -1986,14 +1737,39 @@
return animatable.asState()
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is SelectableChipElevation) return false
+
+ if (defaultElevation != other.defaultElevation) return false
+ if (pressedElevation != other.pressedElevation) return false
+ if (focusedElevation != other.focusedElevation) return false
+ if (hoveredElevation != other.hoveredElevation) return false
+ if (disabledElevation != other.disabledElevation) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = defaultElevation.hashCode()
+ result = 31 * result + pressedElevation.hashCode()
+ result = 31 * result + focusedElevation.hashCode()
+ result = 31 * result + hoveredElevation.hashCode()
+ result = 31 * result + disabledElevation.hashCode()
+ return result
+ }
}
/**
- * Default [ChipColors] implementation.
+ * Represents the container and content colors used in a clickable chip in different states.
+ *
+ * See [AssistChipDefaults], [InputChipDefaults], and [SuggestionChipDefaults] for the default
+ * colors used in the various Chip configurations.
*/
@ExperimentalMaterial3Api
@Immutable
-private class DefaultChipColors(
+class ChipColors internal constructor(
private val containerColor: Color,
private val labelColor: Color,
private val leadingIconContentColor: Color,
@@ -2003,26 +1779,46 @@
private val disabledLeadingIconContentColor: Color,
private val disabledTrailingIconContentColor: Color
// TODO(b/113855296): Support other states: hover, focus, drag
-) : ChipColors {
+) {
+ /**
+ * Represents the container color for this chip, depending on [enabled].
+ *
+ * @param enabled whether the chip is enabled
+ */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor)
}
+ /**
+ * Represents the label color for this chip, depending on [enabled].
+ *
+ * @param enabled whether the chip is enabled
+ */
@Composable
- override fun labelColor(enabled: Boolean): State<Color> {
+ internal fun labelColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) labelColor else disabledLabelColor)
}
+ /**
+ * Represents the leading icon's content color for this chip, depending on [enabled].
+ *
+ * @param enabled whether the chip is enabled
+ */
@Composable
- override fun leadingIconContentColor(enabled: Boolean): State<Color> {
+ internal fun leadingIconContentColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) leadingIconContentColor else disabledLeadingIconContentColor
)
}
+ /**
+ * Represents the trailing icon's content color for this chip, depending on [enabled].
+ *
+ * @param enabled whether the chip is enabled
+ */
@Composable
- override fun trailingIconContentColor(enabled: Boolean): State<Color> {
+ internal fun trailingIconContentColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) trailingIconContentColor else disabledTrailingIconContentColor
)
@@ -2030,9 +1826,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultChipColors
+ if (other == null || other !is ChipColors) return false
if (containerColor != other.containerColor) return false
if (labelColor != other.labelColor) return false
@@ -2061,11 +1855,14 @@
}
/**
- * Default [SelectableChipColors] implementation.
+ * Represents the container and content colors used in a selectable chip in different states.
+ *
+ * See [FilterChipDefaults.filterChipColors] and [FilterChipDefaults.elevatedFilterChipColors] for
+ * the default colors used in [FilterChip].
*/
@ExperimentalMaterial3Api
@Immutable
-private class DefaultSelectableChipColors(
+class SelectableChipColors internal constructor(
private val containerColor: Color,
private val labelColor: Color,
private val leadingIconColor: Color,
@@ -2080,9 +1877,15 @@
private val selectedLeadingIconColor: Color,
private val selectedTrailingIconColor: Color
// TODO(b/113855296): Support other states: hover, focus, drag
-) : SelectableChipColors {
+) {
+ /**
+ * Represents the container color for this chip, depending on [enabled] and [selected].
+ *
+ * @param enabled whether the chip is enabled
+ * @param selected whether the chip is selected
+ */
@Composable
- override fun containerColor(enabled: Boolean, selected: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean, selected: Boolean): State<Color> {
val target = when {
!enabled -> if (selected) disabledSelectedContainerColor else disabledContainerColor
!selected -> containerColor
@@ -2091,8 +1894,14 @@
return rememberUpdatedState(target)
}
+ /**
+ * Represents the label color for this chip, depending on [enabled] and [selected].
+ *
+ * @param enabled whether the chip is enabled
+ * @param selected whether the chip is selected
+ */
@Composable
- override fun labelColor(enabled: Boolean, selected: Boolean): State<Color> {
+ internal fun labelColor(enabled: Boolean, selected: Boolean): State<Color> {
val target = when {
!enabled -> disabledLabelColor
!selected -> labelColor
@@ -2101,8 +1910,14 @@
return rememberUpdatedState(target)
}
+ /**
+ * Represents the leading icon color for this chip, depending on [enabled] and [selected].
+ *
+ * @param enabled whether the chip is enabled
+ * @param selected whether the chip is selected
+ */
@Composable
- override fun leadingIconContentColor(enabled: Boolean, selected: Boolean): State<Color> {
+ internal fun leadingIconContentColor(enabled: Boolean, selected: Boolean): State<Color> {
val target = when {
!enabled -> disabledLeadingIconColor
!selected -> leadingIconColor
@@ -2111,8 +1926,14 @@
return rememberUpdatedState(target)
}
+ /**
+ * Represents the trailing icon color for this chip, depending on [enabled] and [selected].
+ *
+ * @param enabled whether the chip is enabled
+ * @param selected whether the chip is selected
+ */
@Composable
- override fun trailingIconContentColor(enabled: Boolean, selected: Boolean): State<Color> {
+ internal fun trailingIconContentColor(enabled: Boolean, selected: Boolean): State<Color> {
val target = when {
!enabled -> disabledTrailingIconColor
!selected -> trailingIconColor
@@ -2123,9 +1944,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultSelectableChipColors
+ if (other == null || other !is SelectableChipColors) return false
if (containerColor != other.containerColor) return false
if (labelColor != other.labelColor) return false
@@ -2164,20 +1983,27 @@
}
/**
- * Default [SelectableChipBorder] implementation.
+ * Represents the border stroke used used in a selectable chip in different states.
*/
@ExperimentalMaterial3Api
@Immutable
-private class DefaultSelectableChipBorder(
+class SelectableChipBorder internal constructor(
private val borderColor: Color,
private val selectedBorderColor: Color,
private val disabledBorderColor: Color,
private val disabledSelectedBorderColor: Color,
private val borderWidth: Dp,
private val selectedBorderWidth: Dp
-) : SelectableChipBorder {
+) {
+ /**
+ * Represents the [BorderStroke] stroke used for this chip, depending on [enabled] and
+ * [selected].
+ *
+ * @param enabled whether the chip is enabled
+ * @param selected whether the chip is selected
+ */
@Composable
- override fun borderStroke(enabled: Boolean, selected: Boolean): State<BorderStroke?> {
+ internal fun borderStroke(enabled: Boolean, selected: Boolean): State<BorderStroke?> {
val color = if (enabled) {
if (selected) selectedBorderColor else borderColor
} else {
@@ -2190,9 +2016,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultSelectableChipBorder
+ if (other == null || other !is SelectableChipBorder) return false
if (borderColor != other.borderColor) return false
if (selectedBorderColor != other.selectedBorderColor) return false
@@ -2217,17 +2041,22 @@
}
/**
- * Default [ChipBorder] implementation.
+ * Represents the border stroke used in a chip in different states.
*/
@ExperimentalMaterial3Api
@Immutable
-private class DefaultChipBorder(
+class ChipBorder internal constructor(
private val borderColor: Color,
private val disabledBorderColor: Color,
private val borderWidth: Dp,
-) : ChipBorder {
+) {
+ /**
+ * Represents the [BorderStroke] for this chip, depending on [enabled].
+ *
+ * @param enabled whether the chip is enabled
+ */
@Composable
- override fun borderStroke(enabled: Boolean): State<BorderStroke?> {
+ internal fun borderStroke(enabled: Boolean): State<BorderStroke?> {
return rememberUpdatedState(
BorderStroke(borderWidth, if (enabled) borderColor else disabledBorderColor)
)
@@ -2235,9 +2064,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultChipBorder
+ if (other == null || other !is ChipBorder) return false
if (borderColor != other.borderColor) return false
if (disabledBorderColor != other.disabledBorderColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
index f43dc91..19b5893 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt
@@ -607,6 +607,7 @@
internal const val DisabledAlpha = 0.38f
/** Converts a color token key to the local color scheme provided by the theme */
+@ReadOnlyComposable
@Composable
internal fun ColorSchemeKeyTokens.toColor(): Color {
return MaterialTheme.colorScheme.fromToken(this)
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
index 8783c11..40362cf 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
@@ -383,43 +383,6 @@
}
/**
- * Represents the tonal and shadow elevation for a floating action button in different states.
- *
- * See [FloatingActionButtonDefaults.elevation] for the default elevation used in a
- * [FloatingActionButton] and [ExtendedFloatingActionButton].
- */
-@Stable
-interface FloatingActionButtonElevation {
- /**
- * Represents the tonal elevation used in a floating action button, depending on
- * [interactionSource]. This should typically be the same value as the [shadowElevation].
- *
- * Tonal elevation is used to apply a color shift to the surface to give the it higher emphasis.
- * When surface's color is [ColorScheme.surface], a higher the elevation will result in a darker
- * color in light theme and lighter color in dark theme.
- *
- * See [shadowElevation] which controls the elevation of the shadow drawn around the FAB.
- *
- * @param interactionSource the [InteractionSource] for this floating action button
- */
- @Composable
- fun tonalElevation(interactionSource: InteractionSource): State<Dp>
-
- /**
- * Represents the shadow elevation used in a floating action button, depending on
- * [interactionSource]. This should typically be the same value as the [tonalElevation].
- *
- * Shadow elevation is used to apply a shadow around the FAB to give it higher emphasis.
- *
- * See [tonalElevation] which controls the elevation with a color shift to the surface.
- *
- * @param interactionSource the [InteractionSource] for this floating action button
- */
- @Composable
- fun shadowElevation(interactionSource: InteractionSource): State<Dp>
-}
-
-/**
* Contains the default values used by [FloatingActionButton]
*/
object FloatingActionButtonDefaults {
@@ -461,21 +424,12 @@
pressedElevation: Dp = FabPrimaryTokens.PressedContainerElevation,
focusedElevation: Dp = FabPrimaryTokens.FocusContainerElevation,
hoveredElevation: Dp = FabPrimaryTokens.HoverContainerElevation,
- ): FloatingActionButtonElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- ) {
- DefaultFloatingActionButtonElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- )
- }
- }
+ ): FloatingActionButtonElevation = FloatingActionButtonElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ )
/**
* Use this to create a [FloatingActionButton] with a lowered elevation for less emphasis. Use
@@ -493,40 +447,56 @@
pressedElevation: Dp = FabPrimaryTokens.LoweredPressedContainerElevation,
focusedElevation: Dp = FabPrimaryTokens.LoweredFocusContainerElevation,
hoveredElevation: Dp = FabPrimaryTokens.LoweredHoverContainerElevation,
- ): FloatingActionButtonElevation {
- return remember(
- defaultElevation,
- pressedElevation,
- focusedElevation,
- hoveredElevation,
- ) {
- DefaultFloatingActionButtonElevation(
- defaultElevation = defaultElevation,
- pressedElevation = pressedElevation,
- focusedElevation = focusedElevation,
- hoveredElevation = hoveredElevation,
- )
- }
- }
+ ): FloatingActionButtonElevation = FloatingActionButtonElevation(
+ defaultElevation = defaultElevation,
+ pressedElevation = pressedElevation,
+ focusedElevation = focusedElevation,
+ hoveredElevation = hoveredElevation,
+ )
+
+ /**
+ * Use this to create a [FloatingActionButton] that represents the default elevation of a
+ * [FloatingActionButton] used for [BottomAppBar] in different states.
+ *
+ * @param defaultElevation the elevation used when the [FloatingActionButton] has no other
+ * [Interaction]s.
+ * @param pressedElevation the elevation used when the [FloatingActionButton] is pressed.
+ * @param focusedElevation the elevation used when the [FloatingActionButton] is focused.
+ * @param hoveredElevation the elevation used when the [FloatingActionButton] is hovered.
+ */
+ fun bottomAppBarFabElevation(
+ defaultElevation: Dp = 0.dp,
+ pressedElevation: Dp = 0.dp,
+ focusedElevation: Dp = 0.dp,
+ hoveredElevation: Dp = 0.dp
+ ): FloatingActionButtonElevation = FloatingActionButtonElevation(
+ defaultElevation,
+ pressedElevation,
+ focusedElevation,
+ hoveredElevation
+ )
}
/**
- * Default [FloatingActionButtonElevation] implementation.
+ * Represents the tonal and shadow elevation for a floating action button in different states.
+ *
+ * See [FloatingActionButtonDefaults.elevation] for the default elevation used in a
+ * [FloatingActionButton] and [ExtendedFloatingActionButton].
*/
@Stable
-private class DefaultFloatingActionButtonElevation(
+ open class FloatingActionButtonElevation internal constructor(
private val defaultElevation: Dp,
private val pressedElevation: Dp,
private val focusedElevation: Dp,
private val hoveredElevation: Dp,
-) : FloatingActionButtonElevation {
+) {
@Composable
- override fun shadowElevation(interactionSource: InteractionSource): State<Dp> {
+ internal fun shadowElevation(interactionSource: InteractionSource): State<Dp> {
return animateElevation(interactionSource = interactionSource)
}
@Composable
- override fun tonalElevation(interactionSource: InteractionSource): State<Dp> {
+ internal fun tonalElevation(interactionSource: InteractionSource): State<Dp> {
return animateElevation(interactionSource = interactionSource)
}
@@ -588,6 +558,26 @@
}
return animatable.asState()
}
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is FloatingActionButtonElevation) return false
+
+ if (defaultElevation != other.defaultElevation) return false
+ if (pressedElevation != other.pressedElevation) return false
+ if (focusedElevation != other.focusedElevation) return false
+ if (hoveredElevation != other.hoveredElevation) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = defaultElevation.hashCode()
+ result = 31 * result + pressedElevation.hashCode()
+ result = 31 * result + focusedElevation.hashCode()
+ result = 31 * result + hoveredElevation.hashCode()
+ return result
+ }
}
private val ExtendedFabStartIconPadding = 16.dp
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
index e231a10..1893d1a 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
@@ -31,7 +31,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -534,65 +533,6 @@
}
/**
- * Represents the container and content colors used in an icon button in different states.
- *
- * - See [IconButtonDefaults.filledIconButtonColors] and
- * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a
- * [FilledIconButton].
- * - See [IconButtonDefaults.outlinedIconButtonColors] for the default colors used in an
- * [OutlinedIconButton].
- */
-@Stable
-interface IconButtonColors {
- /**
- * Represents the container color for this icon button, depending on [enabled].
- *
- * @param enabled whether the icon button is enabled
- */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the content color for this icon button, depending on [enabled].
- *
- * @param enabled whether the icon button is enabled
- */
- @Composable
- fun contentColor(enabled: Boolean): State<Color>
-}
-
-/**
- * Represents the container and content colors used in a toggleable icon button in
- * different states.
- *
- * - See [IconButtonDefaults.filledIconToggleButtonColors] and
- * [IconButtonDefaults.filledTonalIconToggleButtonColors] for the default colors used in a
- * [FilledIconButton].
- * - See [IconButtonDefaults.outlinedIconToggleButtonColors] for the default colors used in a
- * toggleable [OutlinedIconButton].
- */
-@Stable
-interface IconToggleButtonColors {
- /**
- * Represents the container color for this icon button, depending on [enabled] and [checked].
- *
- * @param enabled whether the icon button is enabled
- * @param checked whether the icon button is checked
- */
- @Composable
- fun containerColor(enabled: Boolean, checked: Boolean): State<Color>
-
- /**
- * Represents the content color for this icon button, depending on [enabled] and [checked].
- *
- * @param enabled whether the icon button is enabled
- * @param checked whether the icon button is checked
- */
- @Composable
- fun contentColor(enabled: Boolean, checked: Boolean): State<Color>
-}
-
-/**
* Contains the default values used by all icon button types.
*/
object IconButtonDefaults {
@@ -620,7 +560,7 @@
disabledContentColor: Color =
contentColor.copy(alpha = IconButtonTokens.DisabledIconOpacity)
): IconButtonColors =
- DefaultIconButtonColors(
+ IconButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -648,7 +588,7 @@
checkedContainerColor: Color = Color.Transparent,
checkedContentColor: Color = IconButtonTokens.SelectedIconColor.toColor()
): IconToggleButtonColors =
- DefaultIconToggleButtonColors(
+ IconToggleButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -674,7 +614,7 @@
disabledContentColor: Color = FilledIconButtonTokens.DisabledColor.toColor()
.copy(alpha = FilledIconButtonTokens.DisabledOpacity)
): IconButtonColors =
- DefaultIconButtonColors(
+ IconButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -705,7 +645,7 @@
checkedContainerColor: Color = FilledIconButtonTokens.SelectedContainerColor.toColor(),
checkedContentColor: Color = contentColorFor(checkedContainerColor)
): IconToggleButtonColors =
- DefaultIconToggleButtonColors(
+ IconToggleButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -732,7 +672,7 @@
disabledContentColor: Color = FilledTonalIconButtonTokens.DisabledColor.toColor()
.copy(alpha = FilledTonalIconButtonTokens.DisabledOpacity)
): IconButtonColors =
- DefaultIconButtonColors(
+ IconButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -762,7 +702,7 @@
FilledTonalIconButtonTokens.SelectedContainerColor.toColor(),
checkedContentColor: Color = FilledTonalIconButtonTokens.ToggleSelectedColor.toColor()
): IconToggleButtonColors =
- DefaultIconToggleButtonColors(
+ IconToggleButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -788,7 +728,7 @@
disabledContentColor: Color =
contentColor.copy(alpha = OutlinedIconButtonTokens.DisabledOpacity)
): IconButtonColors =
- DefaultIconButtonColors(
+ IconButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -817,7 +757,7 @@
OutlinedIconButtonTokens.SelectedContainerColor.toColor(),
checkedContentColor: Color = contentColorFor(checkedContainerColor)
): IconToggleButtonColors =
- DefaultIconToggleButtonColors(
+ IconToggleButtonColors(
containerColor = containerColor,
contentColor = contentColor,
disabledContainerColor = disabledContainerColor,
@@ -861,30 +801,44 @@
}
/**
- * Default [IconButtonColors] implementation.
+ * Represents the container and content colors used in an icon button in different states.
+ *
+ * - See [IconButtonDefaults.filledIconButtonColors] and
+ * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a
+ * [FilledIconButton].
+ * - See [IconButtonDefaults.outlinedIconButtonColors] for the default colors used in an
+ * [OutlinedIconButton].
*/
@Immutable
-private class DefaultIconButtonColors(
+class IconButtonColors internal constructor(
private val containerColor: Color,
private val contentColor: Color,
private val disabledContainerColor: Color,
private val disabledContentColor: Color,
-) : IconButtonColors {
+) {
+ /**
+ * Represents the container color for this icon button, depending on [enabled].
+ *
+ * @param enabled whether the icon button is enabled
+ */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor)
}
+ /**
+ * Represents the content color for this icon button, depending on [enabled].
+ *
+ * @param enabled whether the icon button is enabled
+ */
@Composable
- override fun contentColor(enabled: Boolean): State<Color> {
+ internal fun contentColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) contentColor else disabledContentColor)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultIconButtonColors
+ if (other == null || other !is IconButtonColors) return false
if (containerColor != other.containerColor) return false
if (contentColor != other.contentColor) return false
@@ -905,19 +859,32 @@
}
/**
- * Default [IconToggleButtonColors] implementation.
+ * Represents the container and content colors used in a toggleable icon button in
+ * different states.
+ *
+ * - See [IconButtonDefaults.filledIconToggleButtonColors] and
+ * [IconButtonDefaults.filledTonalIconToggleButtonColors] for the default colors used in a
+ * [FilledIconButton].
+ * - See [IconButtonDefaults.outlinedIconToggleButtonColors] for the default colors used in a
+ * toggleable [OutlinedIconButton].
*/
@Immutable
-private class DefaultIconToggleButtonColors(
+class IconToggleButtonColors internal constructor(
private val containerColor: Color,
private val contentColor: Color,
private val disabledContainerColor: Color,
private val disabledContentColor: Color,
private val checkedContainerColor: Color,
private val checkedContentColor: Color,
-) : IconToggleButtonColors {
+) {
+ /**
+ * Represents the container color for this icon button, depending on [enabled] and [checked].
+ *
+ * @param enabled whether the icon button is enabled
+ * @param checked whether the icon button is checked
+ */
@Composable
- override fun containerColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun containerColor(enabled: Boolean, checked: Boolean): State<Color> {
val target = when {
!enabled -> disabledContainerColor
!checked -> containerColor
@@ -926,8 +893,14 @@
return rememberUpdatedState(target)
}
+ /**
+ * Represents the content color for this icon button, depending on [enabled] and [checked].
+ *
+ * @param enabled whether the icon button is enabled
+ * @param checked whether the icon button is checked
+ */
@Composable
- override fun contentColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun contentColor(enabled: Boolean, checked: Boolean): State<Color> {
val target = when {
!enabled -> disabledContentColor
!checked -> contentColor
@@ -938,9 +911,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultIconToggleButtonColors
+ if (other == null || other !is IconToggleButtonColors) return false
if (containerColor != other.containerColor) return false
if (contentColor != other.contentColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
index cdca4adc..1e8f666 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
@@ -28,7 +28,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
@@ -83,7 +82,7 @@
// One-Line List Item
ListItem(
modifier = modifier,
- containerColor = colors.containerColor(enabled = true).value,
+ containerColor = colors.containerColor().value,
contentColor = colors.headlineColor(enabled = true).value,
tonalElevation = tonalElevation,
shadowElevation = shadowElevation,
@@ -120,7 +119,7 @@
// Two-Line List Item
ListItem(
modifier = modifier,
- containerColor = colors.containerColor(enabled = true).value,
+ containerColor = colors.containerColor().value,
contentColor = colors.headlineColor(enabled = true).value,
tonalElevation = tonalElevation,
shadowElevation = shadowElevation,
@@ -146,7 +145,7 @@
headlineText
)
ProvideTextStyleFromToken(
- colors.supportingColor(enabled = true).value,
+ colors.supportingColor().value,
ListTokens.ListItemSupportingTextFont,
supportingText!!
)
@@ -164,7 +163,7 @@
// Two-Line List Item
ListItem(
modifier = modifier,
- containerColor = colors.containerColor(enabled = true).value,
+ containerColor = colors.containerColor().value,
contentColor = colors.headlineColor(enabled = true).value,
tonalElevation = tonalElevation,
shadowElevation = shadowElevation,
@@ -185,7 +184,7 @@
) {
Column {
ProvideTextStyleFromToken(
- colors.overlineColor(enabled = true).value,
+ colors.overlineColor().value,
ListTokens.ListItemOverlineFont,
overlineText
)
@@ -208,7 +207,7 @@
// Three-Line List Item
ListItem(
modifier = modifier,
- containerColor = colors.containerColor(enabled = true).value,
+ containerColor = colors.containerColor().value,
contentColor = colors.headlineColor(enabled = true).value,
tonalElevation = tonalElevation,
shadowElevation = shadowElevation,
@@ -232,7 +231,7 @@
) {
Column {
ProvideTextStyleFromToken(
- colors.overlineColor(enabled = true).value,
+ colors.overlineColor().value,
ListTokens.ListItemOverlineFont,
overlineText
)
@@ -242,7 +241,7 @@
headlineText
)
ProvideTextStyleFromToken(
- colors.supportingColor(enabled = true).value,
+ colors.supportingColor().value,
ListTokens.ListItemSupportingTextFont,
supportingText
)
@@ -411,7 +410,7 @@
disabledTrailingIconColor: Color = ListTokens.ListItemDisabledTrailingIconColor.toColor()
.copy(alpha = ListTokens.ListItemDisabledTrailingIconOpacity)
): ListItemColors =
- DefaultListItemColors(
+ ListItemColors(
containerColor = containerColor,
headlineColor = headlineColor,
leadingIconColor = leadingIconColor,
@@ -429,39 +428,9 @@
*
* - See [ListItemDefaults.colors] for the default colors used in a [ListItem].
*/
-@Stable
-@ExperimentalMaterial3Api
-interface ListItemColors {
-
- /** The container color of this [ListItem] based on enabled state */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /** The color of this [ListItem]'s headline text based on enabled state */
- @Composable
- fun headlineColor(enabled: Boolean): State<Color>
-
- /** The color of this [ListItem]'s leading content based on enabled state */
- @Composable
- fun leadingIconColor(enabled: Boolean): State<Color>
-
- /** The color of this [ListItem]'s overline text based on enabled state */
- @Composable
- fun overlineColor(enabled: Boolean): State<Color>
-
- /** The color of this [ListItem]'s supporting text based on enabled state */
- @Composable
- fun supportingColor(enabled: Boolean): State<Color>
-
- /** The color of this [ListItem]'s trailing content based on enabled state */
- @Composable
- fun trailingIconColor(enabled: Boolean): State<Color>
-}
-
-/** Default [ListItemColors] implementation. */
@ExperimentalMaterial3Api
@Immutable
-private class DefaultListItemColors(
+class ListItemColors internal constructor(
private val containerColor: Color,
private val headlineColor: Color,
private val leadingIconColor: Color,
@@ -471,38 +440,44 @@
private val disabledHeadlineColor: Color,
private val disabledLeadingIconColor: Color,
private val disabledTrailingIconColor: Color,
-) : ListItemColors {
+) {
+ /** The container color of this [ListItem] based on enabled state */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(): State<Color> {
return rememberUpdatedState(containerColor)
}
+ /** The color of this [ListItem]'s headline text based on enabled state */
@Composable
- override fun headlineColor(enabled: Boolean): State<Color> {
+ internal fun headlineColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) headlineColor else disabledHeadlineColor
)
}
+ /** The color of this [ListItem]'s leading content based on enabled state */
@Composable
- override fun leadingIconColor(enabled: Boolean): State<Color> {
+ internal fun leadingIconColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) leadingIconColor else disabledLeadingIconColor
)
}
+ /** The color of this [ListItem]'s overline text based on enabled state */
@Composable
- override fun overlineColor(enabled: Boolean): State<Color> {
+ internal fun overlineColor(): State<Color> {
return rememberUpdatedState(overlineColor)
}
+ /** The color of this [ListItem]'s supporting text based on enabled state */
@Composable
- override fun supportingColor(enabled: Boolean): State<Color> {
+ internal fun supportingColor(): State<Color> {
return rememberUpdatedState(supportingTextColor)
}
+ /** The color of this [ListItem]'s trailing content based on enabled state */
@Composable
- override fun trailingIconColor(enabled: Boolean): State<Color> {
+ internal fun trailingIconColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) trailingIconColor else disabledTrailingIconColor
)
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
index c78fa9f..0ff7c120 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
@@ -42,7 +42,6 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
@@ -182,7 +181,8 @@
}
CompositionLocalProvider(LocalContentColor provides colors.textColor(enabled).value) {
Box(
- Modifier.weight(1f)
+ Modifier
+ .weight(1f)
.padding(
start = if (leadingIcon != null) {
DropdownMenuItemHorizontalPadding
@@ -243,15 +243,14 @@
.copy(alpha = MenuTokens.ListItemDisabledLeadingIconOpacity),
disabledTrailingIconColor: Color = MenuTokens.ListItemDisabledTrailingIconColor.toColor()
.copy(alpha = MenuTokens.ListItemDisabledTrailingIconOpacity),
- ): MenuItemColors =
- DefaultMenuItemColors(
- textColor = textColor,
- leadingIconColor = leadingIconColor,
- trailingIconColor = trailingIconColor,
- disabledTextColor = disabledTextColor,
- disabledLeadingIconColor = disabledLeadingIconColor,
- disabledTrailingIconColor = disabledTrailingIconColor,
- )
+ ): MenuItemColors = MenuItemColors(
+ textColor = textColor,
+ leadingIconColor = leadingIconColor,
+ trailingIconColor = trailingIconColor,
+ disabledTextColor = disabledTextColor,
+ disabledLeadingIconColor = disabledLeadingIconColor,
+ disabledTrailingIconColor = disabledTrailingIconColor,
+ )
/**
* Default padding used for [DropdownMenuItem].
@@ -262,39 +261,6 @@
)
}
-/**
- * Represents the text and icon colors used in a menu item at different states.
- *
- * - See [MenuDefaults.itemColors] for the default colors used in a [DropdownMenuItemContent].
- */
-@Stable
-interface MenuItemColors {
-
- /**
- * Represents the text color for a menu item, depending on its [enabled] state.
- *
- * @param enabled whether the menu item is enabled
- */
- @Composable
- fun textColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the leading icon color for a menu item, depending on its [enabled] state.
- *
- * @param enabled whether the menu item is enabled
- */
- @Composable
- fun leadingIconColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the trailing icon color for a menu item, depending on its [enabled] state.
- *
- * @param enabled whether the menu item is enabled
- */
- @Composable
- fun trailingIconColor(enabled: Boolean): State<Color>
-}
-
internal fun calculateTransformOrigin(
parentBounds: IntRect,
menuBounds: IntRect
@@ -395,37 +361,53 @@
}
}
-/** Default [MenuItemColors] implementation. */
+/**
+ * Represents the text and icon colors used in a menu item at different states.
+ *
+ * - See [MenuDefaults.itemColors] for the default colors used in a [DropdownMenuItemContent].
+ */
@Immutable
-private class DefaultMenuItemColors(
+class MenuItemColors internal constructor(
private val textColor: Color,
private val leadingIconColor: Color,
private val trailingIconColor: Color,
private val disabledTextColor: Color,
private val disabledLeadingIconColor: Color,
private val disabledTrailingIconColor: Color,
-) : MenuItemColors {
-
+) {
+ /**
+ * Represents the text color for a menu item, depending on its [enabled] state.
+ *
+ * @param enabled whether the menu item is enabled
+ */
@Composable
- override fun textColor(enabled: Boolean): State<Color> {
+ internal fun textColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) textColor else disabledTextColor)
}
+ /**
+ * Represents the leading icon color for a menu item, depending on its [enabled] state.
+ *
+ * @param enabled whether the menu item is enabled
+ */
@Composable
- override fun leadingIconColor(enabled: Boolean): State<Color> {
+ internal fun leadingIconColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) leadingIconColor else disabledLeadingIconColor)
}
+ /**
+ * Represents the trailing icon color for a menu item, depending on its [enabled] state.
+ *
+ * @param enabled whether the menu item is enabled
+ */
@Composable
- override fun trailingIconColor(enabled: Boolean): State<Color> {
+ internal fun trailingIconColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) trailingIconColor else disabledTrailingIconColor)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultMenuItemColors
+ if (other == null || other !is MenuItemColors) return false
if (textColor != other.textColor) return false
if (leadingIconColor != other.leadingIconColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
index a6ffd46..b36e120 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
@@ -275,33 +275,35 @@
indicatorColor: Color = NavigationBarTokens.ActiveIndicatorColor.toColor(),
unselectedIconColor: Color = NavigationBarTokens.InactiveIconColor.toColor(),
unselectedTextColor: Color = NavigationBarTokens.InactiveLabelTextColor.toColor(),
- ): NavigationBarItemColors = remember(
- selectedIconColor,
- unselectedIconColor,
- selectedTextColor,
- unselectedTextColor,
- indicatorColor
- ) {
- DefaultNavigationBarItemColors(
- selectedIconColor = selectedIconColor,
- selectedTextColor = selectedTextColor,
- selectedIndicatorColor = indicatorColor,
- unselectedIconColor = unselectedIconColor,
- unselectedTextColor = unselectedTextColor,
- )
- }
+ ): NavigationBarItemColors = NavigationBarItemColors(
+ selectedIconColor = selectedIconColor,
+ selectedTextColor = selectedTextColor,
+ selectedIndicatorColor = indicatorColor,
+ unselectedIconColor = unselectedIconColor,
+ unselectedTextColor = unselectedTextColor,
+ )
}
-/** Represents the colors of the various elements of a navigation item. */
@Stable
-interface NavigationBarItemColors {
+class NavigationBarItemColors internal constructor(
+ private val selectedIconColor: Color,
+ private val selectedTextColor: Color,
+ private val selectedIndicatorColor: Color,
+ private val unselectedIconColor: Color,
+ private val unselectedTextColor: Color,
+) {
/**
* Represents the icon color for this item, depending on whether it is [selected].
*
* @param selected whether the item is selected
*/
@Composable
- fun iconColor(selected: Boolean): State<Color>
+ internal fun iconColor(selected: Boolean): State<Color> {
+ return animateColorAsState(
+ targetValue = if (selected) selectedIconColor else unselectedIconColor,
+ animationSpec = tween(ItemAnimationDurationMillis)
+ )
+ }
/**
* Represents the text color for this item, depending on whether it is [selected].
@@ -309,40 +311,38 @@
* @param selected whether the item is selected
*/
@Composable
- fun textColor(selected: Boolean): State<Color>
-
- /** Represents the color of the indicator used for selected items. */
- val indicatorColor: Color
- @Composable get
-}
-
-@Stable
-private class DefaultNavigationBarItemColors(
- private val selectedIconColor: Color,
- private val selectedTextColor: Color,
- private val selectedIndicatorColor: Color,
- private val unselectedIconColor: Color,
- private val unselectedTextColor: Color,
-) : NavigationBarItemColors {
- @Composable
- override fun iconColor(selected: Boolean): State<Color> {
- return animateColorAsState(
- targetValue = if (selected) selectedIconColor else unselectedIconColor,
- animationSpec = tween(ItemAnimationDurationMillis)
- )
- }
-
- @Composable
- override fun textColor(selected: Boolean): State<Color> {
+ internal fun textColor(selected: Boolean): State<Color> {
return animateColorAsState(
targetValue = if (selected) selectedTextColor else unselectedTextColor,
animationSpec = tween(ItemAnimationDurationMillis)
)
}
- override val indicatorColor: Color
- @Composable
+ /** Represents the color of the indicator used for selected items. */
+ internal val indicatorColor: Color
get() = selectedIndicatorColor
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is NavigationBarItemColors) return false
+
+ if (selectedIconColor != other.selectedIconColor) return false
+ if (unselectedIconColor != other.unselectedIconColor) return false
+ if (selectedTextColor != other.selectedTextColor) return false
+ if (unselectedTextColor != other.unselectedTextColor) return false
+ if (selectedIndicatorColor != other.selectedIndicatorColor) return false
+
+ return true
+ }
+ override fun hashCode(): Int {
+ var result = selectedIconColor.hashCode()
+ result = 31 * result + unselectedIconColor.hashCode()
+ result = 31 * result + selectedTextColor.hashCode()
+ result = 31 * result + unselectedTextColor.hashCode()
+ result = 31 * result + selectedIndicatorColor.hashCode()
+
+ return result
+ }
}
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
index f23f0ed..a870705 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
@@ -277,33 +277,36 @@
indicatorColor: Color = NavigationRailTokens.ActiveIndicatorColor.toColor(),
unselectedIconColor: Color = NavigationRailTokens.InactiveIconColor.toColor(),
unselectedTextColor: Color = NavigationRailTokens.InactiveLabelTextColor.toColor(),
- ): NavigationRailItemColors = remember(
- selectedIconColor,
- unselectedIconColor,
- selectedTextColor,
- unselectedTextColor,
- indicatorColor
- ) {
- DefaultNavigationRailItemColors(
- selectedIconColor = selectedIconColor,
- unselectedIconColor = unselectedIconColor,
- selectedTextColor = selectedTextColor,
- unselectedTextColor = unselectedTextColor,
- selectedIndicatorColor = indicatorColor,
- )
- }
+ ): NavigationRailItemColors = NavigationRailItemColors(
+ selectedIconColor = selectedIconColor,
+ selectedTextColor = selectedTextColor,
+ selectedIndicatorColor = indicatorColor,
+ unselectedIconColor = unselectedIconColor,
+ unselectedTextColor = unselectedTextColor,
+ )
}
/** Represents the colors of the various elements of a navigation item. */
@Stable
-interface NavigationRailItemColors {
+class NavigationRailItemColors internal constructor(
+ private val selectedIconColor: Color,
+ private val selectedTextColor: Color,
+ private val selectedIndicatorColor: Color,
+ private val unselectedIconColor: Color,
+ private val unselectedTextColor: Color,
+) {
/**
* Represents the icon color for this item, depending on whether it is [selected].
*
* @param selected whether the item is selected
*/
@Composable
- fun iconColor(selected: Boolean): State<Color>
+ internal fun iconColor(selected: Boolean): State<Color> {
+ return animateColorAsState(
+ targetValue = if (selected) selectedIconColor else unselectedIconColor,
+ animationSpec = tween(ItemAnimationDurationMillis)
+ )
+ }
/**
* Represents the text color for this item, depending on whether it is [selected].
@@ -311,40 +314,40 @@
* @param selected whether the item is selected
*/
@Composable
- fun textColor(selected: Boolean): State<Color>
-
- /** Represents the color of the indicator used for selected items. */
- val indicatorColor: Color
- @Composable get
-}
-
-@Stable
-private class DefaultNavigationRailItemColors(
- private val selectedIconColor: Color,
- private val selectedTextColor: Color,
- private val selectedIndicatorColor: Color,
- private val unselectedIconColor: Color,
- private val unselectedTextColor: Color,
-) : NavigationRailItemColors {
- @Composable
- override fun iconColor(selected: Boolean): State<Color> {
- return animateColorAsState(
- targetValue = if (selected) selectedIconColor else unselectedIconColor,
- animationSpec = tween(ItemAnimationDurationMillis)
- )
- }
-
- @Composable
- override fun textColor(selected: Boolean): State<Color> {
+ internal fun textColor(selected: Boolean): State<Color> {
return animateColorAsState(
targetValue = if (selected) selectedTextColor else unselectedTextColor,
animationSpec = tween(ItemAnimationDurationMillis)
)
}
- override val indicatorColor: Color
+ /** Represents the color of the indicator used for selected items. */
+ internal val indicatorColor: Color
@Composable
get() = selectedIndicatorColor
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is NavigationRailItemColors) return false
+
+ if (selectedIconColor != other.selectedIconColor) return false
+ if (unselectedIconColor != other.unselectedIconColor) return false
+ if (selectedTextColor != other.selectedTextColor) return false
+ if (unselectedTextColor != other.unselectedTextColor) return false
+ if (selectedIndicatorColor != other.selectedIndicatorColor) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = selectedIconColor.hashCode()
+ result = 31 * result + unselectedIconColor.hashCode()
+ result = 31 * result + selectedTextColor.hashCode()
+ result = 31 * result + unselectedTextColor.hashCode()
+ result = 31 * result + selectedIndicatorColor.hashCode()
+
+ return result
+ }
}
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
index 66c86c1..e4c464f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
@@ -170,7 +170,7 @@
} else {
modifier
}
- .background(colors.containerColor(enabled).value, shape)
+ .background(colors.containerColor().value, shape)
.defaultMinSize(
minWidth = TextFieldDefaults.MinWidth,
minHeight = TextFieldDefaults.MinHeight
@@ -319,7 +319,7 @@
} else {
modifier
}
- .background(colors.containerColor(enabled).value, shape)
+ .background(colors.containerColor().value, shape)
.defaultMinSize(
minWidth = TextFieldDefaults.MinWidth,
minHeight = TextFieldDefaults.MinHeight
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
index 5e1c05d..38636c8 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
@@ -32,7 +32,6 @@
import androidx.compose.material3.tokens.RadioButtonTokens
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -128,25 +127,6 @@
}
/**
- * Represents the color used by a [RadioButton] in different states.
- *
- * See [RadioButtonDefaults.colors] for the default implementation that follows Material
- * specifications.
- */
-@Stable
-interface RadioButtonColors {
- /**
- * Represents the main color used to draw the outer and inner circles, depending on whether
- * the [RadioButton] is [enabled] / [selected].
- *
- * @param enabled whether the [RadioButton] is enabled
- * @param selected whether the [RadioButton] is selected
- */
- @Composable
- fun radioColor(enabled: Boolean, selected: Boolean): State<Color>
-}
-
-/**
* Defaults used in [RadioButton].
*/
object RadioButtonDefaults {
@@ -171,35 +151,36 @@
disabledUnselectedColor: Color = RadioButtonTokens.DisabledUnselectedIconColor
.toColor()
.copy(alpha = RadioButtonTokens.DisabledUnselectedIconOpacity)
- ): RadioButtonColors {
- return remember(
- selectedColor,
- unselectedColor,
- disabledSelectedColor,
- disabledUnselectedColor
- ) {
- DefaultRadioButtonColors(
- selectedColor,
- unselectedColor,
- disabledSelectedColor,
- disabledUnselectedColor
- )
- }
- }
+ ): RadioButtonColors = RadioButtonColors(
+ selectedColor,
+ unselectedColor,
+ disabledSelectedColor,
+ disabledUnselectedColor
+ )
}
/**
- * Default [RadioButtonColors] implementation.
+ * Represents the color used by a [RadioButton] in different states.
+ *
+ * See [RadioButtonDefaults.colors] for the default implementation that follows Material
+ * specifications.
*/
@Immutable
-private class DefaultRadioButtonColors(
+class RadioButtonColors internal constructor(
private val selectedColor: Color,
private val unselectedColor: Color,
private val disabledSelectedColor: Color,
private val disabledUnselectedColor: Color
-) : RadioButtonColors {
+) {
+ /**
+ * Represents the main color used to draw the outer and inner circles, depending on whether
+ * the [RadioButton] is [enabled] / [selected].
+ *
+ * @param enabled whether the [RadioButton] is enabled
+ * @param selected whether the [RadioButton] is selected
+ */
@Composable
- override fun radioColor(enabled: Boolean, selected: Boolean): State<Color> {
+ internal fun radioColor(enabled: Boolean, selected: Boolean): State<Color> {
val target = when {
enabled && selected -> selectedColor
enabled && !selected -> unselectedColor
@@ -218,9 +199,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultRadioButtonColors
+ if (other == null || other !is RadioButtonColors) return false
if (selectedColor != other.selectedColor) return false
if (unselectedColor != other.unselectedColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
index 1be3607..0a1984b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
@@ -55,7 +55,6 @@
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
@@ -456,7 +455,7 @@
disabledInactiveTickColor: Color = SliderTokens.TickMarksDisabledContainerColor.toColor()
.copy(alpha = SliderTokens.TickMarksDisabledContainerOpacity)
- ): SliderColors = DefaultSliderColors(
+ ): SliderColors = SliderColors(
thumbColor = thumbColor,
activeTrackColor = activeTrackColor,
activeTickColor = activeTickColor,
@@ -470,50 +469,6 @@
)
}
-/**
- * Represents the colors used by a [Slider] and its parts in different states
- *
- * See [SliderDefaults.colors] for the default implementation that follows Material
- * specifications.
- */
-@Stable
-interface SliderColors {
-
- /**
- * Represents the color used for the slider's thumb, depending on [enabled].
- *
- * @param enabled whether the [Slider] is enabled or not
- */
- @Composable
- fun thumbColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the color used for the slider's track, depending on [enabled] and [active].
- *
- * Active part is filled with progress, so if sliders progress is 30% out of 100%, left (or
- * right in RTL) 30% of the track will be active, while the rest is inactive.
- *
- * @param enabled whether the [Slider] is enabled or not
- * @param active whether the part of the track is active of not
- */
- @Composable
- fun trackColor(enabled: Boolean, active: Boolean): State<Color>
-
- /**
- * Represents the color used for the slider's tick which is the dot separating steps, if
- * they are set on the slider, depending on [enabled] and [active].
- *
- * Active tick is the tick that is in the part of the track filled with progress, so if
- * sliders progress is 30% out of 100%, left (or right in RTL) 30% of the track and the ticks
- * in this 30% will be active, the rest is not active.
- *
- * @param enabled whether the [Slider] is enabled or not
- * @param active whether the part of the track this tick is in is active of not
- */
- @Composable
- fun tickColor(enabled: Boolean, active: Boolean): State<Color>
-}
-
@Composable
internal fun SliderImpl(
modifier: Modifier,
@@ -675,7 +630,8 @@
Box(
Modifier
.padding(start = offset)
- .align(Alignment.CenterStart)) {
+ .align(Alignment.CenterStart)
+ ) {
val interactions = remember { mutableStateListOf<Interaction>() }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
@@ -1047,7 +1003,7 @@
}
@Immutable
-private class DefaultSliderColors(
+class SliderColors internal constructor(
private val thumbColor: Color,
private val activeTrackColor: Color,
private val activeTickColor: Color,
@@ -1058,15 +1014,15 @@
private val disabledActiveTickColor: Color,
private val disabledInactiveTrackColor: Color,
private val disabledInactiveTickColor: Color
-) : SliderColors {
+) {
@Composable
- override fun thumbColor(enabled: Boolean): State<Color> {
+ internal fun thumbColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) thumbColor else disabledThumbColor)
}
@Composable
- override fun trackColor(enabled: Boolean, active: Boolean): State<Color> {
+ internal fun trackColor(enabled: Boolean, active: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (active) activeTrackColor else inactiveTrackColor
@@ -1077,7 +1033,7 @@
}
@Composable
- override fun tickColor(enabled: Boolean, active: Boolean): State<Color> {
+ internal fun tickColor(enabled: Boolean, active: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (active) activeTickColor else inactiveTickColor
@@ -1089,9 +1045,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultSliderColors
+ if (other == null || other !is SliderColors) return false
if (thumbColor != other.thumbColor) return false
if (activeTrackColor != other.activeTrackColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
index 4e4b645..1fd5978 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
@@ -40,7 +40,6 @@
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@@ -168,52 +167,6 @@
}
}
-/**
- * Represents the colors used by a [Switch] in different states
- *
- * See [SwitchDefaults.colors] for the default implementation that follows Material
- * specifications.
- */
-@Stable
-interface SwitchColors {
-
- /**
- * Represents the color used for the switch's thumb, depending on [enabled] and [checked].
- *
- * @param enabled whether the [Switch] is enabled or not
- * @param checked whether the [Switch] is checked or not
- */
- @Composable
- fun thumbColor(enabled: Boolean, checked: Boolean): State<Color>
-
- /**
- * Represents the color used for the switch's track, depending on [enabled] and [checked].
- *
- * @param enabled whether the [Switch] is enabled or not
- * @param checked whether the [Switch] is checked or not
- */
- @Composable
- fun trackColor(enabled: Boolean, checked: Boolean): State<Color>
-
- /**
- * Represents the color used for the switch's border, depending on [enabled] and [checked].
- *
- * @param enabled whether the [Switch] is enabled or not
- * @param checked whether the [Switch] is checked or not
- */
- @Composable
- fun borderColor(enabled: Boolean, checked: Boolean): State<Color>
-
- /**
- * Represents the content color passed to the icon if used
- *
- * @param enabled whether the [Switch] is enabled or not
- * @param checked whether the [Switch] is checked or not
- */
- @Composable
- fun iconColor(enabled: Boolean, checked: Boolean): State<Color>
-}
-
@Composable
@Suppress("ComposableLambdaParameterNaming", "ComposableLambdaParameterPosition")
private fun BoxScope.SwitchImpl(
@@ -356,7 +309,7 @@
disabledUncheckedIconColor: Color = SwitchTokens.DisabledUnselectedIconColor.toColor()
.copy(alpha = SwitchTokens.DisabledUnselectedIconOpacity)
.compositeOver(MaterialTheme.colorScheme.surface),
- ): SwitchColors = DefaultSwitchColors(
+ ): SwitchColors = SwitchColors(
checkedThumbColor = checkedThumbColor,
checkedTrackColor = checkedTrackColor,
checkedBorderColor = checkedBorderColor,
@@ -382,10 +335,13 @@
}
/**
- * Default [SwitchColors] implementation.
+ * Represents the colors used by a [Switch] in different states
+ *
+ * See [SwitchDefaults.colors] for the default implementation that follows Material
+ * specifications.
*/
@Immutable
-private class DefaultSwitchColors(
+class SwitchColors internal constructor(
private val checkedThumbColor: Color,
private val checkedTrackColor: Color,
private val checkedBorderColor: Color,
@@ -402,9 +358,15 @@
private val disabledUncheckedTrackColor: Color,
private val disabledUncheckedBorderColor: Color,
private val disabledUncheckedIconColor: Color
-) : SwitchColors {
+) {
+ /**
+ * Represents the color used for the switch's thumb, depending on [enabled] and [checked].
+ *
+ * @param enabled whether the [Switch] is enabled or not
+ * @param checked whether the [Switch] is checked or not
+ */
@Composable
- override fun thumbColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun thumbColor(enabled: Boolean, checked: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (checked) checkedThumbColor else uncheckedThumbColor
@@ -414,8 +376,14 @@
)
}
+ /**
+ * Represents the color used for the switch's track, depending on [enabled] and [checked].
+ *
+ * @param enabled whether the [Switch] is enabled or not
+ * @param checked whether the [Switch] is checked or not
+ */
@Composable
- override fun trackColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun trackColor(enabled: Boolean, checked: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (checked) checkedTrackColor else uncheckedTrackColor
@@ -425,8 +393,14 @@
)
}
+ /**
+ * Represents the color used for the switch's border, depending on [enabled] and [checked].
+ *
+ * @param enabled whether the [Switch] is enabled or not
+ * @param checked whether the [Switch] is checked or not
+ */
@Composable
- override fun borderColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun borderColor(enabled: Boolean, checked: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (checked) checkedBorderColor else uncheckedBorderColor
@@ -436,8 +410,14 @@
)
}
+ /**
+ * Represents the content color passed to the icon if used
+ *
+ * @param enabled whether the [Switch] is enabled or not
+ * @param checked whether the [Switch] is checked or not
+ */
@Composable
- override fun iconColor(enabled: Boolean, checked: Boolean): State<Color> {
+ internal fun iconColor(enabled: Boolean, checked: Boolean): State<Color> {
return rememberUpdatedState(
if (enabled) {
if (checked) checkedIconColor else uncheckedIconColor
@@ -449,9 +429,7 @@
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultSwitchColors
+ if (other == null || other !is SwitchColors) return false
if (checkedThumbColor != other.checkedThumbColor) return false
if (checkedTrackColor != other.checkedTrackColor) return false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
index 63fb471..2c17d6c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
@@ -187,7 +187,7 @@
BasicTextField(
value = value,
modifier = modifier
- .background(colors.containerColor(enabled).value, shape)
+ .background(colors.containerColor().value, shape)
.indicatorLine(enabled, isError, interactionSource, colors)
.defaultMinSize(
minWidth = TextFieldDefaults.MinWidth,
@@ -322,7 +322,7 @@
BasicTextField(
value = value,
modifier = modifier
- .background(colors.containerColor(enabled).value, shape)
+ .background(colors.containerColor().value, shape)
.indicatorLine(enabled, isError, interactionSource, colors)
.defaultMinSize(
minWidth = TextFieldDefaults.MinWidth,
@@ -385,7 +385,9 @@
content = {
if (leading != null) {
Box(
- modifier = Modifier.layoutId(LeadingId).then(IconDefaultSizeModifier),
+ modifier = Modifier
+ .layoutId(LeadingId)
+ .then(IconDefaultSizeModifier),
contentAlignment = Alignment.Center
) {
leading()
@@ -393,7 +395,9 @@
}
if (trailing != null) {
Box(
- modifier = Modifier.layoutId(TrailingId).then(IconDefaultSizeModifier),
+ modifier = Modifier
+ .layoutId(TrailingId)
+ .then(IconDefaultSizeModifier),
contentAlignment = Alignment.Center
) {
trailing()
@@ -417,13 +421,21 @@
}
)
if (placeholder != null) {
- placeholder(Modifier.layoutId(PlaceholderId).then(padding))
+ placeholder(
+ Modifier
+ .layoutId(PlaceholderId)
+ .then(padding))
}
if (label != null) {
- Box(Modifier.layoutId(LabelId).then(padding)) { label() }
+ Box(
+ Modifier
+ .layoutId(LabelId)
+ .then(padding)) { label() }
}
Box(
- modifier = Modifier.layoutId(TextFieldId).then(padding),
+ modifier = Modifier
+ .layoutId(TextFieldId)
+ .then(padding),
propagateMinConstraints = true,
) {
textField()
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
index 4461392..fcbd9af 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
@@ -35,7 +35,6 @@
import androidx.compose.material3.tokens.OutlinedTextFieldTokens
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
@@ -51,116 +50,6 @@
import androidx.compose.ui.unit.dp
/**
- * Represents the colors of the input text, container, and content (including label, placeholder,
- * leading and trailing icons) used in a text field in different states.
- *
- * See [TextFieldDefaults.textFieldColors] for the default colors used in [TextField].
- * See [TextFieldDefaults.outlinedTextFieldColors] for the default colors used in
- * [OutlinedTextField].
- */
-@ExperimentalMaterial3Api
-@Stable
-interface TextFieldColors {
- /**
- * Represents the color used for the input text of this text field.
- *
- * @param enabled whether the text field is enabled
- */
- @Composable
- fun textColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the container color for this text field.
- *
- * @param enabled whether the text field is enabled
- */
- @Composable
- fun containerColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the color used for the placeholder of this text field.
- *
- * @param enabled whether the text field is enabled
- */
- @Composable
- fun placeholderColor(enabled: Boolean): State<Color>
-
- /**
- * Represents the color used for the label of this text field.
- *
- * @param enabled whether the text field is enabled
- * @param isError whether the text field's current value is in error
- * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
- * the text field is in focus or not
- */
- @Composable
- fun labelColor(
- enabled: Boolean,
- isError: Boolean,
- interactionSource: InteractionSource
- ): State<Color>
-
- /**
- * Represents the color used for the leading icon of this text field.
- *
- * @param enabled whether the text field is enabled
- * @param isError whether the text field's current value is in error
- * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
- * the text field is in focus or not
- */
- @Composable
- fun leadingIconColor(
- enabled: Boolean,
- isError: Boolean,
- interactionSource: InteractionSource
- ): State<Color>
-
- /**
- * Represents the color used for the trailing icon of this text field.
- *
- * @param enabled whether the text field is enabled
- * @param isError whether the text field's current value is in error
- * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
- * the text field is in focus or not
- */
- @Composable
- fun trailingIconColor(
- enabled: Boolean,
- isError: Boolean,
- interactionSource: InteractionSource
- ): State<Color>
-
- /**
- * Represents the color used for the border indicator of this text field.
- *
- * @param enabled whether the text field is enabled
- * @param isError whether the text field's current value is in error
- * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
- * the text field is in focus or not
- */
- @Composable
- fun indicatorColor(
- enabled: Boolean,
- isError: Boolean,
- interactionSource: InteractionSource
- ): State<Color>
-
- /**
- * Represents the color used for the cursor of this text field.
- *
- * @param isError whether the text field's current value is in error
- */
- @Composable
- fun cursorColor(isError: Boolean): State<Color>
-
- /**
- * Represents the colors used for text selection in this text field.
- */
- val selectionColors: TextSelectionColors
- @Composable get
-}
-
-/**
* Contains the default values used by [TextField] and [OutlinedTextField].
*/
@ExperimentalMaterial3Api
@@ -382,9 +271,10 @@
disabledPlaceholderColor: Color = FilledTextFieldTokens.DisabledInputColor.toColor()
.copy(alpha = FilledTextFieldTokens.DisabledInputOpacity)
): TextFieldColors =
- DefaultTextFieldColors(
+ TextFieldColors(
textColor = textColor,
disabledTextColor = disabledTextColor,
+ containerColor = containerColor,
cursorColor = cursorColor,
errorCursorColor = errorCursorColor,
textSelectionColors = selectionColors,
@@ -400,7 +290,6 @@
unfocusedTrailingIconColor = unfocusedTrailingIconColor,
disabledTrailingIconColor = disabledTrailingIconColor,
errorTrailingIconColor = errorTrailingIconColor,
- containerColor = containerColor,
focusedLabelColor = focusedLabelColor,
unfocusedLabelColor = unfocusedLabelColor,
disabledLabelColor = disabledLabelColor,
@@ -473,7 +362,7 @@
disabledPlaceholderColor: Color = OutlinedTextFieldTokens.DisabledInputColor.toColor()
.copy(alpha = OutlinedTextFieldTokens.DisabledInputOpacity)
): TextFieldColors =
- DefaultTextFieldColors(
+ TextFieldColors(
textColor = textColor,
disabledTextColor = disabledTextColor,
cursorColor = cursorColor,
@@ -688,11 +577,20 @@
}
}
+/**
+ * Represents the colors of the input text, container, and content (including label, placeholder,
+ * leading and trailing icons) used in a text field in different states.
+ *
+ * See [TextFieldDefaults.textFieldColors] for the default colors used in [TextField].
+ * See [TextFieldDefaults.outlinedTextFieldColors] for the default colors used in
+ * [OutlinedTextField].
+ */
@OptIn(ExperimentalMaterial3Api::class)
@Immutable
-private class DefaultTextFieldColors(
+class TextFieldColors internal constructor(
private val textColor: Color,
private val disabledTextColor: Color,
+ private val containerColor: Color,
private val cursorColor: Color,
private val errorCursorColor: Color,
private val textSelectionColors: TextSelectionColors,
@@ -708,17 +606,23 @@
private val unfocusedTrailingIconColor: Color,
private val disabledTrailingIconColor: Color,
private val errorTrailingIconColor: Color,
- private val containerColor: Color,
private val focusedLabelColor: Color,
private val unfocusedLabelColor: Color,
private val disabledLabelColor: Color,
private val errorLabelColor: Color,
private val placeholderColor: Color,
private val disabledPlaceholderColor: Color
-) : TextFieldColors {
-
+ ) {
+ /**
+ * Represents the color used for the leading icon of this text field.
+ *
+ * @param enabled whether the text field is enabled
+ * @param isError whether the text field's current value is in error
+ * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+ * the text field is in focus or not
+ */
@Composable
- override fun leadingIconColor(
+ internal fun leadingIconColor(
enabled: Boolean,
isError: Boolean,
interactionSource: InteractionSource
@@ -735,8 +639,16 @@
)
}
+ /**
+ * Represents the color used for the trailing icon of this text field.
+ *
+ * @param enabled whether the text field is enabled
+ * @param isError whether the text field's current value is in error
+ * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+ * the text field is in focus or not
+ */
@Composable
- override fun trailingIconColor(
+ internal fun trailingIconColor(
enabled: Boolean,
isError: Boolean,
interactionSource: InteractionSource
@@ -753,8 +665,16 @@
)
}
+ /**
+ * Represents the color used for the border indicator of this text field.
+ *
+ * @param enabled whether the text field is enabled
+ * @param isError whether the text field's current value is in error
+ * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+ * the text field is in focus or not
+ */
@Composable
- override fun indicatorColor(
+ internal fun indicatorColor(
enabled: Boolean,
isError: Boolean,
interactionSource: InteractionSource
@@ -774,18 +694,34 @@
}
}
+ /**
+ * Represents the container color for this text field.
+ */
@Composable
- override fun containerColor(enabled: Boolean): State<Color> {
+ internal fun containerColor(): State<Color> {
return rememberUpdatedState(containerColor)
}
+ /**
+ * Represents the color used for the placeholder of this text field.
+ *
+ * @param enabled whether the text field is enabled
+ */
@Composable
- override fun placeholderColor(enabled: Boolean): State<Color> {
+ internal fun placeholderColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) placeholderColor else disabledPlaceholderColor)
}
+ /**
+ * Represents the color used for the label of this text field.
+ *
+ * @param enabled whether the text field is enabled
+ * @param isError whether the text field's current value is in error
+ * @param interactionSource the [InteractionSource] of this text field. Helps to determine if
+ * the text field is in focus or not
+ */
@Composable
- override fun labelColor(
+ internal fun labelColor(
enabled: Boolean,
isError: Boolean,
interactionSource: InteractionSource
@@ -802,23 +738,29 @@
}
@Composable
- override fun textColor(enabled: Boolean): State<Color> {
+ internal fun textColor(enabled: Boolean): State<Color> {
return rememberUpdatedState(if (enabled) textColor else disabledTextColor)
}
+ /**
+ * Represents the color used for the cursor of this text field.
+ *
+ * @param isError whether the text field's current value is in error
+ */
@Composable
- override fun cursorColor(isError: Boolean): State<Color> {
+ internal fun cursorColor(isError: Boolean): State<Color> {
return rememberUpdatedState(if (isError) errorCursorColor else cursorColor)
}
- override val selectionColors: TextSelectionColors
+ /**
+ * Represents the colors used for text selection in this text field.
+ */
+ internal val selectionColors: TextSelectionColors
@Composable get() = textSelectionColors
override fun equals(other: Any?): Boolean {
if (this === other) return true
- if (other == null || this::class != other::class) return false
-
- other as DefaultTextFieldColors
+ if (other == null || other !is TextFieldColors) return false
if (textColor != other.textColor) return false
if (disabledTextColor != other.disabledTextColor) return false
diff --git a/compose/ui/ui-text/api/current.ignore b/compose/ui/ui-text/api/current.ignore
index 8fe6362..85b4b37 100644
--- a/compose/ui/ui-text/api/current.ignore
+++ b/compose/ui/ui-text/api/current.ignore
@@ -71,3 +71,21 @@
Attempted to remove default value from parameter shadow in androidx.compose.ui.text.Paragraph.paint
DefaultValueChange: androidx.compose.ui.text.Paragraph#paint(androidx.compose.ui.graphics.Canvas, long, androidx.compose.ui.graphics.Shadow, androidx.compose.ui.text.style.TextDecoration) parameter #3:
Attempted to remove default value from parameter textDecoration in androidx.compose.ui.text.Paragraph.paint
+
+
+RemovedMethod: androidx.compose.ui.text.ParagraphStyle#equals(Object):
+ Removed method androidx.compose.ui.text.ParagraphStyle.equals(Object)
+RemovedMethod: androidx.compose.ui.text.Placeholder#equals(Object):
+ Removed method androidx.compose.ui.text.Placeholder.equals(Object)
+RemovedMethod: androidx.compose.ui.text.SpanStyle#equals(Object):
+ Removed method androidx.compose.ui.text.SpanStyle.equals(Object)
+RemovedMethod: androidx.compose.ui.text.TextLayoutInput#equals(Object):
+ Removed method androidx.compose.ui.text.TextLayoutInput.equals(Object)
+RemovedMethod: androidx.compose.ui.text.TextLayoutResult#equals(Object):
+ Removed method androidx.compose.ui.text.TextLayoutResult.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextDecoration#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextDecoration.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextGeometricTransform#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextGeometricTransform.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextIndent#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextIndent.equals(Object)
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index 4903af3..d438842 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -226,7 +226,6 @@
ctor public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
- method public operator boolean equals(Object? other);
method public long getLineHeight();
method public androidx.compose.ui.text.style.LineHeightStyle? getLineHeightStyle();
method public androidx.compose.ui.text.PlatformParagraphStyle? getPlatformStyle();
@@ -250,7 +249,6 @@
@androidx.compose.runtime.Immutable public final class Placeholder {
ctor public Placeholder(long width, long height, int placeholderVerticalAlign);
method public androidx.compose.ui.text.Placeholder copy(optional long width, optional long height, optional int placeholderVerticalAlign);
- method public operator boolean equals(Object? other);
method public long getHeight();
method public int getPlaceholderVerticalAlign();
method public long getWidth();
@@ -321,7 +319,6 @@
ctor public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
- method public operator boolean equals(Object? other);
method public long getBackground();
method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
method public long getColor();
@@ -378,7 +375,6 @@
ctor @Deprecated public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, long constraints);
ctor public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, long constraints);
method @Deprecated public androidx.compose.ui.text.TextLayoutInput copy(optional androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean softWrap, optional int overflow, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, optional long constraints);
- method public operator boolean equals(Object? other);
method public long getConstraints();
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.text.font.FontFamily.Resolver getFontFamilyResolver();
@@ -406,7 +402,6 @@
public final class TextLayoutResult {
ctor public TextLayoutResult(androidx.compose.ui.text.TextLayoutInput layoutInput, androidx.compose.ui.text.MultiParagraph multiParagraph, long size);
method public androidx.compose.ui.text.TextLayoutResult copy(optional androidx.compose.ui.text.TextLayoutInput layoutInput, optional long size);
- method public operator boolean equals(Object? other);
method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
@@ -1354,7 +1349,6 @@
@androidx.compose.runtime.Immutable public final class TextDecoration {
method public operator boolean contains(androidx.compose.ui.text.style.TextDecoration other);
- method public operator boolean equals(Object? other);
method public int getMask();
method public operator androidx.compose.ui.text.style.TextDecoration plus(androidx.compose.ui.text.style.TextDecoration decoration);
property public final int mask;
@@ -1394,7 +1388,6 @@
@androidx.compose.runtime.Immutable public final class TextGeometricTransform {
ctor public TextGeometricTransform(optional float scaleX, optional float skewX);
method public androidx.compose.ui.text.style.TextGeometricTransform copy(optional float scaleX, optional float skewX);
- method public operator boolean equals(Object? other);
method public float getScaleX();
method public float getSkewX();
property public final float scaleX;
@@ -1412,7 +1405,6 @@
@androidx.compose.runtime.Immutable public final class TextIndent {
ctor public TextIndent(optional long firstLine, optional long restLine);
method public androidx.compose.ui.text.style.TextIndent copy(optional long firstLine, optional long restLine);
- method public operator boolean equals(Object? other);
method public long getFirstLine();
method public long getRestLine();
property public final long firstLine;
diff --git a/compose/ui/ui-text/api/public_plus_experimental_current.txt b/compose/ui/ui-text/api/public_plus_experimental_current.txt
index c9450fc..97d495c 100644
--- a/compose/ui/ui-text/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-text/api/public_plus_experimental_current.txt
@@ -241,7 +241,6 @@
ctor public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
- method public operator boolean equals(Object? other);
method public long getLineHeight();
method public androidx.compose.ui.text.style.LineHeightStyle? getLineHeightStyle();
method public androidx.compose.ui.text.PlatformParagraphStyle? getPlatformStyle();
@@ -265,7 +264,6 @@
@androidx.compose.runtime.Immutable public final class Placeholder {
ctor public Placeholder(long width, long height, int placeholderVerticalAlign);
method public androidx.compose.ui.text.Placeholder copy(optional long width, optional long height, optional int placeholderVerticalAlign);
- method public operator boolean equals(Object? other);
method public long getHeight();
method public int getPlaceholderVerticalAlign();
method public long getWidth();
@@ -338,7 +336,6 @@
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.SpanStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
- method public operator boolean equals(Object? other);
method @androidx.compose.ui.text.ExperimentalTextApi public float getAlpha();
method public long getBackground();
method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
@@ -399,7 +396,6 @@
ctor @Deprecated public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, long constraints);
ctor public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, long constraints);
method @Deprecated public androidx.compose.ui.text.TextLayoutInput copy(optional androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean softWrap, optional int overflow, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, optional long constraints);
- method public operator boolean equals(Object? other);
method public long getConstraints();
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.text.font.FontFamily.Resolver getFontFamilyResolver();
@@ -427,7 +423,6 @@
public final class TextLayoutResult {
ctor public TextLayoutResult(androidx.compose.ui.text.TextLayoutInput layoutInput, androidx.compose.ui.text.MultiParagraph multiParagraph, long size);
method public androidx.compose.ui.text.TextLayoutResult copy(optional androidx.compose.ui.text.TextLayoutInput layoutInput, optional long size);
- method public operator boolean equals(Object? other);
method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
@@ -1451,7 +1446,6 @@
@androidx.compose.runtime.Immutable public final class TextDecoration {
method public operator boolean contains(androidx.compose.ui.text.style.TextDecoration other);
- method public operator boolean equals(Object? other);
method public int getMask();
method public operator androidx.compose.ui.text.style.TextDecoration plus(androidx.compose.ui.text.style.TextDecoration decoration);
property public final int mask;
@@ -1491,7 +1485,6 @@
@androidx.compose.runtime.Immutable public final class TextGeometricTransform {
ctor public TextGeometricTransform(optional float scaleX, optional float skewX);
method public androidx.compose.ui.text.style.TextGeometricTransform copy(optional float scaleX, optional float skewX);
- method public operator boolean equals(Object? other);
method public float getScaleX();
method public float getSkewX();
property public final float scaleX;
@@ -1509,7 +1502,6 @@
@androidx.compose.runtime.Immutable public final class TextIndent {
ctor public TextIndent(optional long firstLine, optional long restLine);
method public androidx.compose.ui.text.style.TextIndent copy(optional long firstLine, optional long restLine);
- method public operator boolean equals(Object? other);
method public long getFirstLine();
method public long getRestLine();
property public final long firstLine;
diff --git a/compose/ui/ui-text/api/restricted_current.ignore b/compose/ui/ui-text/api/restricted_current.ignore
index 8fe6362..85b4b37 100644
--- a/compose/ui/ui-text/api/restricted_current.ignore
+++ b/compose/ui/ui-text/api/restricted_current.ignore
@@ -71,3 +71,21 @@
Attempted to remove default value from parameter shadow in androidx.compose.ui.text.Paragraph.paint
DefaultValueChange: androidx.compose.ui.text.Paragraph#paint(androidx.compose.ui.graphics.Canvas, long, androidx.compose.ui.graphics.Shadow, androidx.compose.ui.text.style.TextDecoration) parameter #3:
Attempted to remove default value from parameter textDecoration in androidx.compose.ui.text.Paragraph.paint
+
+
+RemovedMethod: androidx.compose.ui.text.ParagraphStyle#equals(Object):
+ Removed method androidx.compose.ui.text.ParagraphStyle.equals(Object)
+RemovedMethod: androidx.compose.ui.text.Placeholder#equals(Object):
+ Removed method androidx.compose.ui.text.Placeholder.equals(Object)
+RemovedMethod: androidx.compose.ui.text.SpanStyle#equals(Object):
+ Removed method androidx.compose.ui.text.SpanStyle.equals(Object)
+RemovedMethod: androidx.compose.ui.text.TextLayoutInput#equals(Object):
+ Removed method androidx.compose.ui.text.TextLayoutInput.equals(Object)
+RemovedMethod: androidx.compose.ui.text.TextLayoutResult#equals(Object):
+ Removed method androidx.compose.ui.text.TextLayoutResult.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextDecoration#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextDecoration.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextGeometricTransform#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextGeometricTransform.equals(Object)
+RemovedMethod: androidx.compose.ui.text.style.TextIndent#equals(Object):
+ Removed method androidx.compose.ui.text.style.TextIndent.equals(Object)
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index 4903af3..d438842 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -226,7 +226,6 @@
ctor public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
- method public operator boolean equals(Object? other);
method public long getLineHeight();
method public androidx.compose.ui.text.style.LineHeightStyle? getLineHeightStyle();
method public androidx.compose.ui.text.PlatformParagraphStyle? getPlatformStyle();
@@ -250,7 +249,6 @@
@androidx.compose.runtime.Immutable public final class Placeholder {
ctor public Placeholder(long width, long height, int placeholderVerticalAlign);
method public androidx.compose.ui.text.Placeholder copy(optional long width, optional long height, optional int placeholderVerticalAlign);
- method public operator boolean equals(Object? other);
method public long getHeight();
method public int getPlaceholderVerticalAlign();
method public long getWidth();
@@ -321,7 +319,6 @@
ctor public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
- method public operator boolean equals(Object? other);
method public long getBackground();
method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
method public long getColor();
@@ -378,7 +375,6 @@
ctor @Deprecated public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, long constraints);
ctor public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, long constraints);
method @Deprecated public androidx.compose.ui.text.TextLayoutInput copy(optional androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean softWrap, optional int overflow, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, optional long constraints);
- method public operator boolean equals(Object? other);
method public long getConstraints();
method public androidx.compose.ui.unit.Density getDensity();
method public androidx.compose.ui.text.font.FontFamily.Resolver getFontFamilyResolver();
@@ -406,7 +402,6 @@
public final class TextLayoutResult {
ctor public TextLayoutResult(androidx.compose.ui.text.TextLayoutInput layoutInput, androidx.compose.ui.text.MultiParagraph multiParagraph, long size);
method public androidx.compose.ui.text.TextLayoutResult copy(optional androidx.compose.ui.text.TextLayoutInput layoutInput, optional long size);
- method public operator boolean equals(Object? other);
method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
@@ -1354,7 +1349,6 @@
@androidx.compose.runtime.Immutable public final class TextDecoration {
method public operator boolean contains(androidx.compose.ui.text.style.TextDecoration other);
- method public operator boolean equals(Object? other);
method public int getMask();
method public operator androidx.compose.ui.text.style.TextDecoration plus(androidx.compose.ui.text.style.TextDecoration decoration);
property public final int mask;
@@ -1394,7 +1388,6 @@
@androidx.compose.runtime.Immutable public final class TextGeometricTransform {
ctor public TextGeometricTransform(optional float scaleX, optional float skewX);
method public androidx.compose.ui.text.style.TextGeometricTransform copy(optional float scaleX, optional float skewX);
- method public operator boolean equals(Object? other);
method public float getScaleX();
method public float getSkewX();
property public final float scaleX;
@@ -1412,7 +1405,6 @@
@androidx.compose.runtime.Immutable public final class TextIndent {
ctor public TextIndent(optional long firstLine, optional long restLine);
method public androidx.compose.ui.text.style.TextIndent copy(optional long firstLine, optional long restLine);
- method public operator boolean equals(Object? other);
method public long getFirstLine();
method public long getRestLine();
property public final long firstLine;
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt
index 3440d6c..4cba34a 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/ParagraphStyle.kt
@@ -179,7 +179,7 @@
)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ParagraphStyle) return false
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt
index a65fc3f..7e7f2eb 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/Placeholder.kt
@@ -56,7 +56,7 @@
)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Placeholder) return false
if (width != other.width) return false
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
index 758cdfa..9bee135 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/SpanStyle.kt
@@ -483,7 +483,7 @@
)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is SpanStyle) return false
return hasSameLayoutAffectingAttributes(other) &&
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt
index 2fb35be..5f32551 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextLayoutResult.kt
@@ -209,7 +209,7 @@
)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TextLayoutInput) return false
@@ -548,7 +548,7 @@
)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TextLayoutResult) return false
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt
index fe595ce..3244f63 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextDecoration.kt
@@ -97,7 +97,7 @@
return "TextDecoration[${values.fastJoinToString(separator = ", ")}]"
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TextDecoration) return false
if (mask != other.mask) return false
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt
index ea867fe..0763615 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextGeometricTransform.kt
@@ -46,7 +46,7 @@
return TextGeometricTransform(scaleX, skewX)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TextGeometricTransform) return false
if (scaleX != other.scaleX) return false
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt
index aad447e..ae93195 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextIndent.kt
@@ -48,7 +48,7 @@
return TextIndent(firstLine, restLine)
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TextIndent) return false
if (firstLine != other.firstLine) return false
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index f8b91da..59a1dfa 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -32,7 +32,7 @@
implementation(libs.kotlinStdlib)
api("androidx.annotation:annotation:1.1.0")
- implementation("androidx.compose.animation:animation:1.1.1")
+ implementation(project(":compose:animation:animation"))
api("androidx.compose.runtime:runtime:1.1.1")
api(project(":compose:ui:ui"))
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
index a82b7ce..44e1a97 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
@@ -173,7 +173,7 @@
fun animateXAsStateIsSubscribed() {
checkAnimationsAreSubscribed(
"AnimateAsStatePreview",
- listOf("animateValueAsState", "animateValueAsState")
+ listOf("DpAnimation", "IntAnimation")
)
}
@@ -184,7 +184,7 @@
@Test
fun crossFadeIsSubscribed() {
- checkTransitionIsSubscribed("CrossFadePreview", "String")
+ checkTransitionIsSubscribed("CrossFadePreview", "Crossfade")
}
@Test
@@ -208,7 +208,7 @@
checkAnimationsAreSubscribed(
"AllAnimations",
emptyList(),
- listOf("checkBoxAnim", "String")
+ listOf("checkBoxAnim", "Crossfade")
)
UnsupportedComposeAnimation.testOverrideAvailability(true)
}
@@ -241,7 +241,7 @@
assertTrue(clock.trackedAnimatedVisibility.isEmpty())
}
- waitFor("Composable to have animations", 2, TimeUnit.SECONDS) {
+ waitFor("Composable to have animations", 5, TimeUnit.SECONDS) {
// Handle the case where onLayout was called too soon. Calling requestLayout will
// make sure onLayout will be called again.
composeViewAdapter.requestLayout()
diff --git a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/PreviewAnimationClock.kt b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/PreviewAnimationClock.kt
index 5476af2..bb8ed1b 100644
--- a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/PreviewAnimationClock.kt
+++ b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/PreviewAnimationClock.kt
@@ -201,8 +201,7 @@
}
fun trackAnimateXAsState(animatable: Animatable<*, *>) {
- // TODO(b/240919893) Use label from animatable.
- animateXAsStateSubscriber.trackAnimation(animatable, "animateValueAsState")
+ animateXAsStateSubscriber.trackAnimation(animatable, animatable.label)
}
fun trackAnimateContentSize(sizeAnimationModifier: Any) {
diff --git a/core/settings.gradle b/core/settings.gradle
index ffa5f61..634a426 100644
--- a/core/settings.gradle
+++ b/core/settings.gradle
@@ -16,6 +16,7 @@
if (name == ":internal-testutils-fonts") return true
if (name == ":internal-testutils-runtime") return true
if (name == ":internal-testutils-truth") return true
+ if (name.startsWith(":annotation:annotation-experimental")) return true
if (name == ":annotation:annotation-sampled") return true
if (name == ":test:screenshot:screenshot") return true
if (name == ":test:screenshot:screenshot-proto") return true
diff --git a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
index 9c8b9f1..58496d2 100644
--- a/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
+++ b/glance/glance-appwidget/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
@@ -43,7 +43,7 @@
@Composable
override fun TemplateContent() {
val galleryContent = mutableListOf<TemplateImageWithDescription>()
- for (i in 1..8) {
+ for (i in 1..30) {
galleryContent.add(
TemplateImageWithDescription(
ImageProvider(R.drawable.compose),
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
index 9cf2f5b..df1ca96 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GalleryTemplateLayouts.kt
@@ -16,10 +16,18 @@
package androidx.glance.appwidget.template
+import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceModifier
+import androidx.glance.Image
+import androidx.glance.LocalSize
+import androidx.glance.appwidget.cornerRadius
+import androidx.glance.appwidget.lazy.GridCells
+import androidx.glance.appwidget.lazy.LazyVerticalGrid
+import androidx.glance.appwidget.lazy.itemsIndexed
import androidx.glance.background
+import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
import androidx.glance.layout.ContentScale
import androidx.glance.layout.Row
@@ -29,10 +37,17 @@
import androidx.glance.layout.fillMaxWidth
import androidx.glance.layout.height
import androidx.glance.layout.padding
+import androidx.glance.layout.width
+import androidx.glance.template.AspectRatio
import androidx.glance.template.GalleryTemplateData
+import androidx.glance.template.ImageSize
import androidx.glance.template.LocalTemplateColors
import androidx.glance.template.LocalTemplateMode
import androidx.glance.template.TemplateMode
+import kotlin.math.ceil
+import kotlin.math.pow
+import kotlin.math.roundToInt
+import kotlin.math.sqrt
/**
* Composable layout for a gallery template app widget. The template is optimized to show images.
@@ -77,14 +92,64 @@
@Composable
private fun WidgetLayoutVertical(data: GalleryTemplateData) {
- Column(modifier = createTopLevelModifier(data)) {
- HeaderBlockTemplate(data.header)
- Spacer(modifier = GlanceModifier.height(16.dp))
- SingleImageBlockTemplate(data.mainImageBlock, GlanceModifier.fillMaxWidth().defaultWeight())
- Row(modifier = GlanceModifier.fillMaxWidth()) {
- TextBlockTemplate(data.mainTextBlock)
- Spacer(modifier = GlanceModifier.defaultWeight())
- ActionBlockTemplate(data.mainActionBlock)
+ val aspectRatio: Double = when (data.galleryImageBlock.aspectRatio) {
+ AspectRatio.Ratio1x1 -> 1.0
+ AspectRatio.Ratio2x3 -> 2.0 / 3
+ AspectRatio.Ratio16x9 -> 16.0 / 9
+ else -> 1.0
+ }
+ val imageSize: Double = when (data.galleryImageBlock.size) {
+ ImageSize.Small -> 64.0.pow(2.0)
+ ImageSize.Medium -> 96.0.pow(2.0)
+ ImageSize.Large -> 128.0.pow(2.0)
+ else -> 64.0.pow(2.0)
+ }
+ val margin = 16
+ val imageHeight = sqrt(imageSize / aspectRatio)
+ val imageWidth = imageHeight * aspectRatio
+ val galleryWidth = LocalSize.current.width.value
+ val nCols =
+ 1.coerceAtLeast(ceil(((galleryWidth - margin) / (imageWidth + margin))).roundToInt())
+ val gridCells = if (Build.VERSION.SDK_INT >= 31) {
+ GridCells.Adaptive((imageWidth + margin).dp)
+ } else {
+ GridCells.Fixed(nCols)
+ }
+ Column {
+ Row(
+ modifier = createCardModifier(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Column(
+ modifier = GlanceModifier.defaultWeight()
+ ) {
+ HeaderBlockTemplate(data.header)
+ Spacer(modifier = GlanceModifier.height(16.dp).defaultWeight())
+ TextBlockTemplate(data.mainTextBlock)
+ ActionBlockTemplate(data.mainActionBlock)
+ }
+ SingleImageBlockTemplate(
+ data.mainImageBlock
+ )
+ }
+ Row(
+ modifier = createCardModifier(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ LazyVerticalGrid(
+ modifier = GlanceModifier.defaultWeight().fillMaxHeight(),
+ gridCells = gridCells
+ ) {
+ itemsIndexed(data.galleryImageBlock.images) { _, image ->
+ Image(
+ provider = image.image,
+ contentDescription = image.description,
+ modifier = GlanceModifier.padding((margin / 2).dp)
+ .height(imageHeight.dp).width(imageWidth.dp),
+ contentScale = ContentScale.Crop
+ )
+ }
+ }
}
}
}
@@ -95,7 +160,7 @@
isImmersive: Boolean = false
): GlanceModifier {
var modifier = GlanceModifier
- .fillMaxSize().padding(16.dp).background(LocalTemplateColors.current.surface)
+ .fillMaxSize().background(LocalTemplateColors.current.surface)
if (isImmersive && data.mainImageBlock.images.isNotEmpty()) {
val mainImage = data.mainImageBlock.images[0]
modifier = modifier.background(mainImage.image, ContentScale.Crop)
@@ -103,3 +168,7 @@
return modifier
}
+
+@Composable
+private fun createCardModifier() = GlanceModifier.fillMaxWidth().padding(16.dp).cornerRadius(16.dp)
+ .background(LocalTemplateColors.current.primaryContainer)
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
index 2fed787..4a3c354 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/GlanceAppWidgetTemplates.kt
@@ -185,7 +185,6 @@
modifier: GlanceModifier = GlanceModifier
) {
if (imageBlock.images.isNotEmpty()) {
- Spacer(modifier = GlanceModifier.width(16.dp))
val mainImage = imageBlock.images[0]
Image(
provider = mainImage.image,
diff --git a/glance/glance-wear-tiles-preview/api/current.txt b/glance/glance-wear-tiles-preview/api/current.txt
new file mode 100644
index 0000000..5bfa654
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/api/current.txt
@@ -0,0 +1,8 @@
+// Signature format: 4.0
+package androidx.glance.wear.tiles.preview {
+
+ public final class GlanceTileServiceViewAdapterKt {
+ }
+
+}
+
diff --git a/glance/glance-wear-tiles-preview/api/public_plus_experimental_current.txt b/glance/glance-wear-tiles-preview/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..5bfa654
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/api/public_plus_experimental_current.txt
@@ -0,0 +1,8 @@
+// Signature format: 4.0
+package androidx.glance.wear.tiles.preview {
+
+ public final class GlanceTileServiceViewAdapterKt {
+ }
+
+}
+
diff --git a/glance/glance-wear-tiles-preview/api/res-current.txt b/glance/glance-wear-tiles-preview/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/api/res-current.txt
diff --git a/glance/glance-wear-tiles-preview/api/restricted_current.txt b/glance/glance-wear-tiles-preview/api/restricted_current.txt
new file mode 100644
index 0000000..5bfa654
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/api/restricted_current.txt
@@ -0,0 +1,8 @@
+// Signature format: 4.0
+package androidx.glance.wear.tiles.preview {
+
+ public final class GlanceTileServiceViewAdapterKt {
+ }
+
+}
+
diff --git a/glance/glance-wear-tiles-preview/build.gradle b/glance/glance-wear-tiles-preview/build.gradle
new file mode 100644
index 0000000..d1a59d07
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/build.gradle
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.AndroidXComposePlugin
+import androidx.build.LibraryType
+
+plugins {
+ id("AndroidXComposePlugin")
+ id("AndroidXPlugin")
+ id("com.android.library")
+}
+
+// Disable multi-platform; this will only be used on Android.
+AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project, /* isMultiplatformEnabled= */false)
+
+dependencies {
+ api("androidx.wear.tiles:tiles-renderer:1.0.0")
+
+ api(libs.kotlinStdlib)
+ api(libs.kotlinReflect)
+ api(libs.kotlinCoroutinesAndroid)
+
+ implementation("androidx.core:core:1.1.0")
+
+ api(project(":compose:runtime:runtime"))
+ api(project(":glance:glance-wear-tiles"))
+
+ androidTestImplementation(libs.junit)
+ androidTestImplementation(libs.testRunner)
+ androidTestImplementation(libs.testRules)
+}
+
+android {
+ defaultConfig {
+ minSdkVersion 26
+ }
+ namespace "androidx.glance.wear.tiles.preview"
+}
+
+androidx {
+ name = "Android Glance Wear Tiles Preview"
+ type = LibraryType.PUBLISHED_LIBRARY
+ mavenGroup = LibraryGroups.GLANCE
+ inceptionYear = "2022"
+ description = "Glance tooling library. This library provides the API required for the " +
+ "GlanceTileService components and its Glance @Composable to be previewable in the IDE."
+}
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/AndroidManifest.xml b/glance/glance-wear-tiles-preview/src/androidAndroidTest/AndroidManifest.xml
new file mode 100644
index 0000000..a1660e9
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+ <application
+ android:debuggable="true"
+ tools:ignore="HardcodedDebugMode">
+ <activity
+ android:name="androidx.glance.wear.tiles.preview.GlanceTileServiceViewAdapterTest$Companion$TestActivity"
+ android:theme="@style/TestTheme" />
+ </application>
+</manifest>
\ No newline at end of file
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt
new file mode 100644
index 0000000..94ad581
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.wear.tiles.preview
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.unit.dp
+import androidx.glance.action.Action
+import androidx.glance.Button
+import androidx.glance.GlanceModifier
+import androidx.glance.layout.Alignment
+import androidx.glance.layout.Column
+import androidx.glance.layout.Row
+import androidx.glance.layout.fillMaxSize
+import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.height
+import androidx.glance.layout.padding
+import androidx.glance.text.FontWeight
+import androidx.glance.text.Text
+import androidx.glance.text.TextStyle
+
+@Composable
+fun FirstGlancePreview() {
+ Column(
+ modifier = GlanceModifier
+ .fillMaxSize()
+ .padding(16.dp)
+ ) {
+ Text(
+ text = "First Glance widget",
+ modifier = GlanceModifier
+ .fillMaxWidth()
+ .padding(bottom = 8.dp),
+ style = TextStyle(fontWeight = FontWeight.Bold),
+ )
+ Row(
+ modifier = GlanceModifier.fillMaxSize(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Button(
+ text = "Button 1",
+ modifier = GlanceModifier.height(48.dp),
+ onClick = object : Action { }
+ )
+ Button(
+ text = "Button 2",
+ modifier = GlanceModifier.height(48.dp),
+ onClick = object : Action { }
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt
new file mode 100644
index 0000000..3f4b8fd
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.wear.tiles.preview
+
+import androidx.glance.wear.tiles.preview.test.R
+import android.app.Activity
+import android.os.Bundle
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.test.filters.MediumTest
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@MediumTest
+class GlanceTileServiceViewAdapterTest {
+ @Suppress("DEPRECATION")
+ @get:Rule
+ val activityTestRule = androidx.test.rule.ActivityTestRule(TestActivity::class.java)
+
+ private lateinit var glanceTileServiceViewAdapter: GlanceTileServiceViewAdapter
+
+ @Before
+ fun setup() {
+ glanceTileServiceViewAdapter =
+ activityTestRule.activity.findViewById(R.id.glance_tile_service_view_adapter)
+ }
+
+ private fun initAndInflate(
+ className: String,
+ methodName: String,
+ ) {
+ activityTestRule.runOnUiThread {
+ glanceTileServiceViewAdapter.init(className, methodName)
+ glanceTileServiceViewAdapter.requestLayout()
+ }
+ }
+
+ private inline fun <reified T> ViewGroup.getChildOfType(count: Int = 0): T? {
+ var i = 0
+ (0 until childCount).forEach {
+ val child = getChildAt(it)
+ if (child is T) {
+ if (i == count) {
+ return child
+ }
+ i += 1
+ }
+ }
+ return null
+ }
+
+ private fun viewNotFoundMsg(viewTypeName: String, composableName: String) =
+ "Could not find the $viewTypeName View matching $composableName"
+
+ @Test
+ fun testFirstGlancePreview() {
+ initAndInflate(
+ "androidx.glance.wear.tiles.preview.FirstGlancePreviewKt",
+ "FirstGlancePreview")
+
+ activityTestRule.runOnUiThread {
+ val rootComposable = glanceTileServiceViewAdapter.getChildAt(0) as ViewGroup
+ val linearLayoutColumn = rootComposable.getChildOfType<LinearLayout>()
+ Assert.assertNotNull(viewNotFoundMsg("LinearLayout", "Column"), linearLayoutColumn)
+
+ val frameLayout = linearLayoutColumn!!.getChildOfType<FrameLayout>()
+ val textView = frameLayout!!.getChildOfType<TextView>()
+ Assert.assertNotNull(viewNotFoundMsg("TextView", "Text"), textView)
+
+ val linearLayoutRow = linearLayoutColumn.getChildOfType<LinearLayout>()
+ Assert.assertNotNull(viewNotFoundMsg("LinearLayout", "Row"), linearLayoutRow)
+
+ val button1 =
+ linearLayoutRow!!.getChildOfType<FrameLayout>()!!.getChildOfType<TextView>()
+ val button2 =
+ linearLayoutRow.getChildOfType<FrameLayout>(1)!!.getChildOfType<TextView>()
+ Assert.assertNotNull(viewNotFoundMsg("TextView", "Button"), button1)
+ Assert.assertEquals("Button 1", button1!!.text.toString())
+ Assert.assertNotNull(viewNotFoundMsg("TextView", "Button"), button2)
+ Assert.assertEquals("Button 2", button2!!.text.toString())
+ }
+ }
+
+ companion object {
+ class TestActivity : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.glance_tile_service_adapter_test)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget-preview/src/androidMain/AndroidManifest.xml b/glance/glance-wear-tiles-preview/src/androidAndroidTest/res/layout/glance_tile_service_adapter_test.xml
similarity index 66%
rename from glance/glance-appwidget-preview/src/androidMain/AndroidManifest.xml
rename to glance/glance-wear-tiles-preview/src/androidAndroidTest/res/layout/glance_tile_service_adapter_test.xml
index 9a2fb82..9a093d8 100644
--- a/glance/glance-appwidget-preview/src/androidMain/AndroidManifest.xml
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/res/layout/glance_tile_service_adapter_test.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 The Android Open Source Project
@@ -14,4 +13,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest />
\ No newline at end of file
+
+<androidx.glance.wear.tiles.preview.GlanceTileServiceViewAdapter
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/glance_tile_service_view_adapter"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/res/values/styles.xml b/glance/glance-wear-tiles-preview/src/androidAndroidTest/res/values/styles.xml
new file mode 100644
index 0000000..c2f0b86
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/res/values/styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <style name="TestTheme" parent="@android:style/Theme.Material.Light.NoActionBar">
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowFullscreen">true</item>
+ <item name="android:windowNoTitle">true</item>
+ </style>
+</resources>
\ No newline at end of file
diff --git a/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/ComposableInvoker.kt b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/ComposableInvoker.kt
new file mode 100644
index 0000000..6f9269c
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/ComposableInvoker.kt
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.glance.wear.tiles.preview
+
+import androidx.compose.runtime.Composer
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
+import kotlin.math.ceil
+
+/**
+ * TODO(b/228423246): REMOVE THIS FILE
+ * TEMPORARILY COPIED FROM UI-TOOLING UNTIL IT IS NOT AVAILABLE FROM COMPOSE RUNTIME
+ *
+ * A utility object to invoke composable function by its name and containing class.
+ */
+internal object ComposableInvoker {
+
+ /**
+ * Returns true if the [methodTypes] and [actualTypes] are compatible. This means that every
+ * `actualTypes[n]` are assignable to `methodTypes[n]`.
+ */
+ private fun compatibleTypes(
+ methodTypes: Array<Class<*>>,
+ actualTypes: Array<Class<*>>
+ ): Boolean =
+ methodTypes.size == actualTypes.size &&
+ methodTypes.mapIndexed { index, clazz -> clazz.isAssignableFrom(actualTypes[index]) }
+ .all { it }
+
+ /**
+ * Same as [Class#getDeclaredMethod] but it accounts for compatible types so the signature does
+ * not need to exactly match. This allows finding method calls that use subclasses as parameters
+ * instead of the exact types.
+ */
+ private fun Class<*>.getDeclaredCompatibleMethod(
+ methodName: String,
+ vararg args: Class<*>
+ ): Method {
+ val actualTypes: Array<Class<*>> = arrayOf(*args)
+ return declaredMethods.firstOrNull {
+ methodName == it.name && compatibleTypes(it.parameterTypes, actualTypes)
+ } ?: throw NoSuchMethodException("$methodName not found")
+ }
+
+ private inline fun <reified T> T.dup(count: Int): Array<T> {
+ return (0 until count).map { this }.toTypedArray()
+ }
+
+ /**
+ * Find the given method by name. If the method has parameters, this function will try to find
+ * the version that accepts default parameters.
+ */
+ private fun Class<*>.findComposableMethod(methodName: String, vararg args: Any?): Method {
+ val method = try {
+ // without defaults
+ val changedParams = changedParamCount(args.size, 0)
+ getDeclaredCompatibleMethod(
+ methodName,
+ *args.mapNotNull { it?.javaClass }.toTypedArray(),
+ Composer::class.java, // composer param
+ *kotlin.Int::class.java.dup(changedParams) // changed params
+ )
+ } catch (e: ReflectiveOperationException) {
+ try {
+ declaredMethods.find { it.name == methodName }
+ } catch (e: ReflectiveOperationException) {
+ null
+ }
+ } ?: throw NoSuchMethodException("$name.$methodName")
+
+ return method
+ }
+
+ /**
+ * Returns the default value for the [Class] type. This will be 0 for numeric types, false for
+ * boolean, '0' for char and null for object references.
+ */
+ private fun Class<*>.getDefaultValue(): Any? = when (name) {
+ "int" -> 0.toInt()
+ "short" -> 0.toShort()
+ "byte" -> 0.toByte()
+ "long" -> 0.toLong()
+ "double" -> 0.toDouble()
+ "float" -> 0.toFloat()
+ "boolean" -> false
+ "char" -> 0.toChar()
+ else -> null
+ }
+
+ /**
+ * Calls the method on the given [instance]. If the method accepts default values, this function
+ * will call it with the correct options set.
+ */
+ @Suppress("BanUncheckedReflection")
+ private fun Method.invokeComposableMethod(
+ instance: Any?,
+ composer: Composer,
+ vararg args: Any?
+ ): Any? {
+ val composerIndex = parameterTypes.indexOfLast { it == Composer::class.java }
+ val realParams = composerIndex
+ val thisParams = if (instance != null) 1 else 0
+ val changedParams = changedParamCount(realParams, thisParams)
+ val totalParamsWithoutDefaults = realParams +
+ 1 + // composer
+ changedParams
+ val totalParams = parameterTypes.size
+ val isDefault = totalParams != totalParamsWithoutDefaults
+ val defaultParams = if (isDefault)
+ defaultParamCount(realParams)
+ else
+ 0
+
+ check(
+ realParams +
+ 1 + // composer
+ changedParams +
+ defaultParams ==
+ totalParams
+ )
+
+ val changedStartIndex = composerIndex + 1
+ val defaultStartIndex = changedStartIndex + changedParams
+
+ val arguments = Array(totalParams) { idx ->
+ when (idx) {
+ // pass in "empty" value for all real parameters since we will be using defaults.
+ in 0 until realParams -> args.getOrElse(idx) {
+ parameterTypes[idx].getDefaultValue()
+ }
+ // the composer is the first synthetic parameter
+ composerIndex -> composer
+ // since this is the root we don't need to be anything unique. 0 should suffice.
+ // changed parameters should be 0 to indicate "uncertain"
+ in changedStartIndex until defaultStartIndex -> 0
+ // Default values mask, all parameters set to use defaults
+ in defaultStartIndex until totalParams -> 0b111111111111111111111.toInt()
+ else -> error("Unexpected index")
+ }
+ }
+ return invoke(instance, *arguments)
+ }
+
+ private const val SLOTS_PER_INT = 10
+ private const val BITS_PER_INT = 31
+
+ private fun changedParamCount(realValueParams: Int, thisParams: Int): Int {
+ if (realValueParams == 0) return 1
+ val totalParams = realValueParams + thisParams
+ return ceil(
+ totalParams.toDouble() / SLOTS_PER_INT.toDouble()
+ ).toInt()
+ }
+
+ private fun defaultParamCount(realValueParams: Int): Int {
+ return ceil(
+ realValueParams.toDouble() / BITS_PER_INT.toDouble()
+ ).toInt()
+ }
+
+ /**
+ * Invokes the given [methodName] belonging to the given [className]. The [methodName] is
+ * expected to be a Composable function.
+ * This method [args] will be forwarded to the Composable function.
+ */
+ fun invokeComposable(
+ className: String,
+ methodName: String,
+ composer: Composer,
+ vararg args: Any?
+ ) {
+ try {
+ val composableClass = Class.forName(className)
+
+ val method = composableClass.findComposableMethod(methodName, *args)
+ method.isAccessible = true
+
+ if (Modifier.isStatic(method.modifiers)) {
+ // This is a top level or static method
+ method.invokeComposableMethod(null, composer, *args)
+ } else {
+ // The method is part of a class. We try to instantiate the class with an empty
+ // constructor.
+ val instance = composableClass.getConstructor().newInstance()
+ method.invokeComposableMethod(instance, composer, *args)
+ }
+ } catch (e: ReflectiveOperationException) {
+ throw ClassNotFoundException("Composable Method '$className.$methodName' not found", e)
+ }
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt
new file mode 100644
index 0000000..6ed80ec
--- /dev/null
+++ b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.glance.wear.tiles.preview
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.Gravity
+import android.widget.FrameLayout
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.currentComposer
+import androidx.compose.ui.unit.DpSize
+import androidx.core.content.ContextCompat
+import androidx.glance.wear.tiles.ExperimentalGlanceWearTilesApi
+import androidx.glance.wear.tiles.compose
+import androidx.glance.wear.tiles.preview.ComposableInvoker.invokeComposable
+import androidx.wear.tiles.LayoutElementBuilders
+import androidx.wear.tiles.TileBuilders
+import androidx.wear.tiles.TimelineBuilders
+import kotlinx.coroutines.runBlocking
+import androidx.wear.tiles.renderer.TileRenderer
+
+private const val TOOLS_NS_URI = "http://schemas.android.com/tools"
+
+/**
+ * View adapter that renders a glance `@Composable`. The `@Composable` is found by reading the
+ * `tools:composableName` attribute that contains the FQN of the function.
+ */
+internal class GlanceTileServiceViewAdapter : FrameLayout {
+
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
+ init(attrs)
+ }
+
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
+ context,
+ attrs,
+ defStyleAttr
+ ) {
+ init(attrs)
+ }
+
+ @OptIn(ExperimentalGlanceWearTilesApi::class)
+ internal fun init(
+ className: String,
+ methodName: String,
+ ) {
+ val content = @Composable {
+ val composer = currentComposer
+ invokeComposable(
+ className,
+ methodName,
+ composer)
+ }
+
+ val wearTilesComposition = runBlocking {
+ compose(
+ context = context,
+ size = DpSize.Unspecified,
+ content = content)
+ }
+ // As far as GlanceWearTiles.compose accepts no timeleine argument, assume we only support
+ // [TimelineMode.SingleEntry]
+ val timelineBuilders = TimelineBuilders.Timeline.Builder()
+ timelineBuilders.addTimelineEntry(
+ TimelineBuilders.TimelineEntry.Builder()
+ .setLayout(
+ LayoutElementBuilders.Layout.Builder()
+ .setRoot(wearTilesComposition.layout)
+ .build()
+ ).build()
+ )
+ val tile = TileBuilders.Tile.Builder()
+ .setTimeline(timelineBuilders.build())
+ .build()
+ val layout = tile.timeline?.timelineEntries?.get(0)?.layout
+
+ if (layout != null) {
+ val renderer = TileRenderer(
+ context,
+ layout,
+ wearTilesComposition.resources,
+ ContextCompat.getMainExecutor(context)
+ ) { }
+ renderer.inflate(this)?.apply {
+ (layoutParams as LayoutParams).gravity = Gravity.CENTER
+ }
+ }
+ }
+
+ private fun init(attrs: AttributeSet) {
+ val composableName = attrs.getAttributeValue(TOOLS_NS_URI, "composableName") ?: return
+ val className = composableName.substringBeforeLast('.')
+ val methodName = composableName.substringAfterLast('.')
+
+ init(className, methodName)
+ }
+}
\ No newline at end of file
diff --git a/health/health-connect-client/api/current.txt b/health/health-connect-client/api/current.txt
index 177a7c2..a6bf526 100644
--- a/health/health-connect-client/api/current.txt
+++ b/health/health-connect-client/api/current.txt
@@ -1466,16 +1466,19 @@
method public double getMicrograms();
method public double getMilligrams();
method public double getOunces();
+ method public double getPounds();
method public static androidx.health.connect.client.units.Mass grams(double value);
method public static androidx.health.connect.client.units.Mass kilograms(double value);
method public static androidx.health.connect.client.units.Mass micrograms(double value);
method public static androidx.health.connect.client.units.Mass milligrams(double value);
method public static androidx.health.connect.client.units.Mass ounces(double value);
+ method public static androidx.health.connect.client.units.Mass pounds(double value);
property public final double inGrams;
property public final double inKilograms;
property public final double inMicrograms;
property public final double inMilligrams;
property public final double inOunces;
+ property public final double inPounds;
field public static final androidx.health.connect.client.units.Mass.Companion Companion;
}
@@ -1485,6 +1488,7 @@
method public androidx.health.connect.client.units.Mass micrograms(double value);
method public androidx.health.connect.client.units.Mass milligrams(double value);
method public androidx.health.connect.client.units.Mass ounces(double value);
+ method public androidx.health.connect.client.units.Mass pounds(double value);
}
public final class MassKt {
diff --git a/health/health-connect-client/api/public_plus_experimental_current.txt b/health/health-connect-client/api/public_plus_experimental_current.txt
index 177a7c2..a6bf526 100644
--- a/health/health-connect-client/api/public_plus_experimental_current.txt
+++ b/health/health-connect-client/api/public_plus_experimental_current.txt
@@ -1466,16 +1466,19 @@
method public double getMicrograms();
method public double getMilligrams();
method public double getOunces();
+ method public double getPounds();
method public static androidx.health.connect.client.units.Mass grams(double value);
method public static androidx.health.connect.client.units.Mass kilograms(double value);
method public static androidx.health.connect.client.units.Mass micrograms(double value);
method public static androidx.health.connect.client.units.Mass milligrams(double value);
method public static androidx.health.connect.client.units.Mass ounces(double value);
+ method public static androidx.health.connect.client.units.Mass pounds(double value);
property public final double inGrams;
property public final double inKilograms;
property public final double inMicrograms;
property public final double inMilligrams;
property public final double inOunces;
+ property public final double inPounds;
field public static final androidx.health.connect.client.units.Mass.Companion Companion;
}
@@ -1485,6 +1488,7 @@
method public androidx.health.connect.client.units.Mass micrograms(double value);
method public androidx.health.connect.client.units.Mass milligrams(double value);
method public androidx.health.connect.client.units.Mass ounces(double value);
+ method public androidx.health.connect.client.units.Mass pounds(double value);
}
public final class MassKt {
diff --git a/health/health-connect-client/api/restricted_current.txt b/health/health-connect-client/api/restricted_current.txt
index 0902c22..5ff06aa 100644
--- a/health/health-connect-client/api/restricted_current.txt
+++ b/health/health-connect-client/api/restricted_current.txt
@@ -1489,16 +1489,19 @@
method public double getMicrograms();
method public double getMilligrams();
method public double getOunces();
+ method public double getPounds();
method public static androidx.health.connect.client.units.Mass grams(double value);
method public static androidx.health.connect.client.units.Mass kilograms(double value);
method public static androidx.health.connect.client.units.Mass micrograms(double value);
method public static androidx.health.connect.client.units.Mass milligrams(double value);
method public static androidx.health.connect.client.units.Mass ounces(double value);
+ method public static androidx.health.connect.client.units.Mass pounds(double value);
property public final double inGrams;
property public final double inKilograms;
property public final double inMicrograms;
property public final double inMilligrams;
property public final double inOunces;
+ property public final double inPounds;
field public static final androidx.health.connect.client.units.Mass.Companion Companion;
}
@@ -1508,6 +1511,7 @@
method public androidx.health.connect.client.units.Mass micrograms(double value);
method public androidx.health.connect.client.units.Mass milligrams(double value);
method public androidx.health.connect.client.units.Mass ounces(double value);
+ method public androidx.health.connect.client.units.Mass pounds(double value);
}
public final class MassKt {
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/units/Mass.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/units/Mass.kt
index eef031b..babdd20 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/units/Mass.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/units/Mass.kt
@@ -24,6 +24,7 @@
* - milligrams - see [Mass.milligrams], [Double.milligrams]
* - micrograms - see [Mass.micrograms], [Double.micrograms]
* - ounces - see [Mass.ounces], [Double.ounces]
+ * - pounds - see [Mass.pounds], [Double.pounds]
*/
class Mass private constructor(
private val value: Double,
@@ -55,6 +56,11 @@
val inOunces: Double
get() = get(type = Type.OUNCES)
+ /** Returns the mass in pounds. */
+ @get:JvmName("getPounds")
+ val inPounds: Double
+ get() = get(type = Type.POUNDS)
+
private fun get(type: Type): Double =
if (this.type == type) value else inGrams / type.gramsPerUnit
@@ -109,6 +115,9 @@
/** Creates [Mass] with the specified value in ounces. */
@JvmStatic fun ounces(value: Double): Mass = Mass(value, Type.OUNCES)
+
+ /** Creates [Mass] with the specified value in pounds. */
+ @JvmStatic fun pounds(value: Double): Mass = Mass(value, Type.POUNDS)
}
private enum class Type {
@@ -126,6 +135,9 @@
},
OUNCES {
override val gramsPerUnit: Double = 28.34952
+ },
+ POUNDS {
+ override val gramsPerUnit: Double = 453.59237
};
abstract val gramsPerUnit: Double
@@ -231,3 +243,23 @@
@get:JvmSynthetic
val Int.ounces: Mass
get() = toDouble().ounces
+
+/** Creates [Mass] with the specified value in pounds. */
+@get:JvmSynthetic
+val Double.pounds: Mass
+ get() = Mass.pounds(value = this)
+
+/** Creates [Mass] with the specified value in pounds. */
+@get:JvmSynthetic
+val Float.pounds: Mass
+ get() = toDouble().pounds
+
+/** Creates [Mass] with the specified value in pounds. */
+@get:JvmSynthetic
+val Long.pounds: Mass
+ get() = toDouble().pounds
+
+/** Creates [Mass] with the specified value in pounds. */
+@get:JvmSynthetic
+val Int.pounds: Mass
+ get() = toDouble().pounds
diff --git a/health/health-services-client/api/1.0.0-beta01.txt b/health/health-services-client/api/1.0.0-beta01.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/1.0.0-beta01.txt
+++ b/health/health-services-client/api/1.0.0-beta01.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/api/api_lint.ignore b/health/health-services-client/api/api_lint.ignore
index 692c66a..ded5bc40 100644
--- a/health/health-services-client/api/api_lint.ignore
+++ b/health/health-services-client/api/api_lint.ignore
@@ -23,8 +23,6 @@
Invalid nullability on parameter `intent` in method `onBind`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
InvalidNullabilityOverride: androidx.health.services.client.VersionApiService#onBind(android.content.Intent):
Invalid nullability on method `onBind` return. Overrides of unannotated super method cannot be Nullable.
-InvalidNullabilityOverride: androidx.health.services.client.data.ProtoParcelable#writeToParcel(android.os.Parcel, int) parameter #0:
- Invalid nullability on parameter `dest` in method `writeToParcel`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
PairedRegistration: androidx.health.services.client.MeasureClient#registerMeasureCallback(androidx.health.services.client.data.DeltaDataType<?,?>, androidx.health.services.client.MeasureCallback):
diff --git a/health/health-services-client/api/current.txt b/health/health-services-client/api/current.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/current.txt
+++ b/health/health-services-client/api/current.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/api/public_plus_experimental_1.0.0-beta01.txt b/health/health-services-client/api/public_plus_experimental_1.0.0-beta01.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/public_plus_experimental_1.0.0-beta01.txt
+++ b/health/health-services-client/api/public_plus_experimental_1.0.0-beta01.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/api/public_plus_experimental_current.txt b/health/health-services-client/api/public_plus_experimental_current.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/public_plus_experimental_current.txt
+++ b/health/health-services-client/api/public_plus_experimental_current.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/api/restricted_1.0.0-beta01.txt b/health/health-services-client/api/restricted_1.0.0-beta01.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/restricted_1.0.0-beta01.txt
+++ b/health/health-services-client/api/restricted_1.0.0-beta01.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/api/restricted_current.txt b/health/health-services-client/api/restricted_current.txt
index 56bfe2d..a170f81 100644
--- a/health/health-services-client/api/restricted_current.txt
+++ b/health/health-services-client/api/restricted_current.txt
@@ -451,7 +451,6 @@
field public static final androidx.health.services.client.data.ExerciseType BASEBALL;
field public static final androidx.health.services.client.data.ExerciseType BASKETBALL;
field public static final androidx.health.services.client.data.ExerciseType BENCH_PRESS;
- field public static final androidx.health.services.client.data.ExerciseType BENCH_SIT_UP;
field public static final androidx.health.services.client.data.ExerciseType BIKING;
field public static final androidx.health.services.client.data.ExerciseType BIKING_STATIONARY;
field public static final androidx.health.services.client.data.ExerciseType BOOT_CAMP;
@@ -464,13 +463,6 @@
field public static final androidx.health.services.client.data.ExerciseType.Companion Companion;
field public static final androidx.health.services.client.data.ExerciseType DANCING;
field public static final androidx.health.services.client.data.ExerciseType DEADLIFT;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_CURL_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_FRONT_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_LATERAL_RAISE;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM;
- field public static final androidx.health.services.client.data.ExerciseType DUMBBELL_TRICEPS_EXTENSION_TWO_ARM;
field public static final androidx.health.services.client.data.ExerciseType ELLIPTICAL;
field public static final androidx.health.services.client.data.ExerciseType EXERCISE_CLASS;
field public static final androidx.health.services.client.data.ExerciseType FENCING;
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseType.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseType.kt
index 6716a53..5f9affbe 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseType.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseType.kt
@@ -63,7 +63,7 @@
@JvmField public val BASEBALL: ExerciseType = ExerciseType(4, "BASEBALL")
@JvmField public val BASKETBALL: ExerciseType = ExerciseType(5, "BASKETBALL")
@JvmField public val BENCH_PRESS: ExerciseType = ExerciseType(6, "BENCH_PRESS")
- @JvmField public val BENCH_SIT_UP: ExerciseType = ExerciseType(7, "BENCH_SIT_UP")
+ @JvmField internal val BENCH_SIT_UP: ExerciseType = ExerciseType(7, "BENCH_SIT_UP")
@JvmField public val BIKING: ExerciseType = ExerciseType(8, "BIKING")
@JvmField public val BIKING_STATIONARY: ExerciseType = ExerciseType(9, "BIKING_STATIONARY")
@JvmField public val BOOT_CAMP: ExerciseType = ExerciseType(10, "BOOT_CAMP")
@@ -79,22 +79,24 @@
@JvmField public val DANCING: ExerciseType = ExerciseType(16, "DANCING")
@JvmField public val DEADLIFT: ExerciseType = ExerciseType(17, "DEADLIFT")
@JvmField
- public val DUMBBELL_CURL_RIGHT_ARM: ExerciseType =
+ internal val DUMBBELL_CURL_RIGHT_ARM: ExerciseType =
ExerciseType(18, "DUMBBELL_CURL_RIGHT_ARM")
@JvmField
- public val DUMBBELL_CURL_LEFT_ARM: ExerciseType = ExerciseType(19, "DUMBBELL_CURL_LEFT_ARM")
+ internal val DUMBBELL_CURL_LEFT_ARM: ExerciseType =
+ ExerciseType(19, "DUMBBELL_CURL_LEFT_ARM")
@JvmField
- public val DUMBBELL_FRONT_RAISE: ExerciseType = ExerciseType(20, "DUMBBELL_FRONT_RAISE")
+ internal val DUMBBELL_FRONT_RAISE: ExerciseType = ExerciseType(20, "DUMBBELL_FRONT_RAISE")
@JvmField
- public val DUMBBELL_LATERAL_RAISE: ExerciseType = ExerciseType(21, "DUMBBELL_LATERAL_RAISE")
+ internal val DUMBBELL_LATERAL_RAISE: ExerciseType =
+ ExerciseType(21, "DUMBBELL_LATERAL_RAISE")
@JvmField
- public val DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM: ExerciseType =
+ internal val DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM: ExerciseType =
ExerciseType(22, "DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM")
@JvmField
- public val DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM: ExerciseType =
+ internal val DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM: ExerciseType =
ExerciseType(23, "DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM")
@JvmField
- public val DUMBBELL_TRICEPS_EXTENSION_TWO_ARM: ExerciseType =
+ internal val DUMBBELL_TRICEPS_EXTENSION_TWO_ARM: ExerciseType =
ExerciseType(24, "DUMBBELL_TRICEPS_EXTENSION_TWO_ARM")
@JvmField public val ELLIPTICAL: ExerciseType = ExerciseType(25, "ELLIPTICAL")
@JvmField public val EXERCISE_CLASS: ExerciseType = ExerciseType(26, "EXERCISE_CLASS")
diff --git a/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt b/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
index b28ee39..fb5616b 100644
--- a/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
+++ b/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
@@ -34,7 +34,7 @@
import kotlin.UnsupportedOperationException
/**
- * An utility class that provides `ViewModels` for a scope.
+ * A utility class that provides `ViewModels` for a scope.
*
* Default `ViewModelProvider` for an `Activity` or a `Fragment` can be obtained
* by passing it to the constructor: `ViewModelProvider(myFragment)`
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index 136ac5d..834cf3f 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -19,6 +19,7 @@
import androidx.room.compiler.processing.XEquality
import androidx.room.compiler.processing.XNullability
import androidx.room.compiler.processing.XType
+import androidx.room.compiler.processing.isArray
import androidx.room.compiler.processing.tryBox
import androidx.room.compiler.processing.tryUnbox
import com.google.devtools.ksp.symbol.KSClassDeclaration
@@ -84,9 +85,18 @@
}
override val typeElement by lazy {
- // for primitive types, we could technically return null from here as they are not backed
- // by a type element in javac but in Kotlin we have types for them, hence returning them
- // is better.
+ // Array types don't have an associated type element (only the componentType does), so
+ // return null.
+ if (isArray()) {
+ return@lazy null
+ }
+
+ // If the typeName is primitive, return null for consistency since primitives normally imply
+ // that there isn't an associated type element.
+ if (typeName.isPrimitive) {
+ return@lazy null
+ }
+
val declaration = ksType.declaration as? KSClassDeclaration
declaration?.let {
env.wrapClassDeclaration(it)
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index 9f0364c..b347899 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -18,6 +18,7 @@
import androidx.room.compiler.processing.ksp.ERROR_TYPE_NAME
import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.XTestInvocation
import androidx.room.compiler.processing.util.className
import androidx.room.compiler.processing.util.getDeclaredMethodByJvmName
import androidx.room.compiler.processing.util.getField
@@ -830,6 +831,76 @@
}
}
+ @Test
+ fun arrayTypes() {
+ // Used to test both java and kotlin sources.
+ fun XTestInvocation.checkArrayTypesTest() {
+ val fooElement = processingEnv.requireTypeElement("foo.bar.Foo")
+ val barElement = processingEnv.requireTypeElement("foo.bar.Bar")
+ val barType = fooElement.getField("bar").type
+ val barArrayType = fooElement.getField("barArray").type
+
+ assertThat(barType.typeElement).isEqualTo(barElement)
+ assertThat(barType.isArray()).isFalse()
+ assertThat(barArrayType.typeElement).isNull()
+ assertThat(barArrayType.isArray()).isTrue()
+ }
+
+ runProcessorTest(listOf(Source.java(
+ "foo.bar.Foo",
+ """
+ package foo.bar;
+ class Foo {
+ Bar bar;
+ Bar[] barArray;
+ }
+ class Bar {}
+ """.trimIndent()
+ ))) { it.checkArrayTypesTest() }
+
+ runProcessorTest(listOf(Source.kotlin(
+ "foo.bar.Foo.kt",
+ """
+ package foo.bar;
+ class Foo {
+ val bar: Bar = TODO()
+ val barArray: Array<Bar> = TODO()
+ }
+ class Bar
+ """.trimIndent()
+ ))) { it.checkArrayTypesTest() }
+ }
+
+ @Test
+ fun primitiveTypes() {
+ fun XTestInvocation.checkPrimitiveType() {
+ val fooElement = processingEnv.requireTypeElement("foo.bar.Foo")
+ val primitiveType = fooElement.getField("i").type
+ assertThat(primitiveType.typeName).isEqualTo(TypeName.INT)
+ assertThat(primitiveType.typeElement).isNull()
+ }
+
+ runProcessorTest(listOf(Source.java(
+ "foo.bar.Foo",
+ """
+ package foo.bar;
+ class Foo {
+ int i;
+ }
+ """.trimIndent()
+ ))) { it.checkPrimitiveType() }
+
+ runProcessorTest(listOf(Source.kotlin(
+ "foo.bar.Foo.kt",
+ """
+ package foo.bar
+ class Foo {
+ val i: Int = TODO()
+ }
+ """.trimIndent()
+ ))) { it.checkPrimitiveType() }
+ }
+
/**
* Dumps the typename with its bounds in a given depth.
* This makes tests more readable.
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
index b9eb498..f6f9d51 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DatabaseProcessorTest.kt
@@ -1204,19 +1204,9 @@
baseContext = invocation.context,
element = element
).process()
- assertThat(result.daoMethods).hasSize(
- // for KSP, it will still show as a method, just bad return type
- if (invocation.isKsp) 1 else 0
- )
+ assertThat(result.daoMethods).hasSize(0)
invocation.assertCompilationResult {
- hasErrorContaining(
- if (invocation.isKsp) {
- // no primitives in KSP hence we'll get another error
- ProcessorErrors.DAO_MUST_BE_ANNOTATED_WITH_DAO
- } else {
- ProcessorErrors.DATABASE_INVALID_DAO_METHOD_RETURN_TYPE
- }
- )
+ hasErrorContaining(ProcessorErrors.DATABASE_INVALID_DAO_METHOD_RETURN_TYPE)
}
}
}
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
index db69a38..9991b4d 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DeleteOrUpdateShortcutMethodProcessorTest.kt
@@ -582,20 +582,11 @@
""",
) { _, invocation ->
invocation.assertCompilationResult {
- if (invocation.isKsp) {
- hasErrorContaining(
- ProcessorErrors.noColumnsInPartialEntity(
- "java.lang.Long"
- )
+ hasErrorContaining(
+ ProcessorErrors.shortcutMethodArgumentMustBeAClass(
+ TypeName.LONG
)
- } else {
- // javac has a different error for primitives.
- hasErrorContaining(
- ProcessorErrors.shortcutMethodArgumentMustBeAClass(
- TypeName.LONG
- )
- )
- }
+ )
}
}
}
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
index 099ecf8..1df902e 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
@@ -330,16 +330,8 @@
int embeddedPrimitive;
"""
) { _, invocation ->
- if (invocation.isKsp) {
- // there are no primitives in KSP so this won't work. Instead, it will fail
- // because we cannot find a constructor for `int`
- invocation.assertCompilationResult {
- hasErrorContaining(MISSING_POJO_CONSTRUCTOR)
- }
- } else {
- invocation.assertCompilationResult {
- hasErrorContaining(ProcessorErrors.EMBEDDED_TYPES_MUST_BE_A_CLASS_OR_INTERFACE)
- }
+ invocation.assertCompilationResult {
+ hasErrorContaining(ProcessorErrors.EMBEDDED_TYPES_MUST_BE_A_CLASS_OR_INTERFACE)
}
}
}
@@ -481,22 +473,8 @@
public long user;
"""
) { _, invocation ->
- if (invocation.isKsp) {
- // in KSP, there are no primitives so `long` (kotlin.Long) will still look like a
- // class but then we'll fail because it doesn't hvae a `uid` column
- invocation.assertCompilationResult {
- hasErrorContaining(
- relationCannotFindEntityField(
- entityName = "java.lang.Long",
- columnName = "uid",
- availableColumns = emptyList()
- )
- )
- }
- } else {
- invocation.assertCompilationResult {
- hasErrorContaining(ProcessorErrors.RELATION_TYPE_MUST_BE_A_CLASS_OR_INTERFACE)
- }
+ invocation.assertCompilationResult {
+ hasErrorContaining(ProcessorErrors.RELATION_TYPE_MUST_BE_A_CLASS_OR_INTERFACE)
}
}
}
diff --git a/settings.gradle b/settings.gradle
index 6184bf2..7c1552f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -654,6 +654,7 @@
includeProject(":glance:glance-wear-tiles:integration-tests:demos", [BuildType.GLANCE])
includeProject(":glance:glance-wear-tiles:integration-tests:template-demos", [BuildType.GLANCE])
includeProject(":glance:glance-wear-tiles", [BuildType.GLANCE])
+includeProject(":glance:glance-wear-tiles-preview", [BuildType.GLANCE])
includeProject(":gridlayout:gridlayout", [BuildType.MAIN])
includeProject(":health:health-connect-client", [BuildType.MAIN])
includeProject(":health:health-connect-client-proto", [BuildType.MAIN])
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Tests.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Tests.java
index 7ef3613..019c1c6 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Tests.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Tests.java
@@ -49,7 +49,7 @@
@Test
public void testClear() {
- launchTestActivity(UiObject2TestClearTextActivity.class);
+ launchTestActivity(ClearTextTestActivity.class);
UiObject2 object = mDevice.findObject(By.res(TEST_APP, "edit_text"));
// Verify the text field has text before clear()
@@ -61,7 +61,7 @@
@Test
public void testClick() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
// Short click with no parameter (`click()`).
UiObject2 button1 = mDevice.findObject(By.res(TEST_APP, "button1"));
@@ -73,7 +73,7 @@
@Test
public void testClick_point() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
// Short click with a point position as a parameter (`click(Point point)`).
@@ -94,7 +94,7 @@
@Test
public void testClick_duration() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
// Short click with a time duration as a parameter (`click(long duration)`).
UiObject2 button4 = mDevice.findObject(By.res(TEST_APP, "button4"));
@@ -113,7 +113,7 @@
@Test
public void testClick_pointAndDuration() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
// Short click with two parameters (`click(Point point, long duration)`).
UiObject2 button6 = mDevice.findObject(By.res(TEST_APP, "button6"));
@@ -134,7 +134,7 @@
@Test
public void testClickAndWait_conditionAndTimeout() {
- launchTestActivity(UiObject2TestClickAndWaitActivity.class);
+ launchTestActivity(ClickAndWaitTestActivity.class);
// Click the button and wait for a new window
UiObject2 button = mDevice.findObject(By.res(TEST_APP, "new_window_button"));
@@ -143,7 +143,7 @@
@Test
public void testClickAndWait_pointAndConditionAndTimeout() {
- launchTestActivity(UiObject2TestClickAndWaitActivity.class);
+ launchTestActivity(ClickAndWaitTestActivity.class);
// Click point inside the button.
UiObject2 button1 = mDevice.findObject(By.res(TEST_APP, "new_window_button"));
@@ -273,12 +273,12 @@
@Test
public void testGetClassName() {
- launchTestActivity(UiObject2TestGetClassNameActivity.class);
+ launchTestActivity(MainActivity.class);
UiObject2 button = mDevice.findObject(By.res(TEST_APP, "button"));
assertEquals("android.widget.Button", button.getClassName());
- UiObject2 textView = mDevice.findObject(By.res(TEST_APP, "text_view"));
+ UiObject2 textView = mDevice.findObject(By.res(TEST_APP, "example_id"));
assertEquals("android.widget.TextView", textView.getClassName());
}
@@ -319,11 +319,11 @@
public void testGetText() {
launchTestActivity(MainActivity.class);
- UiObject2 object = mDevice.findObject(By.text("Sample text"));
- assertEquals("Sample text", object.getText());
+ UiObject2 sampleTextObject = mDevice.findObject(By.text("Sample text"));
+ assertEquals("Sample text", sampleTextObject.getText());
- UiObject2 nestedObject = mDevice.findObject(By.res(TEST_APP, "nested_elements"));
- assertNull(nestedObject.getText());
+ UiObject2 nullTextObject = mDevice.findObject(By.res(TEST_APP, "nested_elements"));
+ assertNull(nullTextObject.getText());
}
@Test
@@ -392,7 +392,7 @@
@Test
public void testIsCheckable() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
// CheckBox objects are checkable by default.
UiObject2 checkBox = mDevice.findObject(By.res(TEST_APP, "check_box"));
@@ -404,7 +404,7 @@
@Test
public void testIsChecked() {
- launchTestActivity(UiObject2TestClickActivity.class);
+ launchTestActivity(ClickTestActivity.class);
UiObject2 checkBox = mDevice.findObject(By.res(TEST_APP, "check_box"));
assertFalse(checkBox.isChecked());
@@ -752,7 +752,7 @@
@Test
public void testSetText() {
- launchTestActivity(UiObject2TestClearTextActivity.class);
+ launchTestActivity(ClearTextTestActivity.class);
UiObject2 object = mDevice.findObject(By.res(TEST_APP, "edit_text"));
// Verify the text field has "sample_text" before setText()
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
index 5301a70..cdecb3c 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
@@ -74,8 +74,7 @@
UiObject noNode = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id/no_node"));
- assertThrows(noNode.getSelector().toString(), UiObjectNotFoundException.class,
- noNode::getChildCount);
+ assertThrows(UiObjectNotFoundException.class, noNode::getChildCount);
}
@Test
@@ -87,6 +86,7 @@
+ "/drag_button"));
UiObject dragDestination = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/drag_destination"));
+
UiObject expectedDragDest = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/drag_destination").text("drag_received"));
@@ -107,6 +107,7 @@
+ "/drag_button"));
UiObject dragDestination = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/drag_destination"));
+
UiObject expectedDragDest = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/drag_destination").text("drag_received"));
Rect destBounds = dragDestination.getVisibleBounds();
@@ -122,10 +123,19 @@
UiObject swipeRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/swipe_region"));
+ UiObject verySmallRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/very_small_region"));
+ UiObject expectedSwipeRegion = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id"
+ + "/swipe_region").text("swipe_up"));
+
+ // Note that the `swipeRegion` will always show the swipe direction, even if the swipe
+ // action does not happen inside `swipeRegion`.
+ assertFalse(verySmallRegion.swipeUp(100));
assertEquals("no_swipe", swipeRegion.getText());
assertTrue(swipeRegion.swipeUp(100));
- assertEquals("swipe_up", swipeRegion.getText());
+ assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
@Test
@@ -134,10 +144,17 @@
UiObject swipeRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/swipe_region"));
+ UiObject verySmallRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/very_small_region"));
+ UiObject expectedSwipeRegion = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id"
+ + "/swipe_region").text("swipe_down"));
+
+ assertFalse(verySmallRegion.swipeDown(100));
assertEquals("no_swipe", swipeRegion.getText());
assertTrue(swipeRegion.swipeDown(100));
- assertEquals("swipe_down", swipeRegion.getText());
+ assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
@Test
@@ -146,10 +163,17 @@
UiObject swipeRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/swipe_region"));
+ UiObject verySmallRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/very_small_region"));
+ UiObject expectedSwipeRegion = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id"
+ + "/swipe_region").text("swipe_left"));
+
+ assertFalse(verySmallRegion.swipeLeft(100));
assertEquals("no_swipe", swipeRegion.getText());
assertTrue(swipeRegion.swipeLeft(100));
- assertEquals("swipe_left", swipeRegion.getText());
+ assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
@Test
@@ -158,42 +182,216 @@
UiObject swipeRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ "/swipe_region"));
+ UiObject verySmallRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/very_small_region"));
+ UiObject expectedSwipeRegion = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id"
+ + "/swipe_region").text("swipe_right"));
+
+ assertFalse(verySmallRegion.swipeRight(100));
assertEquals("no_swipe", swipeRegion.getText());
assertTrue(swipeRegion.swipeRight(100));
- assertEquals("swipe_right", swipeRegion.getText());
+ assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
+ }
+
+ @Test
+ public void testClick() throws Exception {
+ launchTestActivity(ClickTestActivity.class);
+
+ UiObject button1 = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/button1"));
+
+ UiObject expectedButton1 = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/button1").text("text1_clicked"));
+
+ assertEquals("text1", button1.getText());
+ assertTrue(button1.click());
+ assertTrue(expectedButton1.waitForExists(TIMEOUT_MS));
+ }
+
+ @Test
+ public void testClickAndWaitForNewWindow() throws Exception {
+ launchTestActivity(ClickAndWaitTestActivity.class);
+
+ UiObject newWindowsButton = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/new_window_button"));
+
+ assertTrue(newWindowsButton.clickAndWaitForNewWindow());
+ }
+
+ @Test
+ public void testClickAndWaitForNewWindow_timeout() throws Exception {
+ launchTestActivity(ClickAndWaitTestActivity.class);
+
+ UiObject newWindowsButton = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/new_window_button"));
+
+ assertTrue(newWindowsButton.clickAndWaitForNewWindow(4_000));
+ }
+
+ @Test
+ public void testClickTopLeft() throws Exception {
+ launchTestActivity(ClickOnPositionTestActivity.class);
+
+ UiObject clickRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/click_region"));
+
+ assertEquals("click_region", clickRegion.getText());
+ assertTrue(clickRegion.clickTopLeft());
+ assertEquals("top_left_clicked", clickRegion.getText());
+ }
+
+ @Test
+ public void testLongClickBottomRight() throws Exception {
+ launchTestActivity(ClickOnPositionTestActivity.class);
+
+ UiObject clickRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/click_region"));
+
+ assertEquals("click_region", clickRegion.getText());
+ assertTrue(clickRegion.longClickBottomRight());
+ assertEquals("bottom_right_long_clicked", clickRegion.getText());
+ }
+
+ @Test
+ public void testClickBottomRight() throws Exception {
+ launchTestActivity(ClickOnPositionTestActivity.class);
+
+ UiObject clickRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/click_region"));
+
+ assertEquals("click_region", clickRegion.getText());
+ assertTrue(clickRegion.clickBottomRight());
+ assertEquals("bottom_right_clicked", clickRegion.getText());
+ }
+
+ @Test
+ public void testLongClick() throws Exception {
+ launchTestActivity(ClickOnPositionTestActivity.class);
+
+ UiObject clickRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/click_region"));
+
+ assertEquals("click_region", clickRegion.getText());
+ assertTrue(clickRegion.longClick());
+ assertTrue(clickRegion.getText().contains("long"));
+ }
+
+ @Test
+ public void testLongClickTopLeft() throws Exception {
+ launchTestActivity(ClickOnPositionTestActivity.class);
+
+ UiObject clickRegion = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/click_region"));
+
+ assertEquals("click_region", clickRegion.getText());
+ assertTrue(clickRegion.longClickTopLeft());
+ assertEquals("top_left_long_clicked", clickRegion.getText());
+ }
+
+ @Test
+ public void testClickFamily_throwsUiObjectNotFoundException() {
+ launchTestActivity(ClickTestActivity.class);
+
+ UiObject noNode = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id/no_node"));
+
+ assertThrows(UiObjectNotFoundException.class, noNode::click);
+ assertThrows(UiObjectNotFoundException.class, noNode::clickAndWaitForNewWindow);
+ assertThrows(UiObjectNotFoundException.class, noNode::clickTopLeft);
+ assertThrows(UiObjectNotFoundException.class, noNode::longClickBottomRight);
+ assertThrows(UiObjectNotFoundException.class, noNode::clickBottomRight);
+ assertThrows(UiObjectNotFoundException.class, noNode::longClick);
+ assertThrows(UiObjectNotFoundException.class, noNode::longClickTopLeft);
+ }
+
+ @Test
+ public void testGetText() throws Exception {
+ launchTestActivity(MainActivity.class);
+
+ UiObject sampleTextObject = mDevice.findObject(new UiSelector().text("Sample text"));
+ UiObject nullTextObject = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/nested_elements"));
+
+ assertEquals("Sample text", sampleTextObject.getText());
+ assertEquals("", nullTextObject.getText());
+ }
+
+ @Test
+ public void testGetClassName() throws Exception {
+ launchTestActivity(MainActivity.class);
+
+ UiObject button = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id/button"));
+ UiObject textView = mDevice.findObject(
+ new UiSelector().resourceId(TEST_APP + ":id/example_id"));
+
+ assertEquals("android.widget.Button", button.getClassName());
+ assertEquals("android.widget.TextView", textView.getClassName());
+ }
+
+ @Test
+ public void testGetContentDescription() throws Exception {
+ launchTestActivity(MainActivity.class);
+
+ UiObject button = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id/button"));
+ UiObject textView = mDevice.findObject(new UiSelector().text("Text View 1"));
+
+ assertEquals("I'm accessible!", button.getContentDescription());
+ assertEquals("", textView.getContentDescription());
+ }
+
+ @Test
+ public void testLegacySetText() throws Exception {
+ launchTestActivity(ClearTextTestActivity.class);
+
+ UiObject editText = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/edit_text"));
+
+ assertEquals("sample_text", editText.getText());
+ editText.legacySetText("new_text");
+ assertEquals("new_text", editText.getText());
+ }
+
+ @Test
+ public void testSetText() throws Exception {
+ launchTestActivity(ClearTextTestActivity.class);
+
+ UiObject editText = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/edit_text"));
+
+ assertEquals("sample_text", editText.getText());
+ editText.setText("new_text");
+ assertEquals("new_text", editText.getText());
+ }
+
+ @Test
+ public void testClearTextField() throws Exception {
+ launchTestActivity(ClearTextTestActivity.class);
+
+ UiObject editText = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id"
+ + "/edit_text"));
+
+ assertEquals("sample_text", editText.getText());
+ editText.clearTextField();
+ assertEquals("", editText.getText());
+ }
+
+ @Test
+ public void testTextFamily_throwsUiObjectNotFoundException() {
+ launchTestActivity(ClearTextTestActivity.class);
+
+ UiObject noNode = mDevice.findObject(new UiSelector().resourceId(TEST_APP + ":id/no_node"));
+
+ assertThrows(UiObjectNotFoundException.class, noNode::getText);
+ assertThrows(UiObjectNotFoundException.class, noNode::getClassName);
+ assertThrows(UiObjectNotFoundException.class, noNode::getContentDescription);
+ assertThrows(UiObjectNotFoundException.class, () -> noNode.legacySetText("new_text"));
+ assertThrows(UiObjectNotFoundException.class, () -> noNode.setText("new_text"));
+ assertThrows(UiObjectNotFoundException.class, noNode::clearTextField);
}
/* TODO(b/241158642): Implement these tests, and the tests for exceptions of each tested method.
- public void testClick() {}
-
- public void testClickAndWaitForNewWindow() {}
-
- public void testClickAndWaitForNewWindow_timeout() {}
-
- public void testClickTopLeft() {}
-
- public void testLongClickBottomRight() {}
-
- public void testClickBottomRight() {}
-
- public void testLongClick() {}
-
- public void testLongClickTopLeft() {}
-
- public void testGetText() {}
-
- public void testGetClassName() {}
-
- public void testGetContentDescription() {}
-
- public void testLegacySetText() {}
-
- public void testSetText() {}
-
- public void testClearTextField() {}
-
public void testIsChecked() {}
public void testIsSelected() {}
diff --git a/test/uiautomator/integration-tests/testapp/src/main/AndroidManifest.xml b/test/uiautomator/integration-tests/testapp/src/main/AndroidManifest.xml
index 99fd1c1..1a7feaa 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -41,6 +41,34 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
+ <activity android:name=".ClearTextTestActivity"
+ android:exported="true"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".ClickAndWaitTestActivity"
+ android:exported="true"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".ClickOnPositionTestActivity"
+ android:exported="true"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".ClickTestActivity"
+ android:exported="true"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
<activity android:name=".DragTestActivity"
android:exported="true"
android:theme="@android:style/Theme.Holo.NoActionBar">
@@ -87,27 +115,6 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
- <activity android:name=".UiObject2TestClearTextActivity"
- android:exported="true"
- android:theme="@android:style/Theme.Holo.NoActionBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
- <activity android:name=".UiObject2TestClickActivity"
- android:exported="true"
- android:theme="@android:style/Theme.Holo.NoActionBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
- <activity android:name=".UiObject2TestClickAndWaitActivity"
- android:exported="true"
- android:theme="@android:style/Theme.Holo.NoActionBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
<activity android:name=".UiObject2TestFlingActivity"
android:exported="true"
android:theme="@android:style/Theme.Holo.NoActionBar">
@@ -150,13 +157,6 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
- <activity android:name=".UiObject2TestGetClassNameActivity"
- android:exported="true"
- android:theme="@android:style/Theme.Holo.NoActionBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
<activity android:name=".UiObject2TestPinchActivity"
android:exported="true"
android:theme="@android:style/Theme.Holo.NoActionBar">
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClearTextActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClearTextTestActivity.java
similarity index 87%
rename from test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClearTextActivity.java
rename to test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClearTextTestActivity.java
index 6a816ba..988472f 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClearTextActivity.java
+++ b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClearTextTestActivity.java
@@ -21,12 +21,12 @@
import androidx.annotation.Nullable;
-public class UiObject2TestClearTextActivity extends Activity {
+public class ClearTextTestActivity extends Activity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.uiobject2_testcleartext_activity);
+ setContentView(R.layout.clear_text_test_activity);
}
}
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickAndWaitActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickAndWaitTestActivity.java
similarity index 83%
rename from test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickAndWaitActivity.java
rename to test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickAndWaitTestActivity.java
index 96a6adb..5f82e37 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickAndWaitActivity.java
+++ b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickAndWaitTestActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,20 +26,20 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-public class UiObject2TestClickAndWaitActivity extends Activity {
+public class ClickAndWaitTestActivity extends Activity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.uiobject2_testclickandwait_activity);
+ setContentView(R.layout.click_and_wait_test_activity);
}
public void launchNewWindow(@NonNull View v) {
((Button) v).append("_clicked");
new Handler().postDelayed(() -> {
Intent intent = new Intent(getApplicationContext(),
- UiObject2TestClickAndWaitActivity.class);
+ ClickAndWaitTestActivity.class);
startActivity(intent);
}, 2_000);
}
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickOnPositionTestActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickOnPositionTestActivity.java
new file mode 100644
index 0000000..d300677
--- /dev/null
+++ b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickOnPositionTestActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.test.uiautomator.testapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+public class ClickOnPositionTestActivity extends Activity {
+ private String mTouchMessage = "";
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.click_on_position_test_activity);
+
+ TextView clickRegion = findViewById(R.id.click_region);
+
+ clickRegion.setOnTouchListener((view, motionEvent) -> {
+ if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mTouchMessage += motionEvent.getY() < view.getHeight() / 2.0 ? "top_" : "bottom_";
+ mTouchMessage += motionEvent.getX() < view.getWidth() / 2.0 ? "left" : "right";
+ }
+ return false;
+ });
+ clickRegion.setOnClickListener(view -> clickRegion.setText(mTouchMessage + "_clicked"));
+ clickRegion.setOnLongClickListener(view -> {
+ clickRegion.setText(mTouchMessage + "_long_clicked");
+ return true;
+ });
+ }
+}
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickTestActivity.java
similarity index 78%
rename from test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickActivity.java
rename to test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickTestActivity.java
index 35e4738..452b42e 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestClickActivity.java
+++ b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/ClickTestActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,19 +25,19 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-public class UiObject2TestClickActivity extends Activity {
+public class ClickTestActivity extends Activity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.uiobject2_testclick_activity);
+ setContentView(R.layout.click_test_activity);
// Set up the long-clickable buttons.
- Button button4 = (Button) findViewById(R.id.button4);
- Button button5 = (Button) findViewById(R.id.button5);
- Button button6 = (Button) findViewById(R.id.button6);
- Button button7 = (Button) findViewById(R.id.button7);
+ Button button4 = findViewById(R.id.button4);
+ Button button5 = findViewById(R.id.button5);
+ Button button6 = findViewById(R.id.button6);
+ Button button7 = findViewById(R.id.button7);
button4.setOnLongClickListener(new OnButtonLongClick());
button5.setOnLongClickListener(new OnButtonLongClick());
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestGetClassNameActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestGetClassNameActivity.java
deleted file mode 100644
index 6777abc..0000000
--- a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/UiObject2TestGetClassNameActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.test.uiautomator.testapp;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-
-public class UiObject2TestGetClassNameActivity extends Activity {
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Reuse layout from BySelectorTestClazz
- setContentView(R.layout.byselector_testclazz_activity);
- }
-}
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testcleartext_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/clear_text_test_activity.xml
similarity index 95%
rename from test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testcleartext_activity.xml
rename to test/uiautomator/integration-tests/testapp/src/main/res/layout/clear_text_test_activity.xml
index 49df9a2..e581c09 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testcleartext_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/clear_text_test_activity.xml
@@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".UiObject2TestClearTextActivity">
+ tools:context=".ClearTextTestActivity">
<EditText
android:id="@+id/edit_text"
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_and_wait_test_activity.xml
similarity index 90%
rename from test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml
rename to test/uiautomator/integration-tests/testapp/src/main/res/layout/click_and_wait_test_activity.xml
index 36150b9..d7cf9da 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_and_wait_test_activity.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".UiObject2TestClickAndWaitActivity">
+ tools:context=".ClickAndWaitTestActivity">
<Button
android:id="@+id/new_window_button"
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_on_position_test_activity.xml
similarity index 68%
copy from test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml
copy to test/uiautomator/integration-tests/testapp/src/main/res/layout/click_on_position_test_activity.xml
index 36150b9..3dbe9ab 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclickandwait_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_on_position_test_activity.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".UiObject2TestClickAndWaitActivity">
+ tools:context=".SwipeTestActivity">
- <Button
- android:id="@+id/new_window_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:onClick="launchNewWindow"
- android:text="new_window_button" />
+ <TextView
+ android:id="@+id/click_region"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="30dp"
+ android:background="@android:color/white"
+ android:gravity="center"
+ android:text="click_region" />
</LinearLayout>
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclick_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_test_activity.xml
similarity index 96%
rename from test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclick_activity.xml
rename to test/uiautomator/integration-tests/testapp/src/main/res/layout/click_test_activity.xml
index 54a4ccd..48fa666 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/uiobject2_testclick_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/click_test_activity.xml
@@ -18,9 +18,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- tools:context=".UiObject2TestClickActivity">
+ tools:context=".ClickTestActivity">
- <!-- For `testClick()`. -->
+ <!-- For `testClick()` in both `UiObjectTest` and `UiObject2Test`. -->
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/main_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/main_activity.xml
index 5ef2fc7..239def8 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/main_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/main_activity.xml
@@ -64,7 +64,7 @@
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:entries="@array/list_view_entries"></ListView>
+ android:entries="@array/list_view_entries" />
<TextView
android:layout_width="wrap_content"
diff --git a/test/uiautomator/integration-tests/testapp/src/main/res/layout/swipe_test_activity.xml b/test/uiautomator/integration-tests/testapp/src/main/res/layout/swipe_test_activity.xml
index c9936e2..460e451 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/res/layout/swipe_test_activity.xml
+++ b/test/uiautomator/integration-tests/testapp/src/main/res/layout/swipe_test_activity.xml
@@ -21,6 +21,12 @@
tools:context=".SwipeTestActivity">
<TextView
+ android:id="@+id/very_small_region"
+ android:layout_width="1dp"
+ android:layout_height="1dp"
+ android:text="very_small_region" />
+
+ <TextView
android:id="@+id/swipe_region"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/wear/compose/compose-foundation/api/current.ignore b/wear/compose/compose-foundation/api/current.ignore
new file mode 100644
index 0000000..fe9b752
--- /dev/null
+++ b/wear/compose/compose-foundation/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.wear.compose.foundation.CurvedTextStyle#equals(Object):
+ Removed method androidx.wear.compose.foundation.CurvedTextStyle.equals(Object)
diff --git a/wear/compose/compose-foundation/api/current.txt b/wear/compose/compose-foundation/api/current.txt
index 78a48d4..26f3b10 100644
--- a/wear/compose/compose-foundation/api/current.txt
+++ b/wear/compose/compose-foundation/api/current.txt
@@ -150,7 +150,6 @@
ctor public CurvedTextStyle(optional long background, optional long color, optional long fontSize);
ctor public CurvedTextStyle(androidx.compose.ui.text.TextStyle style);
method public androidx.wear.compose.foundation.CurvedTextStyle copy(optional long background, optional long color, optional long fontSize);
- method public operator boolean equals(Object? other);
method public long getBackground();
method public long getColor();
method public long getFontSize();
diff --git a/wear/compose/compose-foundation/api/public_plus_experimental_current.txt b/wear/compose/compose-foundation/api/public_plus_experimental_current.txt
index 78a48d4..26f3b10 100644
--- a/wear/compose/compose-foundation/api/public_plus_experimental_current.txt
+++ b/wear/compose/compose-foundation/api/public_plus_experimental_current.txt
@@ -150,7 +150,6 @@
ctor public CurvedTextStyle(optional long background, optional long color, optional long fontSize);
ctor public CurvedTextStyle(androidx.compose.ui.text.TextStyle style);
method public androidx.wear.compose.foundation.CurvedTextStyle copy(optional long background, optional long color, optional long fontSize);
- method public operator boolean equals(Object? other);
method public long getBackground();
method public long getColor();
method public long getFontSize();
diff --git a/wear/compose/compose-foundation/api/restricted_current.ignore b/wear/compose/compose-foundation/api/restricted_current.ignore
new file mode 100644
index 0000000..fe9b752
--- /dev/null
+++ b/wear/compose/compose-foundation/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.wear.compose.foundation.CurvedTextStyle#equals(Object):
+ Removed method androidx.wear.compose.foundation.CurvedTextStyle.equals(Object)
diff --git a/wear/compose/compose-foundation/api/restricted_current.txt b/wear/compose/compose-foundation/api/restricted_current.txt
index 78a48d4..26f3b10 100644
--- a/wear/compose/compose-foundation/api/restricted_current.txt
+++ b/wear/compose/compose-foundation/api/restricted_current.txt
@@ -150,7 +150,6 @@
ctor public CurvedTextStyle(optional long background, optional long color, optional long fontSize);
ctor public CurvedTextStyle(androidx.compose.ui.text.TextStyle style);
method public androidx.wear.compose.foundation.CurvedTextStyle copy(optional long background, optional long color, optional long fontSize);
- method public operator boolean equals(Object? other);
method public long getBackground();
method public long getColor();
method public long getFontSize();
diff --git a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/CurvedTextStyle.kt b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/CurvedTextStyle.kt
index c42c947..d262933 100644
--- a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/CurvedTextStyle.kt
+++ b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/CurvedTextStyle.kt
@@ -103,7 +103,7 @@
}
}
- override operator fun equals(other: Any?): Boolean {
+ override fun equals(other: Any?): Boolean {
if (this === other) return true
return other is CurvedTextStyle &&
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
index a66038b..10c0072 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
@@ -50,7 +50,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -83,7 +82,38 @@
}
@Test
- fun initializationCorrectWithAutoCenteringAndNormalItemPadding() {
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForZeroItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(0)
+ }
+
+ @Test
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForOneItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(1)
+ }
+
+ @Test
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForTwoItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(2)
+ }
+
+ @Test
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForThreeItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(3)
+ }
+
+ @Test
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForFourItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(4)
+ }
+
+ @Test
+ fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForFiveItemList() {
+ initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(5)
+ }
+
+ private fun initializationCorrectWithAutoCenteringAndNormalItemPaddingForNItemList(
+ itemCount: Int
+ ) {
lateinit var state: ScalingLazyListState
val listSize = itemSizeDp * 3.5f
rule.setContent {
@@ -92,7 +122,7 @@
state = rememberScalingLazyListState().also { state = it },
modifier = Modifier.testTag(TEST_TAG).requiredSize(listSize),
) {
- items(5) {
+ items(itemCount) {
Box(Modifier.requiredSize(itemSizeDp))
}
}
@@ -902,7 +932,6 @@
assertThat(state.centerItemScrollOffset).isEqualTo(0)
}
- @Ignore("Disabled due to b/239054957")
@Test
fun scrollToNonExistentItemWorks() {
lateinit var state: ScalingLazyListState
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScalingLazyListState.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScalingLazyListState.kt
index 90f782b..2723814 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScalingLazyListState.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScalingLazyListState.kt
@@ -570,10 +570,10 @@
if (lazyListState.layoutInfo.visibleItemsInfo.first().size > 0) return true
// Work out the index we want to find - if there are less items in the list than would be
- // needed to make initialItemIndex be visible then use the last visible item. The -3 is to
+ // needed to make initialItemIndex be visible then use the last visible item. The -2 is to
// allow for the spacers, i.e. an underlying list of size 3 has 2 spacers in index 0 and 2
- // and one real item in index 1.
- val itemIndexToFind = (autoCentering.value!!.itemIndex + 1).coerceAtMost(totalItemCount - 3)
+ // and one real item in underlying lazy column index 1.
+ val itemIndexToFind = (autoCentering.value!!.itemIndex + 1).coerceAtMost(totalItemCount - 2)
// Find the initialCenterItem, if it is null that means it is not in view - therefore
// we have more than enough content before it to make sure it can be scrolled to the center
diff --git a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/testapp/GoldenTestActivity.java b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/testapp/GoldenTestActivity.java
index c9c23f7e..36a28fb 100644
--- a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/testapp/GoldenTestActivity.java
+++ b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/testapp/GoldenTestActivity.java
@@ -21,6 +21,7 @@
import android.app.Activity;
import android.content.Context;
+import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
@@ -65,6 +66,7 @@
Context appContext = getApplicationContext();
FrameLayout root = new FrameLayout(appContext);
+ root.setBackgroundColor(Color.BLACK);
root.setLayoutParams(new LayoutParams(SCREEN_WIDTH, SCREEN_HEIGHT));
Layout layout = new Layout.Builder().setRoot(rootLayoutElement).build();
diff --git a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Chip.java b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Chip.java
index db84840..c704d3f 100644
--- a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Chip.java
+++ b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Chip.java
@@ -99,6 +99,9 @@
* <pre>{@code
* Chip myChip = Chip.fromLayoutElement(box.getContents().get(0));
* }</pre>
+ *
+ * @see androidx.wear.tiles.material.layouts.PrimaryLayout.Builder#setContent if this Chip is used
+ * inside of {@link androidx.wear.tiles.material.layouts.PrimaryLayout}.
*/
public class Chip implements LayoutElement {
/**
diff --git a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Colors.java b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Colors.java
index 101e306..08bfbd0 100644
--- a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Colors.java
+++ b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/Colors.java
@@ -45,7 +45,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@ColorInt
- public static final int ON_PRIMARY = 0xFF202124;
+ public static final int ON_PRIMARY = 0xFF303133;
/**
* The default color used for secondary elements (i.e. background color).
@@ -54,7 +54,7 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@ColorInt
- public static final int SURFACE = 0xFF202124;
+ public static final int SURFACE = 0xFF303133;
/**
* The default color used on secondary elements (i.e. content color).
diff --git a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/TitleChip.java b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/TitleChip.java
index 056089b..d220e42 100644
--- a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/TitleChip.java
+++ b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/TitleChip.java
@@ -68,6 +68,9 @@
* <pre>{@code
* TitleChip myChip = TitleChip.fromLayoutElement(box.getContents().get(0));
* }</pre>
+ *
+ * @see androidx.wear.tiles.material.layouts.PrimaryLayout.Builder#setContent if this TitleChip is
+ * used inside of {@link androidx.wear.tiles.material.layouts.PrimaryLayout}.
*/
public class TitleChip implements LayoutElement {
/** Tool tag for Metadata in Modifiers, so we know that Box is actually a TitleChip. */
diff --git a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/PrimaryLayout.java b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/PrimaryLayout.java
index d33a785..4125e6c 100644
--- a/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/PrimaryLayout.java
+++ b/wear/tiles/tiles-material/src/main/java/androidx/wear/tiles/material/layouts/PrimaryLayout.java
@@ -217,7 +217,16 @@
return this;
}
- /** Sets the additional content to this layout, above the primary chip. */
+ /**
+ * Sets the additional content to this layout, above the primary chip.
+ *
+ * The content slot will wrap the elements' height, so the height of the given content must
+ * be fixed or set to wrap ({@code expand} can't be used).
+ *
+ * This layout has built-in horizontal margins, so the given content should have width set
+ * to {@code expand} to use all the available space, rather than an explicit width which may
+ * lead to clipping.
+ */
@NonNull
public Builder setContent(@NonNull LayoutElement content) {
this.mContent = content;
diff --git a/webkit/webkit/lint-baseline.xml b/webkit/webkit/lint-baseline.xml
deleted file mode 100644
index 18b21f2..0000000
--- a/webkit/webkit/lint-baseline.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
-
- <issue
- id="NewApi"
- message="Call requires API level 29 (current min is 14): `setForceDark`"
- errorLine1=" ApiHelperForQ.setForceDark(settings, forceDarkMode);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/webkit/WebSettingsCompat.java"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 29 (current min is 14): `getForceDark`"
- errorLine1=" return ApiHelperForQ.getForceDark(settings);"
- errorLine2=" ~~~~~~~~~~~~">
- <location
- file="src/main/java/androidx/webkit/WebSettingsCompat.java"/>
- </issue>
-
-</issues>
diff --git a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
index 9e97fc8..4107931 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
@@ -358,7 +358,7 @@
enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public static void setForceDark(@NonNull WebSettings settings,
@ForceDark int forceDarkMode) {
- ApiFeature.NoFramework feature = WebViewFeatureInternal.FORCE_DARK;
+ ApiFeature.Q feature = WebViewFeatureInternal.FORCE_DARK;
if (feature.isSupportedByFramework()) {
ApiHelperForQ.setForceDark(settings, forceDarkMode);
} else if (feature.isSupportedByWebView()) {
@@ -387,7 +387,7 @@
@RequiresFeature(name = WebViewFeature.FORCE_DARK,
enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public static @ForceDark int getForceDark(@NonNull WebSettings settings) {
- ApiFeature.NoFramework feature = WebViewFeatureInternal.FORCE_DARK;
+ ApiFeature.Q feature = WebViewFeatureInternal.FORCE_DARK;
if (feature.isSupportedByFramework()) {
return ApiHelperForQ.getForceDark(settings);
} else if (feature.isSupportedByWebView()) {
diff --git a/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java b/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
index aa106c7..c3fa35b 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -406,7 +406,7 @@
* {@link androidx.webkit.WebSettingsCompat#setForceDark(WebSettings, int)} and
* {@link androidx.webkit.WebSettingsCompat#getForceDark(WebSettings)}.
*/
- public static final ApiFeature.NoFramework FORCE_DARK = new ApiFeature.NoFramework(
+ public static final ApiFeature.Q FORCE_DARK = new ApiFeature.Q(
WebViewFeature.FORCE_DARK, Features.FORCE_DARK);
/**