简体   繁体   中英

Flutter: How to make a button like this?

I tried to use TextButton.Icon to make the effect as following. But I found that the words can only be at the left or right of the icon. How can I put the words under the icon like this?

在此处输入图像描述

  1. the simplest way to create such things is to use column and row widget properly.
  2. i added a full code with the screenshot check it below [1]: https://i.stack.imgur.com/hRzy9.png
  3. created a reusable widget for icon with button and added it in my main class ie test class
class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            const SizedBox(height: 10,),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                IconWithTextButton(icon:const Icon(Icons.lock, color: Colors.red,),text: "Lock",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.alarm, color: Colors.amber),text: "Alarm",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.call, color: Colors.green),text: "call",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.wrong_location_sharp, color: Colors.greenAccent),text: "location",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.add, color: Colors.tealAccent),text: "Add",onClicked: (){},),
              ],
            ),
            const SizedBox(height: 20,),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                IconWithTextButton(icon: const Icon(Icons.lock, color: Colors.red,),text: "Lock",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.alarm, color: Colors.amber),text: "Alarm",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.call, color: Colors.green),text: "call",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.wrong_location_sharp, color: Colors.greenAccent),text: "location",onClicked: (){},),
                IconWithTextButton(icon:const Icon(Icons.add, color: Colors.tealAccent),text: "Add",onClicked: (){},),
              ],
            )
          ],
        ),
      ),
    );
  }
}
  1. this is reusable widget with reusable text, reusable onclick and reusable icon
class IconWithTextButton extends StatelessWidget {
  String text;
  Icon icon;
  VoidCallback onClicked;
  IconWithTextButton({Key? key, required this.text, required this.onClicked, required this.icon}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onClicked,
      child: Container(
        child: Column(
          children: [
            icon,
            const SizedBox(height: 10,),
            Text(text),
          ],
        ),
      ),
    );
  }
}


 

You can use Column Widget and populate its children with Icon and TextField. Then Wrap the whole widget with GestureDetector for on pressed functionality. You can also wrap it with InkWell and Material to get splash effect like in other buttons.

You need not wrap with column.

TextButton(
        onPressed:(){},
        child: Column(
          children: [
            Icon(Icons.play_arrow,color:Colors.green),
            Text(
              'Hello',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),

I think GirdView Widget the best way to make button like this-

GridView.count(
    crossAxisCount: 4,
    children:  List<Widget>.generate(16, (index) {
      return  GridTile(
        child:GestureDetector(  
          onTap:(){
            print(index.toString());
          },
      child:    Card(
          color: Colors.blue.shade200,
          child:  Column(
            children:[  Text('tile $index'),
                         Icon(Icons.alarm)
          ])
        )),
     );
    }),
  ),
 

With help of index parameter you can pass function according to button type. If this answer helped you.please upvote the answer. Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM