#flutter #flutter-layout
#flutter #флаттер-макет #flutter-layout
Вопрос:
Я написал пакет Flutter, который предоставляет кнопки входа для социальных платформ. Вот пример того, как это выглядит:
Я изо всех сил пытаюсь заставить эту кнопку выглядеть красиво, когда родитель заставляет ее растягиваться. Например, поместить эту кнопку в столбец с CrossAxisAlignment.stretch
. Я бы хотел, чтобы значок и текст оставались такими, какие они есть, а свободное пространство «добавлялось» к синему с правой стороны.
Как вы можете видеть из кода, это RaisedButton
с Icon
и Text
, плюс некоторое заполнение (как определено стандартами Google). Он использует Row
с MainAxisSize.min
:
// Code omitted for clarity (see link above for full version)
ButtonTheme(
child: RaisedButton(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(1.0),
child: Container(
height: 38.0,
width: 38.0,
child: Center(
child: Image(...),
height: 18.0,
width: 18.0,
),
),
),
),
SizedBox(width: 14.0),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 8.0, 8.0, 8.0),
child: Text("Sign in with Google"),
),
],
),
),
);
Я попытался добавить Spacer
в строку в качестве последнего виджета, но это приводит к тому, что строка всегда расширяется, чтобы заполнить своего родителя. Вместо этого я хочу, чтобы он заполнял родительский элемент только тогда, когда родитель заставляет это делать.
Есть предложения по решению этой проблемы?
Ответ №1:
Вы можете использовать Align
виджет в качестве родительского элемента вашего RaisedButton
, что-то вроде этого :
child: Align(
alignment: Alignment.centerLeft,
child: RaisedButton(
onPressed: onPressed,
color: darkMode ? Color(0xFF4285F4) : Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
Используя это, ваш Row
не будет расширяться 🙂
или
Используйте LayoutBuilder
, если хотите развернуть кнопку в соответствии с родительским виджетом :
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
return ButtonTheme(
height: 40.0,
padding: const EdgeInsets.all(0.0),
shape: RoundedRectangleBorder(
// Google doesn't specify a border radius, but this looks about right.
borderRadius: BorderRadius.circular(3.0),
),
child: Align(
alignment: Alignment.centerLeft,
child: RaisedButton(
onPressed: onPressed,
color: darkMode ? Color(0xFF4285F4) : Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// The Google design guidelines aren't consistent. The dark mode
// seems to have a perfect square of white around the logo, with a
// thin 1dp (ish) border. However, since the height of the button
// is 40dp and the logo is 18dp, it suggests the bottom and top
// padding is (40 - 18) * 0.5 = 11. That's 10dp once we account for
// the thin border.
//
// The design guidelines suggest 8dp padding to the left of the
// logo, which doesn't allow us to center the image (given the 10dp
// above). Something needs to give - either the 8dp is wrong or the
// 40dp should be 36dp. I've opted to increase left padding to 10dp.
Padding(
padding: const EdgeInsets.all(1.0),
child: Container(
height: 38.0, // 40dp - 2*1dp border
width: 38.0, // matches above
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(3.0),
),
child: Center(
child: Image(
image: AssetImage(
"graphics/google-logo.png",
package: "flutter_auth_buttons",
),
height: 18.0,
width: 18.0,
),
),
),
),
SizedBox(width: 14.0 /* 24.0 - 10dp padding */),
Padding(
padding: const EdgeInsets.fromLTRB(0.0, 8.0, 8.0, 8.0),
child: Text(
text,
style: TextStyle(
fontSize: 18.0,
fontFamily: "Roboto",
fontWeight: FontWeight.w500,
color: darkMode
? Colors.white
: Colors.black.withOpacity(0.54),
),
),
),
constraints.minWidth == 0 ? SizedBox.shrink() : Spacer(),
],
),
),
),
);
},
);
}
Комментарии:
1. Ваш первый ответ у меня не сработал. Но второй сделал 🙂