【问题标题】:Flutter - Button Group style and positionFlutter - 按钮组样式和位置
【发布时间】:2020-04-12 03:47:01
【问题描述】:

我正在尝试创建类似于附加图像的内容。我已经走到这一步了……

     Expanded(
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(32),
              topRight: Radius.circular(32),
            ),
          ),
          child: ButtonTheme(
            child: ButtonBar(
              alignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  onPressed: () => print('hi'),
                  child: Text('Referals'),
                  color: Color(0xff2FBBF0),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.only(
                        bottomLeft: Radius.circular(15.0),
                        topLeft: Radius.circular(15.0)),
                  ),
                ),
                RaisedButton(
                  onPressed: () => print('hii'),
                  child: Text('Stats'),
                  color: Color(0xff2FBBF0),
                ),
                RaisedButton(
                  onPressed: () => print('hiii'),
                  child: Text('Edit Profile'),
                  color: Color(0xff2FBBF0),
                  // color: Colors.white,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.only(
                        bottomRight: Radius.circular(15.0),
                        topRight: Radius.circular(15.0)),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),

但我真的不觉得它会像图片那样。

我还希望按钮组位于容器的顶部。现在他们处于绝对的中心。就像包装在 Center 小部件中一样。

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

检查我创建的ButtonGroup 小部件

import 'package:flutter/material.dart';

class ButtonGroup extends StatelessWidget {
  static const double _radius = 10.0;
  static const double _outerPadding = 2.0;

  final int current;
  final List<String> titles;
  final ValueChanged<int> onTab;
  final Color color;
  final Color secondaryColor;

  const ButtonGroup({
    Key key,
    this.titles,
    this.onTab,
    int current,
    Color color,
    Color secondaryColor,
  })  : assert(titles != null),
        current = current ?? 0,
        color = color ?? Colors.blue,
        secondaryColor = secondaryColor ?? Colors.white,
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Material(
      color: color,
      borderRadius: BorderRadius.circular(_radius),
      child: Padding(
        padding: const EdgeInsets.all(_outerPadding),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(_radius - _outerPadding),
          child: IntrinsicHeight(
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: _buttonList(),
            ),
          ),
        ),
      ),
    );
  }

  List<Widget> _buttonList() {
    final buttons = <Widget>[];
    for (int i = 0; i < titles.length; i++) {
      buttons.add(_button(titles[i], i));
      buttons.add(
        VerticalDivider(
          width: 1.0,
          color: (i == current || i + 1 == current) ? color : secondaryColor,
          thickness: 1.5,
          indent: 5.0,
          endIndent: 5.0,
        ),
      );
    }
    buttons.removeLast();
    return buttons;
  }

  Widget _button(String title, int index) {
    if (index == this.current)
      return _activeButton(title);
    else
      return _inActiveButton(title, index);
  }

  Widget _activeButton(String title) => FlatButton(
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        disabledColor: secondaryColor,
        disabledTextColor: color,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.zero,
        ),
        child: Text(title),
        onPressed: null,
      );

  Widget _inActiveButton(String title, int index) => FlatButton(
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        color: Colors.transparent,
        textColor: Colors.white,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.zero,
        ),
        child: Text(title),
        onPressed: () {
          if (onTab != null) onTab(index);
        },
      );
}

你可以这样使用它

ButtonGroup(
  titles: ["Button1", "Button2", "Button3"],
  current: index,
  color: Colors.blue,
  secondaryColor: Colors.white,
  onTab: (selected) {
    setState(() {
      index = selected;
    });
  },
)

示例:

import 'package:flutter/material.dart';
import 'package:flutter_app_test2/btn_grp.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int current = 0;

  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ButtonGroup(
          titles: ["Button1", "Button2", "Button3", "Button3"],
          current: current,
          onTab: (selected) {
            print(selected);
            setState(() {
              current = selected;
            });
          },
        ),
      ),
    );
  }
}

【讨论】:

  • 感谢您的回答,但是,如何调整文本和边缘之间的边距?
【解决方案2】:

这是完整的代码。我刚刚使用了ContainerRow,因为我发现它更合适,也更容易实现,而且不会让人头疼。 :P

如果你想用 RaisedButton,想办法。

来源:

import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  _DemoState createState() => new _DemoState();
}

class _DemoState extends State<Demo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("DEMO")),
        body: Padding( // used padding just for demo purpose to separate from the appbar and the main content
            padding: EdgeInsets.all(10),
            child: Container(
              alignment: Alignment.topCenter,
              child: Container(
                  height: 60,
                  padding: EdgeInsets.all(3.5),
                  width: MediaQuery.of(context).size.width * 0.9,
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    borderRadius: BorderRadius.all(Radius.circular(15)),
                  ),
                  child: Row(
                    children: <Widget>[
                      Expanded(
                          child: InkWell(
                              onTap: () {},
                              child: Container(
                                alignment: Alignment.center,
                                decoration: BoxDecoration(
                                    color: Colors.white,
                                    borderRadius: BorderRadius.only(
                                        bottomLeft: Radius.circular(12),
                                        topLeft: Radius.circular(12))),
                                child: Text("Referrals",
                                    style: TextStyle(
                                      color: Colors.blue,
                                      fontSize: 17,
                                    )),
                              ))),
                      Expanded(
                          child: InkWell(
                              onTap: () {},
                              child: Container(
                                alignment: Alignment.center,
                                child: Text("Stats",
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 17)),
                              ))),
                      Padding(
                          padding: EdgeInsets.symmetric(vertical: 5),
                          child: Container(color: Colors.white, width: 2)),
                      Expanded(
                          child: InkWell(
                              onTap: () {},
                              child: Container(
                                alignment: Alignment.center,
                                child: Text("Edit Profile",
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 17)),
                              )))
                    ],
                  )),
            )));
  }
}

输出截图:

【讨论】:

  • 这样更好。谢谢。
  • 如果我的回复满足了您的要求,也请点赞。谢谢你。 :)
  • 自从我为ButtonBar 寻求解决方案以来,我接受了第一个答案。但是,我将使用您的代码。谢谢!
【解决方案3】:

尝试在所有 RaisedButton 小部件中添加以下内容:

materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,

buttonPadding: EdgeInsets.all(1), 中的ButtonBar

来源:https://api.flutter.dev/flutter/material/MaterialTapTargetSize-class.html

【讨论】:

  • 什么都不做。
  • 对不起,我忘了添加解决方案的其他部分,答案已更新。
  • 间距问题已修复。非常感谢。你知道如何将按钮浮动到容器顶部吗?
  • 尝试Align 小部件和alignment: Alignment.topCenter
猜你喜欢
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 2023-04-01
  • 2019-11-20
相关资源
最近更新 更多