Я хочу сделать 2 (приподнятые) кнопки, одну (назад) в форме буквы L и одну с обычным закругленным текстом, вот так:
На данный момент я могу придумать 3 подхода, но не знаю, как реализовать любой из них:
clip
, чтобы вырезать внутреннюю часть кнопки L, но я не уверен, как сделать правильные закругленные углы в верхней левой части; Кроме того, я не уверен, как гарантировать, что проверка нажатия работает правильно, чтобы можно было действительно нажать квадратную кнопку.Stack
или что-то еще, чтобы объединить их в один виджет, но тогда как мне сделать, чтобы этот Stack
действовал как одна кнопка?CustomPaint
, что кажется трудным для получения правильных кривых, особенно потому, что кнопки должны иметь динамический размер, а затем мне придется заново реализовать логику ElevatedButton
, чтобы сделать их нажимаемыми, фокусируемыми и т. д.Как бы вы расположили две кнопки вот так?
Вы можете комбинировать Stack и ShapeBorder для кнопки L.
class LShapeBorder extends OutlinedBorder {
@override
OutlinedBorder copyWith({BorderSide? side}) => this;
@override
ui.Path getInnerPath(ui.Rect rect, {ui.TextDirection? textDirection}) =>
getOuterPath(rect, textDirection: textDirection);
@override
ui.Path getOuterPath(ui.Rect rect, {ui.TextDirection? textDirection}) {
// L shape
final Path path = Path();
final btnW = rect.width / 2 - 10;
// path.moveTo(rect.right - btnW, rect.top);
path.addRRect(
RRect.fromRectAndRadius(
Rect.fromLTRB(rect.right - btnW, rect.top, rect.right, rect.bottom),
const Radius.circular(8),
),
);
path.addRRect(
RRect.fromRectAndRadius(
Rect.fromLTRB(rect.left, rect.bottom - btnW, rect.right, rect.bottom),
const Radius.circular(8),
),
);
path.close();
return path;
}
@override
void paint(ui.Canvas canvas, ui.Rect rect,
{ui.TextDirection? textDirection}) {}
@override
ShapeBorder scale(double t) => this;
}
И вариант использования
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
height: 200,
width: 200,
child: Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
fixedSize: Size.square(100),
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
)),
onPressed: () {
debugPrint('1');
},
child: SizedBox(),
),
),
Positioned.fill(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
shape: LShapeBorder(),
),
onPressed: () {
debugPrint('2');
},
child: SizedBox(),
),
)
],
),
),
),
),
);
}
}
Не знаю на 100%, спрашивали ли вы, как нарисовать полилинию, заполненную произвольным узором, но даже не вам это может пригодиться в некоторых случаях: gist.github.com/pskink/…
Всегда ценю вашу суть @pskink, я часто захожу к вам, чтобы поучиться у вас.
ну, половина из них - "секретные сущности" - недоступны для публики ;-( (кстати вашего ответа: некоторое время назад я добавил суть с произвольной рамкой формы, чтобы вам не приходилось создавать собственную фигуру с нуля ️ 🔁 gist.github.com/pskink/7955c8f7a27a25e70d530648964cf2e5 - в комплекте три примера)
используйте ButtonStyle.shape — в документации сказано: «Форма основного материала кнопки».