flutter_slidable
flutter_slidable copied to clipboard
Action pane with rounded corners
I have Card
s that are wrapped with Slidable
widgets.
What I want
When the cards slide I want the action pane corners to be rounded as the Card:

(From material design documentation, specifically this video)
What I tried
Wrapping the action pane (SlidableBehindActionPane
in this case) with ClipRRect
.
What happened
the behaviour is inconsistent. Initially, the child is also clipped, but after sliding and sliding back the child is no longer clipped.
Ok I will look at it for while doing the refactoring.
I was able to accomplish this by wrapping the Action in an OverflowBox w/LayoutBuilder:
LayoutBuilder(
builder: (context, constraints) =>
OverflowBox(
alignment: Alignment.topLeft,
minWidth: constraints.minWidth,
maxWidth: constraints.maxWidth + 10.0, // your corner radius
minHeight: constraints.minHeight,
maxHeight: constraints.maxHeight,
child: IconSlideAction(
caption: 'Archive',
color: Colors.blue,
icon: Icons.archive,
onTap: () {},
),
),
),
hope this helps!
I was able to accomplish this by wrapping the Action in an OverflowBox w/LayoutBuilder:
LayoutBuilder( builder: (context, constraints) => OverflowBox( alignment: Alignment.topLeft, minWidth: constraints.minWidth, maxWidth: constraints.maxWidth + 10.0, // your corner radius minHeight: constraints.minHeight, maxHeight: constraints.maxHeight, child: IconSlideAction( caption: 'Archive', color: Colors.blue, icon: Icons.archive, onTap: () {}, ), ), ),
hope this helps!
Hello this works for me too, but my requirement is opposite to OP's, which is set the actions card and my card has same borderRadius, like email app in iPadOS:
Is it possible to do this with your method?
Thank you
Should be ok with 1.0. Can you test it?
I tried 1.0-dev.9. to add space and rounded corners to the actions.
First Problem: If the backgroundColor of SlideableAction is used, the whole available space is used and no space or rounded corners are appliable (At least I don't know how). So I tried it with CustomSlidableAction (following code):
CustomSlidableAction(
backgroundColor: Colors.blue,
onPressed: (context) { },
child: LayoutBuilder(
builder: (context, constraints) => Container(
color: Colors.grey,
margin: EdgeInsets.symmetric(vertical: 4.0),
width: constraints.maxWidth,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Icon(Icons.check_box_outline_blank),
Text("Remove")
],
),
),
),
),
Problem: but I'm not able to expand the Container horizontally. I would like the grey to be expanded horizontally, but it's tight with the Column's content (see following Screenshot).
Question: How can I expand a child in CustomSlidableAction to the available space?
This solution doesn't work any more
Should be ok with 1.0. Can you test it?
There is a borderRadius
on the SlidableAction
now, can you test with the latest version?
@letsar I am not sure this is enough, if you take a look at his screenshot, it has the radius to the opposite side. I am having the same problem, let me try to explain the way I see the problem and how I would solve it, maybe you know a easier way to solve. in the list, the item would have no radius, but, on the action of sliding, it would change that radius. With this new radius during the slide action, the item would be cropped, and the background from the start/end action would be visible. Now, I am not sure how things work under the hood, but, it would only be possible if the Slidable widget could be a container under the widget it is receiving, that could detect the color from the closest action of each ActionPanel and paint the half left and the half right of its own (under received Widget) container of the closest action Foreground colors. Also, it would be necessary that each panel could receive a callback, so we can identify when the sliding action is happening. (by the way, this callback would be awesome for multiple other things.) Does it make sense?
Hi, I also made my own attempt, but IT ONLY WORKS BY ADDING clipBehavior: Clip.none,
on the ClipRect()
of the action pane (slidable.dart, line 244).
ActionPane(
motion: const BehindMotion(),
extentRatio: 0.25,
children: [
Expanded(
child: LayoutBuilder(builder: (context, constraints) {
return OverflowBox(
alignment: Alignment.centerLeft,
maxWidth: constraints.maxWidth + 15,
child: GestureDetector(
onTap: () {},
child: Container(
padding: const EdgeInsets.only(right: 15),
decoration: const BoxDecoration(
borderRadius: BorderRadius.horizontal(left: Radius.circular(15)),
color: Colors.blue,
),
alignment: Alignment.center,
child: const Icon(Icons.copy, color: Colors.white),
),
),
);
}),
),
],
)
Did it by overflowing the Slidable
content width by its own borderRadius
:
LayoutBuilder(builder: (context, constraints) {
return Slidable(
startActionPane: _buildStartActionPane,
endActionPane: _buildEndActionPane,
child: OverflowBox(
alignment: Alignment.center, // Alignment.center for both sides (Alignment.centerRight for startActionPane only and Alignment.centerLeft for endActionPane only)
maxWidth: constraints.maxWidth + 30, // 2 times the borderRadius for left and right
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.black26,
blurRadius: 3,
offset: Offset(1, 3),
),
],
),
child: _content,
),
),
);
})
The only issue is that the ActionPanes
will have a margin equal to the border radius