another commit

This commit is contained in:
kicap1992
2022-06-08 06:03:46 +08:00
commit 330bfdeadb
60 changed files with 9627 additions and 0 deletions

View File

@ -0,0 +1,33 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
class BoxBackgroundDecoration extends StatelessWidget {
final Widget? child;
const BoxBackgroundDecoration({
Key? key,
this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
// decoration gradient
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 199, 214, 234),
Color.fromARGB(255, 104, 164, 164),
Color.fromARGB(255, 4, 103, 103),
Color.fromARGB(255, 2, 72, 72),
],
),
),
child: child,
);
}
}

View File

@ -0,0 +1,166 @@
// ignore_for_file: file_names
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
// import 'package:meta/meta.dart';
///
/// Helper class that ensures a Widget is visible when it has the focus
/// For example, for a TextFormField when the keyboard is displayed
///
/// How to use it:
///
/// In the class that implements the Form,
/// Instantiate a FocusNode
/// FocusNode _focusNode = new FocusNode();
///
/// In the build(BuildContext context), wrap the TextFormField as follows:
///
/// new EnsureVisibleWhenFocused(
/// focusNode: _focusNode,
/// child: new TextFormField(
/// ...
/// focusNode: _focusNode,
/// ),
/// ),
///
/// Initial source code written by Collin Jackson.
/// Extended (see highlighting) to cover the case when the keyboard is dismissed and the
/// user clicks the TextFormField/TextField which still has the focus.
///
class EnsureVisibleWhenFocused extends StatefulWidget {
const EnsureVisibleWhenFocused({
Key? key,
required this.child,
required this.focusNode,
this.curve = Curves.ease,
this.duration = const Duration(milliseconds: 100),
}) : super(key: key);
/// The node we will monitor to determine if the child is focused
final FocusNode focusNode;
/// The child widget that we are wrapping
final Widget child;
/// The curve we will use to scroll ourselves into view.
///
/// Defaults to Curves.ease.
final Curve curve;
/// The duration we will use to scroll ourselves into view
///
/// Defaults to 100 milliseconds.
final Duration duration;
@override
_EnsureVisibleWhenFocusedState createState() =>
_EnsureVisibleWhenFocusedState();
}
///
/// We implement the WidgetsBindingObserver to be notified of any change to the window metrics
///
class _EnsureVisibleWhenFocusedState extends State<EnsureVisibleWhenFocused>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
widget.focusNode.addListener(_ensureVisible);
WidgetsBinding.instance!.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
widget.focusNode.removeListener(_ensureVisible);
super.dispose();
}
///
/// This routine is invoked when the window metrics have changed.
/// This happens when the keyboard is open or dismissed, among others.
/// It is the opportunity to check if the field has the focus
/// and to ensure it is fully visible in the viewport when
/// the keyboard is displayed
///
@override
void didChangeMetrics() {
if (widget.focusNode.hasFocus) {
_ensureVisible();
}
}
///
/// This routine waits for the keyboard to come into view.
/// In order to prevent some issues if the Widget is dismissed in the
/// middle of the loop, we need to check the "mounted" property
///
/// This method was suggested by Peter Yuen (see discussion).
///
Future<void> _keyboardToggled() async {
if (mounted) {
EdgeInsets edgeInsets = MediaQuery.of(context).viewInsets;
while (mounted && MediaQuery.of(context).viewInsets == edgeInsets) {
await Future.delayed(const Duration(milliseconds: 10));
}
}
return;
}
Future<void> _ensureVisible() async {
// Wait for the keyboard to come into view
await Future.any([
Future.delayed(const Duration(milliseconds: 300)),
_keyboardToggled()
]);
// No need to go any further if the node has not the focus
if (!widget.focusNode.hasFocus) {
return;
}
// Find the object which has the focus
final RenderObject? object = context.findRenderObject();
final RenderAbstractViewport? viewport = RenderAbstractViewport.of(object);
// If we are not working in a Scrollable, skip this routine
if (viewport == null) {
return;
}
// Get the Scrollable state (in order to retrieve its offset)
ScrollableState? scrollableState = Scrollable.of(context);
assert(scrollableState != null);
// Get its offset
ScrollPosition position = scrollableState!.position;
double alignment;
if (position.pixels > viewport.getOffsetToReveal(object!, 0.0).offset) {
// Move down to the top of the viewport
alignment = 0.0;
} else if (position.pixels <
viewport.getOffsetToReveal(object, 1.0).offset) {
// Move up to the bottom of the viewport
alignment = 1.0;
} else {
// No scrolling is necessary to reveal the child
return;
}
position.ensureVisible(
object,
alignment: alignment,
duration: widget.duration,
curve: widget.curve,
);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}

View File

@ -0,0 +1,35 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
class OurContainer extends StatelessWidget {
final Widget? child;
const OurContainer({Key? key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
final double left = (MediaQuery.of(context).size.width -
(MediaQuery.of(context).size.width * 0.9)) /
2;
return Container(
width: MediaQuery.of(context).size.width * 0.9,
margin: EdgeInsets.only(left: left, right: left),
padding: const EdgeInsets.only(left: 20, right: 15, bottom: 20, top: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: const [
BoxShadow(
color: Colors.grey,
blurRadius: 10,
spreadRadius: 1,
offset: Offset(
4,
4,
),
),
]),
child: child,
);
}
}

View File

@ -0,0 +1,50 @@
// ignore_for_file: file_names
import 'package:flutter/services.dart';
class ThousandsSeparatorInputFormatter extends TextInputFormatter {
static const separator = ','; // Change this to '.' for other locales
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Short-circuit if the new value is empty
if (newValue.text.isEmpty) {
return newValue.copyWith(text: '');
}
// Handle "deletion" of separator character
String oldValueText = oldValue.text.replaceAll(separator, '');
String newValueText = newValue.text.replaceAll(separator, '');
if (oldValue.text.endsWith(separator) &&
oldValue.text.length == newValue.text.length + 1) {
newValueText = newValueText.substring(0, newValueText.length - 1);
}
// Only process if the old value and new value are different
if (oldValueText != newValueText) {
int selectionIndex =
newValue.text.length - newValue.selection.extentOffset;
final chars = newValueText.split('');
String newString = '';
for (int i = chars.length - 1; i >= 0; i--) {
if ((chars.length - 1 - i) % 3 == 0 && i != chars.length - 1) {
newString = separator + newString;
}
newString = chars[i] + newString;
}
return TextEditingValue(
text: newString.toString(),
selection: TextSelection.collapsed(
offset: newString.length - selectionIndex,
),
);
}
// If the new value and old value are the same, just return as-is
return newValue;
}
}