feat: 首页,收藏页的UI,字体 组件封装
This commit is contained in:
1 parent
f233f1c642
commit
7f329aef44
32 files changed
+1110
-41
No files matched your search
@@ -0,0 +1,101 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CutCornerClipper extends StatelessWidget {
|
||||
|
||||
const CutCornerClipper({super.key,
|
||||
this.width,
|
||||
this.height,
|
||||
this.cutCorner = CutCorner.topRight,
|
||||
this.cutSize,
|
||||
this.child,
|
||||
});
|
||||
|
||||
final double? width;
|
||||
final double? height;
|
||||
final CutCorner cutCorner;
|
||||
final double? cutSize;
|
||||
final Widget? child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipPath(
|
||||
clipper: EqualCutCornerClipper(
|
||||
cutSize: cutSize ?? 35,
|
||||
corner: cutCorner,
|
||||
),
|
||||
child: Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 长方形缺一个角(等边缺角)
|
||||
class EqualCutCornerClipper extends CustomClipper<Path> {
|
||||
final double cutSize; // 缺角两条直角边的长度(相等)
|
||||
final CutCorner corner;
|
||||
|
||||
const EqualCutCornerClipper({
|
||||
this.cutSize = 20,
|
||||
this.corner = CutCorner.topRight,
|
||||
});
|
||||
|
||||
@override
|
||||
Path getClip(Size size) {
|
||||
final path = Path();
|
||||
final w = size.width;
|
||||
final h = size.height;
|
||||
final c = cutSize;
|
||||
|
||||
switch (corner) {
|
||||
case CutCorner.topRight:
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(w - c, 0); // 上边到缺角起点
|
||||
path.lineTo(w, c); // 🔥 45° 斜线(两条边相等)
|
||||
path.lineTo(w, h);
|
||||
path.lineTo(0, h);
|
||||
break;
|
||||
|
||||
case CutCorner.topLeft:
|
||||
path.moveTo(c, 0);
|
||||
path.lineTo(w, 0);
|
||||
path.lineTo(w, h);
|
||||
path.lineTo(0, h);
|
||||
path.lineTo(0, c);
|
||||
break;
|
||||
|
||||
case CutCorner.bottomRight:
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(w, 0);
|
||||
path.lineTo(w, h - c);
|
||||
path.lineTo(w - c, h);
|
||||
path.lineTo(0, h);
|
||||
break;
|
||||
|
||||
case CutCorner.bottomLeft:
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(w, 0);
|
||||
path.lineTo(w, h);
|
||||
path.lineTo(c, h);
|
||||
path.lineTo(0, h - c);
|
||||
break;
|
||||
}
|
||||
path.close();
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
|
||||
if (oldClipper is EqualCutCornerClipper) {
|
||||
return oldClipper.cutSize != cutSize || oldClipper.corner != corner;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
enum CutCorner { topLeft, topRight, bottomLeft, bottomRight }
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:novyronst/root/lib_export.dart';
|
||||
import 'package:novyronst/tools/widgets/novy_com_widget.dart';
|
||||
|
||||
class NyProgressWidget extends StatelessWidget {
|
||||
const NyProgressWidget({super.key,
|
||||
this.progress = 0.4,
|
||||
this.width,
|
||||
});
|
||||
|
||||
final double progress;
|
||||
final double? width;
|
||||
static final double _width = AppScreen.screenWidth - 50;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 14,
|
||||
width: width ?? _width
|
||||
),
|
||||
Positioned(
|
||||
left: 0, right: 0, top: 4.5,
|
||||
child: Container(
|
||||
height: 5,
|
||||
padding: EdgeInsets.symmetric(horizontal: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
borderRadius: BorderRadius.circular(2.5),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: (progress * 100).toInt(),
|
||||
child: _line(),
|
||||
),
|
||||
Expanded(
|
||||
flex: 100 - (progress * 100).toInt(),
|
||||
child: _line(isActive: false),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0, left: (width ?? _width - 50) * progress,
|
||||
child: _pTag(),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container _line({bool isActive = true}) {
|
||||
return Container(
|
||||
height: 2,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? ConstColor.btGreen : ConstColor.btGreen.withAlpha(127),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _pTag() {
|
||||
return Container(
|
||||
height: 14,
|
||||
padding: EdgeInsets.symmetric(horizontal: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: ConstColor.btGreen,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(4),
|
||||
bottomLeft: Radius.circular(4),
|
||||
topRight: Radius.circular(16),
|
||||
bottomRight: Radius.circular(4),
|
||||
)
|
||||
),
|
||||
child: NovyText('${(progress * 100).toInt()}%',
|
||||
fontSize: 10,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:novyronst/common/const/const_color.dart';
|
||||
import 'package:novyronst/common/help/help_image.dart';
|
||||
import 'package:novyronst/tools/widgets/novy_com_widget.dart';
|
||||
|
||||
class NyTagWidget extends StatelessWidget {
|
||||
const NyTagWidget({super.key,
|
||||
required this.text,
|
||||
this.bgColor,
|
||||
this.textColor,
|
||||
});
|
||||
|
||||
final String text;
|
||||
final Color? bgColor;
|
||||
final Color? textColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 20,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor ?? ConstColor.withValue('EEEEEE'),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Center(
|
||||
child: NovyText(text,
|
||||
fontSize: 10,
|
||||
color: textColor ?? ConstColor.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NyHotWidget extends StatelessWidget {
|
||||
const NyHotWidget({super.key,
|
||||
required this.text,
|
||||
});
|
||||
|
||||
final String text;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
HelpImage.asset(ConstImage.hot, width: 12),
|
||||
NovyText(text,
|
||||
fontSize: 10,
|
||||
color: Colors.black,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user