Address few minor issues in Drawer.
This CL adds parameters requested to allow better Drawer customization, as well as semantics for proper container identification
Fixes: 149274110
Fixes: 154862521
Test: tests updated
Change-Id: I2a3420d18074f82789018087449becd999dfc236
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
index 613d4e2..841f60a 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
@@ -27,7 +27,6 @@
import androidx.ui.foundation.Box
import androidx.ui.foundation.Clickable
import androidx.ui.layout.fillMaxSize
-import androidx.ui.semantics.Semantics
import androidx.ui.test.createComposeRule
import androidx.ui.test.doGesture
import androidx.ui.test.findByTag
@@ -154,27 +153,25 @@
val drawerState = mutableStateOf(DrawerState.Closed)
composeTestRule.setMaterialContent {
TestTag("Drawer") {
- Semantics(container = true) {
- ModalDrawerLayout(drawerState.value, { drawerState.value = it },
- drawerContent = {
- Box(
- Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
- val pos = info.localToGlobal(PxPosition.Origin)
- if (pos.x == 0.px) {
- // If fully opened, mark the openedLatch if present
- openedLatch?.countDown()
- } else if (-pos.x.round() == contentWidth) {
- // If fully closed, mark the closedLatch if present
- closedLatch?.countDown()
- }
+ ModalDrawerLayout(drawerState.value, { drawerState.value = it },
+ drawerContent = {
+ Box(
+ Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
+ val pos = info.localToGlobal(PxPosition.Origin)
+ if (pos.x == 0.px) {
+ // If fully opened, mark the openedLatch if present
+ openedLatch?.countDown()
+ } else if (-pos.x.round() == contentWidth) {
+ // If fully closed, mark the closedLatch if present
+ closedLatch?.countDown()
}
- )
- },
- bodyContent = {
- Box(Modifier.fillMaxSize()
- .onPositioned { contentWidth = it.size.width })
- })
- }
+ }
+ )
+ },
+ bodyContent = {
+ Box(Modifier.fillMaxSize()
+ .onPositioned { contentWidth = it.size.width })
+ })
}
}
// Drawer should start in closed state
@@ -205,19 +202,17 @@
composeTestRule.setMaterialContent {
// emulate click on the screen
TestTag("Drawer") {
- Semantics(container = true) {
- ModalDrawerLayout(drawerState.value, { drawerState.value = it },
- drawerContent = {
- Clickable( drawerClicks += 1 }) {
- Box(Modifier.fillMaxSize(), children = emptyContent())
- }
- },
- bodyContent = {
- Clickable( bodyClicks += 1 }) {
- Box(Modifier.fillMaxSize(), children = emptyContent())
- }
- })
- }
+ ModalDrawerLayout(drawerState.value, { drawerState.value = it },
+ drawerContent = {
+ Clickable( drawerClicks += 1 }) {
+ Box(Modifier.fillMaxSize(), children = emptyContent())
+ }
+ },
+ bodyContent = {
+ Clickable( bodyClicks += 1 }) {
+ Box(Modifier.fillMaxSize(), children = emptyContent())
+ }
+ })
}
}
@@ -255,28 +250,26 @@
val drawerState = mutableStateOf(DrawerState.Closed)
composeTestRule.setMaterialContent {
TestTag("Drawer") {
- Semantics(container = true) {
- BottomDrawerLayout(drawerState.value, { drawerState.value = it },
- drawerContent = {
- Box(Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
- val pos = info.localToGlobal(PxPosition.Origin)
- if (pos.y.round() == openedHeight) {
- // If fully opened, mark the openedLatch if present
- openedLatch?.countDown()
- } else if (pos.y.round() == contentHeight) {
- // If fully closed, mark the closedLatch if present
- closedLatch?.countDown()
- }
- })
- },
- bodyContent = {
- Box(Modifier.fillMaxSize().onPositioned {
- contentHeight = it.size.height
- openedHeight = it.size.height * BottomDrawerOpenFraction
- })
- }
- )
- }
+ BottomDrawerLayout(drawerState.value, { drawerState.value = it },
+ drawerContent = {
+ Box(Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
+ val pos = info.localToGlobal(PxPosition.Origin)
+ if (pos.y.round() == openedHeight) {
+ // If fully opened, mark the openedLatch if present
+ openedLatch?.countDown()
+ } else if (pos.y.round() == contentHeight) {
+ // If fully closed, mark the closedLatch if present
+ closedLatch?.countDown()
+ }
+ })
+ },
+ bodyContent = {
+ Box(Modifier.fillMaxSize().onPositioned {
+ contentHeight = it.size.height
+ openedHeight = it.size.height * BottomDrawerOpenFraction
+ })
+ }
+ )
}
}
// Drawer should start in closed state
@@ -307,19 +300,17 @@
composeTestRule.setMaterialContent {
// emulate click on the screen
TestTag("Drawer") {
- Semantics(container = true) {
- BottomDrawerLayout(drawerState.value, { drawerState.value = it },
- drawerContent = {
- Clickable( drawerClicks += 1 }) {
- Box(Modifier.fillMaxSize(), children = emptyContent())
- }
- },
- bodyContent = {
- Clickable( bodyClicks += 1 }) {
- Box(Modifier.fillMaxSize(), children = emptyContent())
- }
- })
- }
+ BottomDrawerLayout(drawerState.value, { drawerState.value = it },
+ drawerContent = {
+ Clickable( drawerClicks += 1 }) {
+ Box(Modifier.fillMaxSize(), children = emptyContent())
+ }
+ },
+ bodyContent = {
+ Clickable( bodyClicks += 1 }) {
+ Box(Modifier.fillMaxSize(), children = emptyContent())
+ }
+ })
}
}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
index 4dfc50c..254f5c0e 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
@@ -26,15 +26,18 @@
import androidx.ui.core.clipToBounds
import androidx.ui.core.hasBoundedHeight
import androidx.ui.core.hasBoundedWidth
+import androidx.ui.core.semantics.semantics
import androidx.ui.foundation.Box
import androidx.ui.foundation.Canvas
import androidx.ui.foundation.Clickable
import androidx.ui.foundation.gestures.DragDirection
+import androidx.ui.graphics.Shape
import androidx.ui.layout.DpConstraints
import androidx.ui.layout.Stack
import androidx.ui.layout.fillMaxSize
import androidx.ui.layout.preferredSizeIn
import androidx.ui.material.internal.StateDraggable
+import androidx.ui.unit.Dp
import androidx.ui.unit.IntPx
import androidx.ui.unit.Px
import androidx.ui.unit.dp
@@ -72,6 +75,9 @@
* @param onStateChange lambda to be invoked when the drawer requests to change its state,
* e.g. when the drawer is being swiped to the new state or when the scrim is clicked
* @param gesturesEnabled whether or not drawer can be interacted by gestures
+ * @param drawerShape shape of the drawer sheet
+ * @param drawerElevation drawer sheet elevation. This controls the size of the shadow below the
+ * drawer sheet
* @param drawerContent composable that represents content inside the drawer
* @param bodyContent content of the rest of the UI
*
@@ -82,10 +88,12 @@
drawerState: DrawerState,
onStateChange: (DrawerState) -> Unit,
gesturesEnabled: Boolean = true,
+ drawerShape: Shape = MaterialTheme.shapes.large,
+ drawerElevation: Dp = DrawerConstants.DefaultElevation,
drawerContent: @Composable () -> Unit,
bodyContent: @Composable () -> Unit
) {
- Box(Modifier.fillMaxSize()) {
+ Box(Modifier.fillMaxSize().semantics(container = true)) {
WithConstraints {
// TODO : think about Infinite max bounds case
if (!constraints.hasBoundedWidth) {
@@ -113,7 +121,7 @@
Scrim(drawerState, onStateChange, fraction = {
calculateFraction(minValue, maxValue, model.value)
})
- DrawerContent(model, dpConstraints, drawerContent)
+ DrawerContent(model, dpConstraints, drawerShape, drawerElevation, drawerContent)
}
}
}
@@ -138,6 +146,9 @@
* @param onStateChange lambda to be invoked when the drawer requests to change its state,
* e.g. when the drawer is being swiped to the new state or when the scrim is clicked
* @param gesturesEnabled whether or not drawer can be interacted by gestures
+ * @param drawerShape shape of the drawer sheet
+ * @param drawerElevation drawer sheet elevation. This controls the size of the shadow below the
+ * drawer sheet
* @param drawerContent composable that represents content inside the drawer
* @param bodyContent content of the rest of the UI
*
@@ -148,10 +159,12 @@
drawerState: DrawerState,
onStateChange: (DrawerState) -> Unit,
gesturesEnabled: Boolean = true,
+ drawerShape: Shape = MaterialTheme.shapes.large,
+ drawerElevation: Dp = DrawerConstants.DefaultElevation,
drawerContent: @Composable () -> Unit,
bodyContent: @Composable () -> Unit
) {
- Box(Modifier.fillMaxSize()) {
+ Box(Modifier.fillMaxSize().semantics(container = true)) {
WithConstraints {
// TODO : think about Infinite max bounds case
if (!constraints.hasBoundedHeight) {
@@ -196,17 +209,32 @@
// as we scroll "from height to 0" , need to reverse fraction
1 - calculateFraction(openedValue, maxValue, model.value)
})
- BottomDrawerContent(model, dpConstraints, drawerContent)
+ BottomDrawerContent(
+ model, dpConstraints, drawerShape, drawerElevation, drawerContent
+ )
}
}
}
}
}
+/**
+ * Object to hold default values for [ModalDrawerLayout] and [BottomDrawerLayout]
+ */
+object DrawerConstants {
+
+ /**
+ * Default Elevation for drawer sheet as specified in material specs
+ */
+ val DefaultElevation = 16.dp
+}
+
@Composable
private fun DrawerContent(
xOffset: AnimatedFloat,
constraints: DpConstraints,
+ shape: Shape,
+ elevation: Dp,
content: @Composable () -> Unit
) {
WithOffset(xOffset = xOffset) {
@@ -220,7 +248,7 @@
paddingEnd = VerticalDrawerPadding
) {
// remove Container when we will support multiply children
- Surface {
+ Surface(shape = shape, elevation = elevation) {
Box(Modifier.fillMaxSize(), children = content)
}
}
@@ -231,6 +259,8 @@
private fun BottomDrawerContent(
yOffset: AnimatedFloat,
constraints: DpConstraints,
+ shape: Shape,
+ elevation: Dp,
content: @Composable () -> Unit
) {
WithOffset(yOffset = yOffset) {
@@ -243,7 +273,7 @@
)
) {
// remove Container when we will support multiply children
- Surface {
+ Surface(shape = shape, elevation = elevation) {
Box(Modifier.fillMaxSize(), children = content)
}
}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Shapes.kt b/ui/ui-material/src/main/java/androidx/ui/material/Shapes.kt
index 82b25db..f4980ae 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Shapes.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Shapes.kt
@@ -44,7 +44,7 @@
*/
val medium: CornerBasedShape = RoundedCornerShape(4.dp),
/**
- * Shape used by large components.
+ * Shape used by large components like [ModalDrawerLayout] or [BottomDrawerLayout].
*/
val large: CornerBasedShape = RoundedCornerShape(0.dp)
)