Мне действительно нужно использовать MediaQuery для всех переменных размера? - PullRequest
0 голосов
/ 12 февраля 2020

Итак, я пришел из веб-фона и, узнав, что в веб-дизайне не очень рекомендуется использовать пиксель в качестве размера для чего-то вроде ширины кнопки и высоты или размера шрифта. Большую часть времени я использую 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: () {},
              ),
            ),
          );
        },
      ),
    );
  }

так что же является лучшим решением? и этот проект в настоящее время по-прежнему предназначен только для портретного смартфона, так что нет никакого плана для размера ландшафта или планшета / рабочего стола.

просто хочу убедиться, что эти приложения выглядят хорошо (нет полицейской строки, как ошибка говоря переполнение на любом виджете) на любом смартфоне, который люди все еще используют.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...