Reputation: 760
For my Flutter App I want that four buttons together are a circle. Here an Image of what i kinda want.
I don't know how to style the corners of a button in flutter. In case of button 1 my idea would be to take the upper left corner and set the border radius and leave the other corners normal. With the other buttons I would do the same with the appropriated corners. To arrange my "pizza slices" i would use Colums and Rows. I just don't know and couldn't figure out how to style only one corner.
Thanks for everyone in advance for helping.
Upvotes: 1
Views: 768
Reputation: 412
Hi I do that with Grid View and "Clip R Rec t" enter image description here
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: Container(
height: 120,
width: 120,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisSpacing: 3,
mainAxisSpacing: 3,
crossAxisCount: 2,
children: [
ElevatedButton(
onPressed: () {},
child: Text("1", textAlign: TextAlign.right),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Text("2", textAlign: TextAlign.center),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Text("3", textAlign: TextAlign.center),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Text("4", textAlign: TextAlign.center),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
],
),
),
),
),
),
);
}
}
and you can use Align Widget and put your numbers in align to you have a beautiful UI like this : enter image description here
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: Container(
height: 120,
width: 120,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(0),
crossAxisSpacing: 3,
mainAxisSpacing: 3,
crossAxisCount: 2,
children: [
ElevatedButton(
onPressed: () {},
child: Align(
alignment: Alignment(0.5, 0),
child: Text("1", textAlign: TextAlign.center),
),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Align(
alignment: Alignment(-0.5, 0),
child: Text("2", textAlign: TextAlign.center),
),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Align(
alignment: Alignment(0.5, 0),
child: Text("3", textAlign: TextAlign.center),
),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
ElevatedButton(
onPressed: () {},
child: Align(
alignment: Alignment(-0.5, 0),
child: Text("4", textAlign: TextAlign.center),
),
style: ElevatedButton.styleFrom(
primary: Colors.blueGrey,
),
),
],
),
),
),
),
),
);
}
}
you can compare between images and code and If you liked my answer and it was useful, I will be happy for you to rate my answer. Thank You.
Upvotes: 2
Reputation: 760
Thank you to everyone here! I got an solution based of this Question: [https://stackoverflow.com/questions/53138955/how-can-i-make-a-buttons-corner-only-rounded-on-the-top]
And based of the answer of @fusion
My solution looks like this:
import 'package:flutter/material.dart';
enum QuarterPosition { topLeft, topRight, bottomLeft, bottomRight }
class QuarterButton extends StatelessWidget {
const QuarterButton({Key? key, required this.position, this.size = 100, this.text = ""}) : super(key: key);
final QuarterPosition position;
final double size;
final String text;
BorderRadiusGeometry _generateBorderRadius() {
switch (position) {
case QuarterPosition.topLeft:
return BorderRadius.only(
topLeft: Radius.circular(size),
);
case QuarterPosition.topRight:
return BorderRadius.only(
topRight: Radius.circular(size),
);
case QuarterPosition.bottomLeft:
return BorderRadius.only(
bottomLeft: Radius.circular(size),
);
case QuarterPosition.bottomRight:
return BorderRadius.only(
bottomRight: Radius.circular(size),
);
}
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {},
child: Text(text, style: TextStyle(fontSize: 30, color: Colors.white)),
style: ElevatedButton.styleFrom(
primary: Colors.black54,
fixedSize: Size(size, size),
shape: RoundedRectangleBorder(
borderRadius: _generateBorderRadius(),
),
side: BorderSide(color: Colors.white)),
);
}
}
And I can use it now like that.
Column(
children: [
Row(
children: [
QuarterButton(position: QuarterPosition.topLeft, size: 100, text: "1"),
QuarterButton(position: QuarterPosition.topRight, size: 100, text: "2"),
],
),
Row(
children: [
QuarterButton(position: QuarterPosition.bottomLeft, size: 100, text: "3"),
QuarterButton(position: QuarterPosition.bottomRight, size: 100, text: "4"),
],
),
],
);
Thanks for all the quick answers. Great community! :)
Upvotes: 0
Reputation: 3087
you can do it inside a card like this
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Card(
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(60.0),
),
child: SizedBox(
width: 120,
height: 120,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Row(
children: [
Expanded(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text("1"),
)),
),
Expanded(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text("2"),
)),
)
],
),
),
Expanded(
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text("1"),
)),
),
Expanded(
child: InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text("2"),
)),
)
],
),
)
],
),
),
),
),
));
}
Upvotes: 0
Reputation: 457
One possible solution would be to create a Container with a fixed width and height. Then you set a background color and the border radius with BorderRadius.only for topLeft, topRight etc. Now you only have to create a column with two rows containing your respective containers.
E.g.:
// pizza_button.dart
enum PizzaPosition { topLeft, topRight, bottomLeft, bottomRight }
class PizzaButton extends StatelessWidget {
final PizzaPosition pizzaPosition;
final _buttonSize = 60.0;
const PizzaButton({Key? key, required this.pizzaPosition}) : super(key: key);
BorderRadiusGeometry? _generateBorderRadius() {
switch (pizzaPosition) {
case PizzaPosition.topLeft:
return BorderRadius.only(
topLeft: Radius.circular(_buttonSize),
);
case PizzaPosition.topRight:
return BorderRadius.only(
topRight: Radius.circular(_buttonSize),
);
case PizzaPosition.bottomLeft:
return BorderRadius.only(
bottomLeft: Radius.circular(_buttonSize),
);
case PizzaPosition.bottomRight:
return BorderRadius.only(
bottomRight: Radius.circular(_buttonSize),
);
}
}
@override
Widget build(BuildContext context) {
return Container(
width: _buttonSize,
height: _buttonSize,
margin: EdgeInsets.all(1.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: _generateBorderRadius(),
),
child: Text("1"),
);
}
}
And for the whole "pizza" an example widget would be
class Pizza extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PizzaButton(pizzaPosition: PizzaPosition.topLeft),
PizzaButton(pizzaPosition: PizzaPosition.topRight),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PizzaButton(pizzaPosition: PizzaPosition.bottomLeft),
PizzaButton(pizzaPosition: PizzaPosition.bottomRight),
],
)
],
),
);
}
}
Now to have it work as buttons you should wrap the containers inside PizzaButton in GestureDetectors and specify your action onTap
which can be hold as another property of PizzaButton for example.
Upvotes: 1