我正在尝试创建这个
我能够在交互时实现接近但线条和曲线中的空间
vise visa
我的代码
class SegmentedControl extends StatefulWidget {
@override
_SegmentedControlState createState() => _SegmentedControlState();
}
class _SegmentedControlState extends State<SegmentedControl> {
bool isSpendingSelected = true;
@override
Widget build(BuildContext context) {
return Container(
width: 300,
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: Colors.grey,
),
),
child: Stack(
children: [
AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
left: isSpendingSelected ? 0 : 150,
child: Container(
width: 150,
height: 50,
decoration: BoxDecoration(
color: const Color(0xFF22303C), // Dark color for selected tab
borderRadius: BorderRadius.circular(25),
),
),
),
Row(
children: [
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
isSpendingSelected = true;
});
},
child: Center(
child: Text(
'Spending',
style: TextStyle(
color: isSpendingSelected ? Colors.white : Colors.grey,
fontWeight: FontWeight.bold,
),
),
),
),
),
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
isSpendingSelected = false;
});
},
child: Center(
child: Text(
'Saving',
style: TextStyle(
color: isSpendingSelected ? Colors.grey : Colors.grey,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
],
),
);
}
}
您可以使用CustomPainter来制作您想要的形状。您可以轻松复制并粘贴代码并在您的应用程序中尝试。
import 'package:flutter/material.dart';
class SpendingSavingPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final double cornerRadius = size.height / 2;
const double gapWidth = 4.0; // Width of the gap between Spending and Saving sections
// Paint for the filled "Spending" section
final paintSpending = Paint()
..color = Colors.teal[800]!
..style = PaintingStyle.fill;
// Paint for the "Saving" section background
final paintSaving = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
// Paint for the border
final paintBorder = Paint()
..color = Colors.teal[800]!
..style = PaintingStyle.stroke
..strokeWidth = 2;
// Draw the entire Saving background
final rRect = RRect.fromLTRBR(
0,
0,
size.width,
size.height,
Radius.circular(cornerRadius),
);
canvas.drawRRect(rRect, paintSaving);
// Draw the Spending section
final spendingWidth = (size.width - gapWidth) / 2;
final spendingRect = Rect.fromLTWH(0, 0, spendingWidth, size.height);
final spendingRRect = RRect.fromRectAndCorners(
spendingRect,
topLeft: Radius.circular(cornerRadius),
bottomLeft: Radius.circular(cornerRadius),
bottomRight: Radius.circular(cornerRadius * 2)
);
canvas.drawRRect(spendingRRect, paintSpending);
// Draw the border with modifications
Path path = Path();
// Start from the top-right corner of the Spending section
path.moveTo(spendingWidth, 1);
// Top side of the Saving section
path.lineTo(size.width - cornerRadius, 1);
path.arcToPoint(
Offset(size.width, cornerRadius),
radius: Radius.circular(cornerRadius),
);
// Right side of the Saving section
path.lineTo(size.width, size.height - cornerRadius);
// Bottom side of the Saving section (shortened)
path.arcToPoint(
Offset(size.width - cornerRadius, size.height - 1),
radius: Radius.circular(cornerRadius),
);
// *****
// Change the number 10 to control the space
// *****
path.lineTo(spendingWidth + gapWidth + 5, size.height - 1); // Shortened bottom
// Draw the border
canvas.drawPath(path, paintBorder);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
class SpendingSavingWidget extends StatelessWidget {
const SpendingSavingWidget({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
child: CustomPaint(
size: const Size(200, 50), // Adjust the size as needed
painter: SpendingSavingPainter(),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Padding(
padding: EdgeInsets.only(left: 20.0),
child: Text(
'Spending',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
Padding(
padding: const EdgeInsets.only(right: 20.0),
child: Text(
'Saving',
style: TextStyle(
color: Colors.teal[400],
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
],
),
),
),
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SpendingSavingWidget(),
],
),
),
),
);
}
}
void main() {
runApp(const MyApp());
}