The swipe back gesture of the `horologist.WearNavS...
# compose-wear
y
The swipe back gesture of the
horologist.WearNavScaffold
intercepts the drag gesture intended for a
AndroidView
composable. Does anybody experience the same issue? Is it possible to disable the swipe back gesture on a
NavGraphBuilder.scrollable
temporarily?
I am using a MPAndroidChart LineChart inside a
AndroidView
composable. I used
Copy code
requestDisallowInterceptTouchEvent(true)
on the view system before similar to this hack (https://stackoverflow.com/questions/31844471/android-dragging-in-mpandroidchart-is-unresponsive-when-contained-in-scrollvie/59769402#59769402) Is it possible to achieve the same with compose-wear?
Strangely, it happens on the pixel watch. In compose preview tool, and wear os emulator, the drag event works fine.
y
WearNavScaffold is a wrapper for SwipeDismissableNavHost, you can pass in a state which allows you to change the region which is used for swipe to dismiss.
state: SwipeDismissableNavHostState = rememberSwipeDismissableNavHostState()
But I'm not 100% familiar with the right options to do what you want
Cc @stevebower do you know?
y
There is a
swipeToDismissBoxState
inside the
SwipeDismissableNavHostState
which takes
AnimationSpec
and a callback, it doesn’t seem to have any influence of setting the regions to trigger swipe back?
Copy code
public class SwipeToDismissBoxState(
    animationSpec: AnimationSpec<Float> = SwipeToDismissBoxDefaults.AnimationSpec,
    confirmStateChange: (SwipeToDismissValue) -> Boolean = { true },
)
y
You use that state swipeToDismissBoxState with a modifier. See https://kotlinlang.slack.com/archives/C02GBABJUAF/p1662486779957449
y
Unfortunately, the
Copy code
.edgeSwipeToDismiss(swipeToDismissBoxState, 0.dp)
doesn’t help to deactivate the
SwipeDismissableNavHost
in my case. Inside the
androidx.wear.compose.material.SwipeToDismissBox
is a Box with
swipable
modifier, which probably triggers the swipe gesture from the
maxWidth
Copy code
Box(
    modifier = modifier
        .fillMaxSize()
        .onSizeChanged { maxWidth = it.width.toFloat() }
        .swipeable(
            state = state.swipeableState,
            enabled = hasBackground,
            anchors = anchors(maxWidth),
            thresholds = { _, _ -> FractionalThreshold(SWIPE_THRESHOLD) },
            resistance = ResistanceConfig(
                basis = maxWidth,
                factorAtMin = TOTAL_RESISTANCE,
                factorAtMax = TOTAL_RESISTANCE,
            ),
            orientation = Orientation.Horizontal,
        )
Does this means, i need to use
swipeable
on my
AndroidView
with
anchers = anchors(0.dp)
instead of
edgeSwipeToDismiss
?
What is this
maxWidth
defined inside the
SwipeToDismissBox
? A fraction maybe?
Copy code
@Composable
@OptIn(ExperimentalWearMaterialApi::class)
public fun SwipeToDismissBox(
   ...
) {
    // Will be updated in onSizeChanged, initialise to any value other than zero
    // so that it is different to the other anchor used for the swipe gesture.
    var maxWidth by remember { mutableStateOf(1f) }
y
I'm out of my depth here. Best wait for one of the core wear compose devs to chime in.
s
Hi - if you want to disable SwipeToDismiss on a composable, you could try this, which has done the trick for me in the past:
Copy code
/**
 * Override a composable to be unswipeable by blocking the swipe-to-dismiss gesture.
 *
 * When a composable is on top of another composable that supports swipe-to-dismiss,
 * then [Modifier.unswipeable] can be applied to the top composable to handle and ignore
 * the swipe gesture. For example, this may be used to prevent swiping away a dialog.
 */
public fun Modifier.unswipeable() =
  this.then(
    Modifier.draggable(
      orientation = Orientation.Horizontal,
      enabled = true,
      state = DraggableState {}
    )
  )
🦜 1
y
@stevebower Thanks so much, you saved my day. Your modifier extension function
unswipeable
helps disable the swipe back on SwipeToDismissBox, which also allows
very slow drag
events to be consumed by the AndroidView composable still. This is is a good hack It would be super great if
edgeSwipeToDismiss
can work on any composable, as stated in this issue https://issuetracker.google.com/issues/200699800
s
@Michail Kulaga Please take a look - thanks.
y
@Michail Kulaga I created a sample repository https://github.com/yingding/swipeToDismiss to show the
edgeSwipeToDismiss
modifier doesn’t work on my
AndroidView
, which is documented in https://issuetracker.google.com/issues/200699800 Thanks for looking into this.
m
Thanks @Yingding Wang for the demo!
121 Views