flutter - 如何在颤动中像给定图像一样构建自定义 OTP 屏幕
问题描述
我正在尝试构建如下图所示的 OTP 屏幕,但无法准确构建图像。appLogo 应该在 TopCenter 和 Submit 按钮应该在 BottomCenter ,OTP 元素应该在屏幕的中心,OtpBox 应该像图像中的一样,有 1 个限制字符。
我试图像它一样构建但无法构建:
我的代码:
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height/4.5,
width: MediaQuery.of(context).size.width/2.5,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/TriggerTrackerIcons/splash_logo@3x.png'),
)
),
),
SizedBox(height: 50,),
Container(
alignment: Alignment.centerLeft,
child: Text("Enter OTP:", style:TextStyle(fontWeight:FontWeight.bold, fontSize: 20, color: Colors.orange))
),
SizedBox(height: 8,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
otpBoxBuilder(),
SizedBox(width: 5,),
otpBoxBuilder(),
SizedBox(width: 5,),
otpBoxBuilder(),
SizedBox(width: 5,),
otpBoxBuilder(),
],
),
SizedBox(height: 50,),
InkWell(
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height/15,
color: Colors.orangeAccent,
child: Text("Submit", style:TextStyle(fontWeight:FontWeight.bold, fontSize: 20, color: Colors.white)),
),
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>HomePage()));
},
),
],
),
),
),
),
);
OTP 盒制造商:
Widget otpBoxBuilder(){
return Container(
alignment: Alignment.center,
height: 70,
width: 70,
child: TextField(
keyboardType: TextInputType.number,
maxLength: 1,
decoration: InputDecoration(
border: InputBorder.none
),
),
decoration: BoxDecoration(
border: Border.all(color: Colors.blue)
),
);
}
解决方案
你做对了,但需要一些调整和修改才能实现预期的 UI,
不要将所有内容都包裹在SingleChildScrollView
. 它将使整个屏幕可滚动。
Expanded
一起使用并Column
实现Container
您所需要的。请参阅下面的代码片段。
Widget _body(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: _topLayout(context),
),
_bottomButton(context)
],
);
}
Widget _boxWithLable(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(
height: 20,
),
Container(
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 25),
alignment: Alignment.centerLeft,
child: Text("Boxes:",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.orange))),
_boxBuilder()
],
);
}
Widget _boxBuilder() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_box(),
_box(),
_box(),
_box(),
],
);
}
Widget _box() {
return Container(
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 3),
alignment: Alignment.center,
height: 50,
width: 50,
child: TextField(
keyboardType: TextInputType.number,
maxLength: 1,
decoration: InputDecoration(border: InputBorder.none, counterText: ''),
),
decoration: BoxDecoration(border: Border.all(color: Colors.blue)),
);
}
Widget _headerImage() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Image.asset(
"assets/someimage.png",
fit: BoxFit.cover,
height: 160,
),
);
}
Widget _bottomButton(BuildContext context) {
return Container(
alignment: Alignment.topCenter,
child: Column(
children: <Widget>[
RaisedButton(
onPressed: () {
print('clicked');
},
child: Text('Submit'),
),
SizedBox(
height: 20,
),
],
),
);
}
Widget _topLayout(BuildContext context) {
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[_headerImage(), _boxWithLable(context)],
),
);
}
现在调用_body
内部构建方法
Scaffold(
appBar: 'OTP',
body: _body(context),
)
尝试让我知道它是否适合您。
推荐阅读
- objective-c - 使用 NSInputStream 从文件中读取数字
- r - 在 R 数据框中分组和粘贴重复的行(从长到宽)
- postgresql - 在 SQL 中使用两个时间戳列在“point-in_time”生成计数
- html - 图像不会使用 localhost 显示
- c++ - 如何从调试控制台中删除额外的细节?
- javascript - 如何在没有 nodeJs 的情况下在 javascript 文件中加载反应
- vue.js - 在运行时更改 Vuetify 2 中主题的主要文本颜色
- google-cloud-platform - 如何修复 google-cloud-platform 计算实例上的 mysql 访问被拒绝
- mysql - 如何在 mysql 5.7 中使用“OR”编码访问 5000 万条记录
- amazon-web-services - 如何在 CLI 中获取 ec2 实例状态?