Flutter 意见输入框

2021-03-02 14:32:57 浏览数 (1)

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);

          },
        );
      });
}

0 人点赞