我已经尝试了许多不同的方法来使小部件排列在一起,但是我很陌生,无法轻松制作支架。我希望我的屏幕看起来像这样。 我确实在努力使相对于其他事物的对齐,例如将2个textview放在图标下方,并使事物相对于页面对齐。我的颤抖代码也很糟糕,所以我放它毫无意义。任何帮助表示赞赏,谢谢!
检查此
import 'package:flutter/material.dart';
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
bool _obscureText = true;
bool _isChecked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 85,
height: 85,
decoration: BoxDecoration(
color: Colors.blue[900],
borderRadius: BorderRadius.circular(30)),
),
Icon(
Icons.settings,
color: Colors.grey,
size: 40,
)
],
),
SizedBox(
height: 10,
),
Text(
"Highlands Latin School",
style: TextStyle(fontSize: 25, color: Colors.blue[900]),
),
SizedBox(
height: 10,
),
Text(
"Canvas Grades",
style: TextStyle(color: Colors.grey[700], fontSize: 18),
),
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "Email",
border: OutlineInputBorder()
),
),
SizedBox(height: 10,),
TextField(
obscureText: _obscureText,
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(_obscureText ? Icons.visibility_off: Icons.visibility),
onPressed: (){
setState(() {
_obscureText = !_obscureText;
});
},
)
),
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Checkbox(
value: _isChecked,
onChanged: (value){
setState(() {
_isChecked = !_isChecked;
});
},
),
Text(
"SAVE LOGIN?"
)
],
),
Container(
height: 30,
width: 1,
color: Colors.grey,
),
GestureDetector(
onTap: (){},
child: Text(
"FORGOT PASSWORD?"
),
)
],
)
],
),
],
),
SizedBox(
width: double.infinity,
child: RaisedButton(
child: Text(
"Login",
style: TextStyle(
color: Colors.white,
fontSize: 18
),
),
padding: EdgeInsets.all(15),
color: Colors.blue[900],
onPressed: (){
},
),
)
],
),
),
),
);
}
}
希望对您有帮助。
我在这里做了一个。您可以在此箭中签出代码:http://dartpad.dev/8ea752f0b6bec0388b8e478d0ac8eb22
我做出了响应,然后将其放入容器中以模拟电话设备。您可以直接在代码中调整宽度和高度,以在不同尺寸的手机上查看。 (但是,在最终版本中,您希望使用MediaQuery来获取该数据)
它需要重构,但是我想将其保存在一个文件中以便将其放入dartpad。
我知道一开始要做这些布局有点不知所措,所以分步进行总是更好。基本上,这就是我处理大多数布局的方式:1.定义较小的区域:我在代码中定义了这些区域并将它们放入堆栈中:齿轮,波峰,标题栏,输入栏和登录按钮2.找出可以用于每个小部件的小部件...,并注意列内的行和行内的列。3.放置小部件。这可以通过我在本代码中使用的堆栈中的精确定位,也可以通过在小部件周围放置填充来实现
这里是完整的代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
var width = 350.0; // <-- play with these numbers
var height = 700.0; // <-- to see it on different sized devices
class _MyHomePageState extends State<MyHomePage> {
bool trueFalse;
initState() {
trueFalse = true;
super.initState();
}
@override
Widget build(BuildContext context) {
// width = MediaQuery.of(context).size.width; <-- this is where you would
// height = MediaQuery.of(context).size.height; <-- get the real width/height
print(trueFalse);
return Center(
child: Container(
width: width,
height: height,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(25.0),
child: AppBar(backgroundColor: Colors.grey[850])),
body: Stack(
children: [
Positioned(
// THIS IS THE SETTINGS COG
right: width * 0.02,
top: height * 0.03,
child: Icon(
Icons.settings,
color: Colors.grey,
size: width * 0.1,
),
),
Positioned(
// THIS IS THE CREST AND BACKGROUND
left: width * 0.05,
top: height * 0.05,
child: Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Image(
image: NetworkImage(
'http://highlandslatin.org/wp-content/uploads/2016/12/Monogram-white.png'))),
width: width * 0.20,
height: width * 0.20,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(25),
),
)),
Positioned(
// THIS IS THE HIGHLANDS UPPER TEXT
left: width * 0.05,
top: height * 0.17,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Highlands Latin School",
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.bold)),
Container(height: 8),
Text("Canvas Grades",
style: TextStyle(
fontSize: 13, fontWeight: FontWeight.bold))
],
),
),
Column(
// THIS IS THE LOGIN AREA
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: width * 0.05),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email'))),
Container(height: 10),
Padding(
padding: EdgeInsets.symmetric(horizontal: width * 0.05),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password'))),
Container(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding:
EdgeInsets.fromLTRB(width * 0.01, 0, 0, 0),
child: Container(
child: Row(children: [
Checkbox(
value: trueFalse,
onChanged: (bool value) {
setState(() {
trueFalse =
value; // trueFalse?false:true;
});
print("check mark changed");
print(value);
},
),
Padding(
padding: EdgeInsets.fromLTRB(1, 0, 0, 0),
child: Text("Save Login?")),
]),
)),
Padding(
padding: EdgeInsets.symmetric(
horizontal: width * 0.05),
child: Text("Forgot Password")),
])
]),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, width * 0.05),
child: Container(
width: width - 2 * width * 0.05,
child: FlatButton(
color: Colors.grey[850],
textColor: Colors.white,
padding: EdgeInsets.symmetric(
vertical: 11.0, horizontal: width * 0.05),
splashColor: Colors.blue,
onPressed: () {
print("button pressed");
},
child: Text(
"Login",
style: TextStyle(fontSize: 20.0),
),
),
),
),
)
],
),
),
),
);
}
}