项目快完成了,来了个加水印的需求。。。
到 pub.dev 上看了下,SDK 要求 Flutter 2 版本,但是我用的是 1.x.x
那就自己写
关键:
- 使用 mixin,不用过多修改现有的页面
- 使用 Stack 和 Positon,画出水印层
- 水印层一定是用户看到的最上层,所以是 Stack 的 children 中的最后一个 widget
- 水印层是 Stack 的 children 中的最后一个 widget,导致真正要操作的 widget 没能获得手势事件
- 水印层外包裹 IgnorePointer,忽略事件(本来往事件穿透方向去想,但是事件穿透更多是父子关系中)
代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
mixin WaterMarkerMixin<T extends StatefulWidget> on State<T> {
Widget draw({
String text = "water marker",
@required Widget child,
int countPerLine = 3,
Matrix4 transform,
TextStyle style = const TextStyle(
color: Color(0xFFE3E3E3),
fontSize: 14,
decoration: TextDecoration.none,
),
}) {
return Stack(children: [
child,
Positioned(
left: 0,
right: 0,
top: 0,
bottom: 0,
child: IgnorePointer(
child: _buildMarkers(
text: text,
style: style,
countPerLine: countPerLine,
transform: transform,
),
),
),
]);
}
Widget _buildMarkers({
@required String text,
TextStyle style,
int countPerLine,
Matrix4 transform,
}) {
double itemWidth = MediaQuery.of(context).size.width / countPerLine;
/// 几行 可以 + 1
int lineCount = (MediaQuery.of(context).size.height / itemWidth).round();
List<Widget> children = List.filled(
lineCount * countPerLine,
Container(
child: new Transform(
alignment: Alignment.center,
transform: transform ?? Matrix4.skewY(0.3), //沿Y轴倾斜0.3弧度
child: Center(
child: Text(
text,
style: style,
textAlign: TextAlign.center,
),
),
),
),
);
return GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: countPerLine,
// crossAxisSpacing: 3,
// mainAxisSpacing: 3,
),
physics: NeverScrollableScrollPhysics(),
children: children,
);
}
}
使用
class TestPage extends StatefulWidget {
const TestPage({Key key}) : super(key: key);
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> with WaterMarkerMixin {
@override
Widget build(BuildContext context) {
return super.draw(child: Text('test page'));
}
}