Расположите виджет относительно центрированного виджета - PullRequest
0 голосов
/ 17 декабря 2018

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

Iне могу понять, как изменить мой макет так, чтобы кнопка не была включена в качестве центрированного элемента, как в настоящее время показано на скриншоте:

Image depicting a mobile login screen. There are text fields for email and password as well as a login button. The elements as a group are all centered within the page

Мой код:

class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Expanded(flex: 2, child: Container()),
            Expanded(
              flex: 8,
              child: Form(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    RoundedTextField(
                      hintText: 'Email',
                      keyboardType: TextInputType.emailAddress,
                      textInputAction: TextInputAction.next,
                    ),
                    Container(
                      height: 12,
                    ),
                    RoundedTextField.password(
                      hintText: 'Password',
                      textInputAction: TextInputAction.go,
                    ),
                    Container(
                      height: 48,
                    ),
                    PrimaryButton(
                      child: Text('Log In'),
                      onPressed: () => print(null),
                    ),
                  ],
                ),
              ),
            ),
            Expanded(flex: 2, child: Container()),
          ]),
    );
  }
}

Я родом из мира разработки под Android, где мы можем просто сделать constrainTopToBottomOf:@id/passwordField, и я не уверен, есть ли действительно аналог в гибкой системе.

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

взломать, но вы можете установить высоту с помощью медиа-запроса:

double _height = MediaQuery.of(context).size.height * .5;

, а затем сделать это:

body: Column(
        children: <Widget>[

          Container(
            height: _height,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                    hintText: 'email@email.com',
                    labelText: 'Email',
                  ),
                ),
              ],
            ),
          ),

          Container(
            height: _height,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                    hintText: 'email@email.com',
                    labelText: 'Email',
                  ),
                ),
                Padding(padding: EdgeInsets.only(top: 48.0)),
                Text('some button'),
              ],
            ),
          ),
        ],
      ),
0 голосов
/ 17 декабря 2018

Распространенным решением для этого варианта использования является столбец с некоторым расширением следующим образом:

Column(
  children: [
    Expanded(),
    someContent,
    Expanded(
      child: someOffsetContent,
    ),
),

Более наглядный пример: (фиолетовый - это расширенный)

enter image description here

Column(
  children: <Widget>[
    Expanded(child: Container(color: Colors.purple)),
    Column(
      children: <Widget>[
        Container(
          height: 42,
          width: double.infinity,
          color: Colors.red,
        ),
        Container(
          height: 42,
          width: double.infinity,
          color: Colors.yellow,
        ),
      ],
    ),
    Expanded(
      child: Container(
        color: Colors.purple,
        alignment: Alignment.topCenter,
        padding: const EdgeInsets.only(top: 48),
        child: Container(
          color: Colors.red,
          height: 42.0,
          width: double.infinity,
        ),
      ),
    )
  ],
)
0 голосов
/ 17 декабря 2018

Самое простое решение - поддерживать симметрию с помощью кнопки, которая не отображается и не используется:

class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Expanded(flex: 2, child: Container()),
            Expanded(
              flex: 8,
              child: Form(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Opacity(
                      opacity: 0.0,
                      child: RaisedButton(
                        child: Text(''),
                        onPressed: null,
                      ),
                    ),
                    Container(
                      height: 12,
                    ),
                    TextField(
                      decoration: InputDecoration(hintText: 'Email'),
                      keyboardType: TextInputType.emailAddress,
                      textInputAction: TextInputAction.next,
                    ),
                    Container(
                      height: 12,
                    ),
                    TextField(
                      decoration: InputDecoration(hintText: 'Password'),
                      textInputAction: TextInputAction.go,
                    ),
                    Container(
                      height: 48,
                    ),
                    RaisedButton(
                      child: Text('Log In'),
                      onPressed: () => print(null),
                    ),
                  ],
                ),
              ),
            ),
            Expanded(flex: 2, child: Container()),
          ]),
    );
  }
}
...