flutter引入公共组件在ListView中不显示问题(全局组件复用问题)

异常问题:
RenderCustomMultiChildLayoutBox object was given an infinite size during layout
子布局没有明确的大小不能使用Scaffold脚手架
公共组件的构建使用如下方式

class LoginWidget extends StatefulWidget {
  @override
  State createState() {
    return _LoginState();
  }
}

class _LoginState extends State {
  final phoneController = TextEditingController();
  final pwdController = TextEditingController();

  @override
  Widget build(BuildContext context) {
  //此处用Container替代scaffold
    return Container(
        child: Container(
            alignment: AlignmentDirectional.center,
            child: Padding(
              padding: EdgeInsets.fromLTRB(30.0, 32.0, 30.0, 0),
              child: Column(
                children: [
                  Image(
                    image: AssetImage("images/course_logo.png"),
                    width: 139,
                    height: 38,
                    fit: BoxFit.contain,
                  ),
                  inputPhone(context),

                  inputPassword(context),

                  loginWidget(context),

                  loginByWX(context),
                ],
              ),
            )),
    );
  }

引入的公共组件widget样例(登录模块)

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:micro_course/bean/LoginMsg.dart';
import 'package:micro_course/utils/HexColor.dart';
import 'package:micro_course/http/DioManger.dart';
import 'package:micro_course/http/APIConfig.dart';
import 'package:micro_course/common/eventbus.dart';
import 'package:fluwx/fluwx.dart' as fluwx;

class LoginWidget extends StatefulWidget {
  @override
  State createState() {
    return _LoginState();
  }
}

class _LoginState extends State {
  final phoneController = TextEditingController();
  final pwdController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Container(
            alignment: AlignmentDirectional.center,
            child: Padding(
              padding: EdgeInsets.fromLTRB(30.0, 32.0, 30.0, 0),
              child: Column(
                children: [
                  Image(
                    image: AssetImage("images/course_logo.png"),
                    width: 139,
                    height: 38,
                    fit: BoxFit.contain,
                  ),
                  inputPhone(context),

                  inputPassword(context),

                  loginWidget(context),

                  loginByWX(context),
                ],
              ),
            )),
    );
  }

  ///手机号模块
  Widget inputPhone(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: 40),
      child: Container(
        height: 50,
        width: 307,
        padding: EdgeInsets.only(left: 10.0),
        alignment: AlignmentDirectional.center,
        decoration: BoxDecoration(
            color: Colors.grey[200], borderRadius: BorderRadius.circular(15)),
        child: TextField(
//          autofocus: true,
          controller: phoneController,
          decoration: InputDecoration(
            hintText: "请输入手机号",
            border: InputBorder.none,
            contentPadding: EdgeInsets.zero,
          ),
          onChanged: (v) {
//                      print("手机号:$v");
          },
        ),
      ),
    );
  }

  /// 密码模块
  Widget inputPassword(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: 20),
      child: Container(
        height: 50,
        width: 307,
        padding: EdgeInsets.only(left: 10.0),
        alignment: AlignmentDirectional.center,
        decoration: BoxDecoration(
            color: Colors.grey[200], borderRadius: BorderRadius.circular(15)),
        child: TextField(
//          autofocus: true,
          controller: pwdController,
          decoration: InputDecoration(
            hintText: "请输入密码",
            border: InputBorder.none,
            contentPadding: EdgeInsets.zero,
          ),
          onChanged: (v) {
//                      print("密码:$v");
          },
        ),
      ),
    );
  }

  /// 手机号登录模块
  Widget loginWidget(BuildContext context) {
    return GestureDetector(
      onTap: () {
        var params = {
          "phone": phoneController.text,
          "password": pwdController.text,
        };
        login(params, context);

//        Scaffold.of(context).showSnackBar(SnackBar(
//          content: Text('点击登录'+phoneController.text),
//        ));
      },
      child: Padding(
        padding: EdgeInsets.fromLTRB(7.5, 0, 7.5, 0),
        child: Container(
          height: 120,
          child: Stack(
            alignment: AlignmentDirectional.center,
            children: [
              Container(
                height: 50,
                width: 307,
                decoration: BoxDecoration(
                  color: Colors.yellow[800],
                  borderRadius: BorderRadius.all(Radius.circular(45)),
                ),
              ),
              Text(
                '登录',
                style: TextStyle(fontSize: 18, color: HexColor('#824E00')),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 微信登录模块
  Widget loginByWX(BuildContext context) {
    return GestureDetector(
      onTap: loginWX,
      child: Container(
//        height: 50,
        alignment: AlignmentDirectional.center,
        child: Padding(
          padding: EdgeInsets.all(2),
          child: Image(
            image: AssetImage("images/send.png"),
            width: 139,
            height: 40,
            fit: BoxFit.contain,
          ),
        ),
      ),
    );
  }

  void login(Map params, BuildContext context) {
    DioManger.getInstance().post(APIConfig.LOGIN, params, null, (data) {
      setState(() {
        print("登录成功:" + data.toString());
        Map jsonMsg = json.decode(data.toString());
        LoginMsg loginMsg = LoginMsg.fromJson(jsonMsg);
        print("json转实体类:" + loginMsg.toString());

        ///更新UI
//            Navigator.pushReplacement(context, MaterialPageRoute(
//                builder: (context) => BottomNavigationWidget(),
//                settings: RouteSettings(
//                arguments:jsonMsg,
//               ),
//            ));
        getUserCourseList(loginMsg);
      });
    }, (error) {
      setState(() {});
      print("登录异常:" + error.toString());
    });
  }

  ///获取用户课程信息
  void getUserCourseList(LoginMsg loginMsg) {
    ///显示指定Map的限定类型
    Map parms = {
      "student_id": loginMsg.data.studentId.toString()
    };
    Map headers = {
      "token": loginMsg.data.loginToken.toString()
    };
    DioManger.getInstance().get(APIConfig.GET_COURSE_LIST, parms, headers,
            (data) {
          print("获取课程列表成功:" + data.toString());

          /// 登录成功发送全局事件
          bus.emit('login', loginMsg);
        }, (error) {
          print("获取课程列表失败:" + error.toString());
        });
  }

  ///微信登录
  void loginWX() {
    print("微信登录");
    fluwx
        .sendAuth(scope: "snsapi_userinfo", state: "wechat_sdk_demo_test")
        .then((data) {
      setState(() {
        print("拉取微信用户信息:" + data.toString());
      });
    }).catchError((e) {
      print('weChatLogin  e  $e');
    });
  }
}

公共组件的引入

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:micro_course/widgets/login.dart';

class CourseScreen extends StatefulWidget {
  @override
  State createState() {
    return _LoginState();
  }
}

class _LoginState extends State {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomPadding: false,
        appBar: AppBar(
          title: Text(
            '选课',
            style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.normal,
                color: Colors.black87),
          ),
          centerTitle: true,
          actions: [
            IconButton(
                icon: Icon(
                  Icons.more_horiz,
                  color: Colors.grey,
                ),
                onPressed: () {
                  Scaffold.of(context)
                      .showSnackBar(SnackBar(content: Text('点击分享')));
                })
          ],
        ),
        body: ListView(
          shrinkWrap: true,///根据子组件的总长度来设置 ListView 的长度
          children: [
            Container(
                alignment: AlignmentDirectional.center,
                child: LoginWidget(),///引入公共登录组件
            ),
          ],
        ));
  }
}

  • 注意:此组件中因为有输入框的原因,在引入的时候公共组件要放在lisetview等滑动列表中,不然键盘弹起的时候会出现布局越界的异常,还有就是上文提到的公共组件中如果没有明确组件的大小,不能使用Scaffold脚手架,要用container等容器来替代。

你可能感兴趣的:(Flutter,listview,公共组件,widget不显示,组件复用)