Screenshot_1612840493.png
要实现一个这样对话框。难点是什么?
难点
自定义一个Widget 继承Dialog
代码语言:javascript复制class SongSheetIntroduceDialog extends Dialog
在我们输入文本之后下面的输入字数会变,可能马上你会想到使用setState不就完了嘛!....可是Dialog 并没有setState方法
我想到的解决办法就是输入文本框单独提取出来继承StatefulWidget 这样就可以使用setState方法来更新了。
不多说了分享一下代码。分享使人快乐!!!!
代码语言:javascript复制import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:toofoo/common/color/colorsUtil.dart';
import 'package:toofoo/common/screenAdaper/ScreenAdaper.dart';
import 'introduce_input.dart';
typedef CancelCallback = void Function();
typedef OkCallback = void Function(String inputTxt);
// ignore: must_be_immutable
class SongSheetIntroduceDialog extends Dialog {
final CancelCallback cancelCallback;
final OkCallback okCallback;
String inputText = '';
SongSheetIntroduceDialog({Key key, this.cancelCallback, this.okCallback}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(53),
child: Material(
type: MaterialType.transparency,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
decoration: ShapeDecoration(
color: Color(0xFFFFFFFF),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
))),
child: Column(
children: [
Padding(
padding: EdgeInsets.fromLTRB(10, 19, 10, 10),
child: Text(
'歌单描述',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.sp(32),
color: ColorsUtil.hexStringColor('#111E36')),
maxLines: 1,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InputWidget(
placeholder: '对歌单进行描述',
onChanged: (String txt){
inputText = txt;
},
),
_buttonWidget()
],
)
],
),
),
],
),
),
);
}
Widget _buttonWidget() {
return Container(
margin: EdgeInsets.only(top: 10, bottom: 18),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FlatButton(
padding: EdgeInsets.all(2),
// 水波纹颜色
colorBrightness: Brightness.light,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(18)),
side: BorderSide(
color: Color(0xFFFFFFFF),
style: BorderStyle.solid,
width: 1)),
clipBehavior: Clip.antiAlias,
onPressed: () {
print('----');
cancelCallback();
},
child: Container(
alignment: Alignment.center,
width: 102,
height: 35,
decoration: BoxDecoration(
border: Border.all(
color: ColorsUtil.hexStringColor('#EEEEEE'), width: 1),
borderRadius: BorderRadius.circular((18.0))),
child: Text(
'取消',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.sp(28),
color: ColorsUtil.hexStringColor('#666D7F')),
maxLines: 1,
),
),
),
SizedBox(
width: 10,
),
FlatButton(
padding: EdgeInsets.all(4),
// 水波纹颜色
colorBrightness: Brightness.light,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(18)),
side: BorderSide(
color: Color(0xFFFFFFFF),
style: BorderStyle.solid,
width: 1)),
clipBehavior: Clip.antiAlias,
onPressed: () {
print('----');
okCallback(inputText);
},
child: Container(
alignment: Alignment.center,
width: 102,
height: 35,
decoration: BoxDecoration(
color: ColorsUtil.hexStringColor('#EC1B23'),
borderRadius: BorderRadius.circular((18.0))),
child: Text(
'完成',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.sp(28),
color: ColorsUtil.hexStringColor('#FFFFFF')),
maxLines: 1,
),
),
)
],
),
);
}
}
输入框部分
代码语言:javascript复制import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/screenutil.dart';
import 'package:toofoo/common/base_component/base_image.dart';
import 'package:toofoo/common/base_component/base_text.dart';
import 'package:toofoo/common/divider/custom_divider.dart';
import 'package:toofoo/common/toast/toast_util.dart';
import 'package:toofoo/views/control_module/song_order_page/model/EquipmentLineReserve.dart';
import 'package:toofoo/views/disccover_module/song_sheet_detail/model/SongMoreDialogModel.dart';
import 'package:toofoo/views/disccover_module/song_sheet_detail/model/UserCollectionTrackIceDTO.dart';
import '../state.dart';
typedef OnChanged = void Function(String txt);
class InputWidget extends StatefulWidget {
const InputWidget({
this.placeholder='请输入',
this.onChanged,
this.maxLength = 100,
this.maxLines = 10,
});
final String placeholder;
final OnChanged onChanged;
final int maxLength;
final int maxLines;
@override
_InputWidgetState createState() => _InputWidgetState();
}
class _InputWidgetState extends State<InputWidget> {
String result = '';
@override
Widget build(BuildContext context) {
return _textInput();
}
Widget _textInput() {
return Stack(
alignment: AlignmentDirectional.bottomEnd,
children: [
Container(
height: 136,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(4.0),
),
border: Border.all(color: Color(0xFFDEDEDE)),
),
alignment: AlignmentDirectional.topStart,
margin: EdgeInsets.only(bottom: 10,left: 10,right: 10),
child: CupertinoTextField(
placeholder: widget.placeholder,
style: TextStyle(fontSize: 15, color: Colors.black),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2)),
),
maxLines: widget.maxLines,
maxLength: widget.maxLength,
textInputAction: TextInputAction.unspecified,
onChanged: (str) {
setState(() {
result = str;
if(widget.onChanged != null){
widget.onChanged(str);
}
});
},
),
),
Container(
margin: EdgeInsets.only(bottom: 25, right: 20),
child: Text(
result.length.toString() '/' widget.maxLength.toString(),
style: TextStyle(color: Colors.grey),
),
)
],
);
}
}
使用
代码语言:javascript复制void _showSongSheetIntroduceDialog(BuildContext context, Dispatch dispatch) {
showDialog(
context: context,
builder: (context) {
return SongSheetIntroduceDialog(
cancelCallback: () {
Navigator.pop(context);
},
okCallback: (String inputTxt) {
Navigator.pop(context);
},
);
});
}