123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- import 'package:flutter/material.dart';
- /// 全屏输入框
- class VFullViewInput extends StatefulWidget {
- /// 初始值
- final String? value;
- /// 占位文本
- final String? placeholder;
- /// 值变更事件
- final ValueChanged<String>? onChanged;
- /// 是否可清除(一键)
- final bool? clearable;
- /// 前缀
- final Widget? prefix;
- /// 后缀
- final Widget? suffix;
- /// 字号
- final double? fontSize;
- const VFullViewInput({
- super.key,
- this.value,
- this.placeholder,
- this.onChanged,
- this.clearable,
- this.prefix,
- this.suffix,
- this.fontSize,
- });
- @override
- State<StatefulWidget> createState() => _InputState();
- }
- class _InputState extends State<VFullViewInput> {
- late String value;
- late final double fontSize;
- @override
- void initState() {
- fontSize = widget.fontSize ?? 20;
- value = widget.value ?? "";
- super.initState();
- }
- @override
- Widget build(BuildContext context) {
- return LayoutBuilder(
- builder: (_, c) {
- final height = c.maxHeight;
- final borderRadius = height / 2;
- final border = OutlineInputBorder(
- borderRadius: BorderRadius.all(Radius.circular(borderRadius)),
- borderSide: BorderSide.none,
- );
- final suffix = _buildSuffix();
- return SizedBox(
- height: height,
- child: TextField(
- controller: TextEditingController(text: value),
- readOnly: true,
- style: TextStyle(fontSize: fontSize),
- decoration: InputDecoration(
- border: border,
- enabledBorder: border,
- focusedBorder: border,
- filled: true,
- fillColor: Colors.grey.shade300,
- contentPadding: EdgeInsets.symmetric(
- vertical: (height - fontSize * 1.2) / 2,
- horizontal: borderRadius,
- ),
- hintStyle: TextStyle(fontSize: fontSize),
- labelStyle: TextStyle(fontSize: fontSize),
- hintText: widget.placeholder,
- prefixIcon: widget.prefix,
- suffixIcon: suffix != null
- ? Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- suffix,
- SizedBox(width: borderRadius / 4),
- ],
- )
- : null,
- isCollapsed: true,
- ),
- onTap: () {
- _onTap(height);
- },
- ),
- );
- },
- );
- }
- void _onTap(double height) async {
- final result = await Navigator.of(context).push<String>(
- MaterialPageRoute(
- fullscreenDialog: true,
- builder: (context) {
- return _InputDialog(
- height: height,
- fontSize: fontSize,
- title: widget.placeholder ?? "请输入",
- value: value,
- );
- },
- ),
- );
- if (result != null) {
- setState(() {
- value = result;
- widget.onChanged?.call(value);
- });
- }
- }
- Widget? _buildSuffix() {
- if (widget.suffix != null) {
- return widget.suffix;
- }
- if (widget.clearable == true && value.isNotEmpty) {
- return IconButton(
- icon: Icon(
- Icons.close,
- size: fontSize * 1.2,
- color: Colors.grey,
- ),
- onPressed: () {
- setState(() {
- value = "";
- widget.onChanged?.call(value);
- });
- },
- );
- }
- return null;
- }
- }
- class _InputDialog extends StatelessWidget {
- late final _controller = TextEditingController(text: value);
- final String value;
- final String title;
- final double fontSize;
- final double height;
- _InputDialog({
- super.key,
- required this.value,
- required this.title,
- required this.fontSize,
- required this.height,
- });
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(title),
- titleTextStyle: TextStyle(color: Colors.grey.shade700, fontSize: 20),
- centerTitle: true,
- leading: IconButton(
- icon: const Icon(Icons.arrow_back, size: 28),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ),
- actions: [
- IconButton(
- icon: const Icon(Icons.check, size: 28),
- onPressed: () {
- _onCompleted(context);
- },
- )
- ],
- ),
- body: Container(
- alignment: Alignment.topCenter,
- padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
- child: SizedBox(
- height: height,
- child: _buildInput(context),
- ),
- ),
- );
- }
- Widget _buildInput(BuildContext context) {
- final borderRadius = height / 2;
- return TextField(
- autofocus: true,
- controller: _controller,
- style: TextStyle(fontSize: fontSize),
- decoration: InputDecoration(
- filled: true,
- fillColor: Colors.grey.shade300,
- focusedBorder: OutlineInputBorder(
- borderRadius: BorderRadius.circular(borderRadius),
- // borderSide: BorderSide(color: Theme.of(context).primaryColor),
- borderSide: BorderSide.none,
- ),
- contentPadding: EdgeInsets.symmetric(
- vertical: (height - fontSize * 1.2) / 2,
- horizontal: borderRadius,
- ),
- hintStyle: TextStyle(fontSize: fontSize),
- labelStyle: TextStyle(fontSize: fontSize),
- ),
- onEditingComplete: () {
- _onCompleted(context);
- },
- onChanged: (value) {
- _controller.text = value;
- },
- );
- }
- void _onCompleted(BuildContext context) {
- Navigator.of(context).pop(_controller.text);
- }
- }
|