Итак, я пришел из веб-фона и, узнав, что в веб-дизайне не очень рекомендуется использовать пиксель в качестве размера для чего-то вроде ширины кнопки и высоты или размера шрифта. Большую часть времени я использую em.
Сейчас во флаттере я не совсем уверен, что использовать, поэтому я использую это
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
и для всего, что нужно для определения размера, тогда я просто использую эти переменные и время его с некоторым числом, чтобы соответствовать желаемому размеру или положению.
и я также использую layoutbuilder для обработки дочернего виджета внутри родительского виджета (например, текста и кнопки внутри виджета карты), чтобы убедиться, что он будет соответственно измените масштаб, просто указав высоту и ширину контейнера.
, но в процессе, потому что я также повторно использую свой виджет и в разных местах, мне трудно убедиться, что виджет имеет правильный размер во всех местах ,
возьмите пример этой карты, на которой показано изображение пользователя с именем и другой информацией
class UserCard extends StatelessWidget {
final User user;
final VoidCallback onTap;
final double containerWidth;
final double containerHeight;
final bool isWithCard;
const UserCard({
Key key,
@required this.user,
@required this.onTap,
@required this.containerWidth,
@required this.containerHeight,
this.isWithCard = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: isWithCard
? Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(containerHeight * 0.2),
),
child: Container(
width: containerWidth,
height: containerHeight * 1.4,
child: LayoutBuilder(
builder: (ctx, constraints) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: containerWidth * 0.03),
_boxesImage(constraints, user),
Expanded(
child: _boxesText(constraints, user, containerHeight),
),
],
);
},
),
),
)
: Container(
width: containerWidth,
height: containerHeight * 1.4,
child: LayoutBuilder(
builder: (ctx, constraints) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_boxesImage(constraints, user),
Expanded(
child: _boxesText(constraints, user, containerHeight),
),
],
);
},
),
),
);
}
Widget _boxesImage(BoxConstraints constraints, User user) {
if (user.photoUrl == null) {
return Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxHeight * 0.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(width: 3, color: Colors.red),
image: DecorationImage(
image: AssetImage('assets/images/logoB.png'),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
);
} else {
return Container(
height: constraints.maxHeight * 0.5,
width: constraints.maxHeight * 0.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(width: 3, color: Colors.red),
image: DecorationImage(
image: NetworkImage(user.photoUrl),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
);
}
}
Widget _boxesText(
BoxConstraints constraints, User user, double containerHeight) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
child: LayoutBuilder(
builder: (ctx, constraints) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
user.nama,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.black87,
fontSize: containerHeight * 0.25,
fontWeight: FontWeight.bold,
),
),
),
Divider(height: containerHeight * 0.15),
Align(
alignment: Alignment.centerLeft,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
FontAwesomeIcons.mobileAlt,
color: Colors.grey,
size: containerHeight * 0.18,
),
SizedBox(width: 5),
Text(
_checkNullText(user.hp),
style: TextStyle(
color: Colors.grey,
fontSize: containerHeight * 0.18,
),
),
],
),
SizedBox(height: containerHeight * 0.07),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
FontAwesomeIcons.car,
color: Colors.grey,
size: containerHeight * 0.18,
),
SizedBox(width: 5),
Text(
_checkNullText(user.noPlat),
style: TextStyle(
color: Colors.grey,
fontSize: containerHeight * 0.18,
),
),
],
),
],
),
),
],
);
},
),
),
);
}
String _checkNullText(String value) {
return value != null ? value : '-';
}
}
Я использую layoutbuilder и каждый раз, когда я вызываю этот виджет, мне просто нужно определить screenHeight и screenWidth от mediaquery
Widget build(BuildContext context) {
final database = Provider.of<Database>(context);
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Text(tipe.toUpperCase()),
),
body: StreamBuilder<List<User>>(
stream: database.userStreamWhere(tipe),
builder: (context, snapshot) {
return ListItemsBuilder<User>(
snapshot: snapshot,
itemBuilder: (context, user) => Padding(
padding: const EdgeInsets.all(8.0),
child: UserCard(
containerHeight: screenHeight * 0.1,
containerWidth: screenWidth,
user: user,
onTap: () {},
),
),
);
},
),
);
}
так что же является лучшим решением? и этот проект в настоящее время по-прежнему предназначен только для портретного смартфона, так что нет никакого плана для размера ландшафта или планшета / рабочего стола.
просто хочу убедиться, что эти приложения выглядят хорошо (нет полицейской строки, как ошибка говоря переполнение на любом виджете) на любом смартфоне, который люди все еще используют.