Skip to content

Commit

Permalink
update demo gesture password
Browse files Browse the repository at this point in the history
  • Loading branch information
10456 authored and CarGuo committed Sep 30, 2024
1 parent 23c939b commit eaf40fc
Show file tree
Hide file tree
Showing 8 changed files with 501 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,18 @@ Map<String, WidgetBuilder> routers = {
return un_bounded_listview.UnboundedListViewDemoPage();
});
},
"PageView嵌套PageView": (context) {
return ContainerAsyncRouterPage(
pageview_in_pageview_demo_page.loadLibrary(), (context) {
return pageview_in_pageview_demo_page.PageViewInPageViewDemoPage();
});
},
"手势密码": (context) {
return ContainerAsyncRouterPage(gesture_password_demo_page.loadLibrary(),
(context) {
return gesture_password_demo_page.GesturePasswordDemoPage();
});
},
};
```
Expand Down
9 changes: 9 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ import 'package:gsy_flutter_demo/widget/un_bounded_listview.dart'
import 'package:gsy_flutter_demo/widget/pageview_in_pageview_demo_page.dart'
deferred as pageview_in_pageview_demo_page;

import 'package:gsy_flutter_demo/widget/gesture_password/gesture_password_demo_page.dart'
deferred as gesture_password_demo_page;

import 'package:window_location_href/window_location_href.dart';

void main() => runApp(const MyApp());
Expand Down Expand Up @@ -917,6 +920,12 @@ Map<String, WidgetBuilder> routers = {
return pageview_in_pageview_demo_page.PageViewInPageViewDemoPage();
});
},
"手势密码": (context) {
return ContainerAsyncRouterPage(gesture_password_demo_page.loadLibrary(),
(context) {
return gesture_password_demo_page.GesturePasswordDemoPage();
});
},
};

enum Cat {
Expand Down
44 changes: 44 additions & 0 deletions lib/widget/gesture_password/gesture_password_demo_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:gsy_flutter_demo/widget/gesture_password/gesture_password_view.dart';
import 'package:gsy_flutter_demo/widget/link_sliver/link_flexible_space_bar.dart';

class GesturePasswordDemoPage extends StatefulWidget {
const GesturePasswordDemoPage({super.key});

@override
_GesturePasswordDemoState createState() => _GesturePasswordDemoState();
}

class _GesturePasswordDemoState extends State<GesturePasswordDemoPage> {
String _pwd = '';

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("手势密码"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 300,
child: GesturePasswordView(
pathWidth: 6,
frameRadius: 30,
onDone: (value) {
setState(() {
_pwd = value.join();
});
},
),
),
Text("当前密码: $_pwd"),
],
),
),
);
}
}
87 changes: 87 additions & 0 deletions lib/widget/gesture_password/gesture_password_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import 'package:flutter/material.dart';

import 'src/gesture_view_controller.dart';
import 'src/gesture_view_path.dart';
import 'src/gesture_view_point.dart';

class GesturePasswordView extends StatefulWidget {

/// 圆圈半径
final double frameRadius;

/// 圆圈中心点半径
final double pointRadius;

/// 圆圈普通状态下颜色
final Color color;

/// 圆圈选中颜色
final Color highlightColor;

/// 连线颜色
final Color pathColor;

/// 连线半径
final double pathWidth;

/// 手势结果
final Function(List<int>)? onDone;

const GesturePasswordView({
super.key,
this.pointRadius = 10,
this.frameRadius = 40,
this.color = Colors.grey,
this.highlightColor = Colors.blue,
this.pathColor = Colors.blue,
this.onDone,
this.pathWidth = 5,
});

@override
State<StatefulWidget> createState() => _GesturePasswordState();
}

class _GesturePasswordState extends State<GesturePasswordView> {
final GestureViewController controller = GestureViewController();

@override
void initState() {
controller.initParameters(
pointRadius: widget.pointRadius,
frameRadius: widget.frameRadius,
color: widget.color,
highlightColor: widget.highlightColor,
pathColor: widget.pathColor,
onFinishGesture: widget.onDone,
pathWidth: widget.pathWidth,
updateView: (){
setState(() {});
}
);
WidgetsBinding.instance.addPostFrameCallback((_) => controller.setPointValues());
super.initState();
}

@override
Widget build(BuildContext context) {
return SizedBox(
key: controller.globalKey,
width: double.infinity,
height: double.infinity,
child: Stack(
children: [
GestureDotsPanelWidget(points: controller.point),
GestureViewPathWidget(
points: controller.pathPoint,
pathWidth: controller.pathWidth,
color: controller.pathColor,
onPanDown: controller.onPanDown,
onPanEnd: controller.onPanEnd,
onPanUpdate: controller.onPanUpdate,
),
],
),
);
}
}
141 changes: 141 additions & 0 deletions lib/widget/gesture_password/src/gesture_view_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import 'package:flutter/material.dart';

import 'gesture_view_model.dart';

class GestureViewController {
final List<GesturePasswordPointModel> _points = [];
final List<Offset> _pathPoint = [];
final GlobalKey globalKey = GlobalKey();
double _frameRadius = 0.0;
double _pointRadius = 0.0;
Color _color = Colors.grey;
Color _highlightColor = Colors.blue;
Color _pathColor = Colors.blue;
Function(List<int>)? _onFinishGesture;
double _pathWidth = 5;
Function()? _updateView;
Offset? _firstPoint;
Offset? _movePoint;
List<int> _result = [];
}

extension Data on GestureViewController {
List<GesturePasswordPointModel> get point => _points;

List<Offset> get pathPoint {
List<Offset> tempPathPoint = [];
tempPathPoint.addAll(_pathPoint);
if (_movePoint != null) {
tempPathPoint.add(_movePoint!);
}
return tempPathPoint;
}

Color get pathColor => _pathColor;

double get pathWidth => _pathWidth;

}

extension Private on GestureViewController {
void _initPoint() {
_points.addAll(List.generate(
9,
(index) => GesturePasswordPointModel(
index: index,
frameRadius: _frameRadius,
pointRadius: _pointRadius,
color: _color,
highlightColor: _highlightColor,
pathColor: _pathColor,
),
));
}

double _getPointWidth(double width) => width / 3;
}

extension Public on GestureViewController {
void initParameters({
double frameRadius = 0.0,
double pointRadius = 0.0,
Color color = Colors.grey,
Color highlightColor = Colors.blue,
Color pathColor = Colors.blue,
Function(List<int>)? onFinishGesture,
Function()? updateView,
double pathWidth = 5,
}) {
_frameRadius = frameRadius;
_pointRadius = pointRadius;
_color = color;
_highlightColor = highlightColor;
_pathColor = pathColor;
_onFinishGesture = onFinishGesture;
_updateView = updateView;
_pathWidth = pathWidth;
_initPoint();
}

void setPointValues() {
try {
Size size = globalKey.currentContext?.size ?? Size.zero;
double pointWidth = _getPointWidth(size.width);
List<Offset> pointCenter = [];
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
Offset center = Offset((y - 1) * pointWidth + pointWidth / 2,
(x - 1) * pointWidth + pointWidth / 2);
pointCenter.add(center);
}
}
for (int index = 0; index < pointCenter.length; index++) {
_points[index].centerPoint = pointCenter[index];
}
} catch (_) {}
}
}

extension Tap on GestureViewController {
void onPanDown(DragDownDetails e) {
for (var item in _points) {
if (item.containPoint(e.localPosition)) {
item.selected = true;
_firstPoint = e.localPosition;
_pathPoint.add(item.centerPoint);
_updateView?.call();
_result.add(item.index);
break;
}
}
}

void onPanUpdate(DragUpdateDetails e) {
if (_firstPoint == null) return;
_movePoint = e.localPosition;
for (var item in _points) {
if (item.containPoint(e.localPosition)) {
if (!item.selected) {
item.selected = true;
_pathPoint.add(item.centerPoint);
_result.add(item.index);
}
break;
}
}
_updateView?.call();
}

void onPanEnd(DragEndDetails e) {
_firstPoint = null;
_movePoint = null;

_onFinishGesture?.call(_result);
_result.clear();
for (var element in _points) {
element.selected = false;
}
_pathPoint.clear();
_updateView?.call();
}
}
43 changes: 43 additions & 0 deletions lib/widget/gesture_password/src/gesture_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

import 'dart:math';
import 'package:flutter/material.dart';

class GesturePasswordPointModel {
Offset centerPoint = Offset.zero;
bool selected = false;
double frameRadius;
double pointRadius;
Color color = Colors.grey;
Color highlightColor = Colors.blue;
Color pathColor = Colors.blue;
int index = 0;

GesturePasswordPointModel({
this.index = 0,
this.centerPoint = Offset.zero,
this.frameRadius = 0.0,
this.pointRadius = 0.0,
this.selected = false,
this.color = Colors.grey,
this.highlightColor = Colors.blue,
this.pathColor = Colors.blue,
});


Color get pointColor{
return selected ? highlightColor : color;
}
Color get frameColor => selected ? highlightColor : color;

bool containPoint(Offset offset){
return distanceTo(offset, centerPoint) <= frameRadius;
}


double distanceTo(Offset f1, Offset f2){
var dx= f1.dx - f2.dx;
var dy= f1.dy - f2.dy;
return sqrt(dx * dx + dy * dy);
}

}
Loading

0 comments on commit eaf40fc

Please sign in to comment.