Как мне удалить Flutter IconButton большой отступ?
Я хочу иметь ряд значков IconButton, расположенных рядом друг с другом, но между реальной иконкой и пределами IconButton, похоже, имеется довольно большой отступ. Я уже установил отступ для кнопки на 0.
Это мой компонент, довольно простой:
class ActionButtons extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.lightBlue,
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
IconButton(
icon: new Icon(ScanrIcons.reg),
alignment: Alignment.center,
padding: new EdgeInsets.all(0.0),
onPressed: () {},
),
IconButton(
icon: new Icon(Icons.volume_up),
alignment: Alignment.center,
padding: new EdgeInsets.all(0.0),
onPressed: () {},
)
],
),
);
}
}
Я хочу избавиться от большей части светло-синего пространства, чтобы мои иконки начинались раньше слева и были ближе друг к другу, но я не могу найти способ изменить размер самой IconButton.
Я почти уверен, что это место занято самой кнопкой, потому что если я изменю их выравнивание на centerRight
а также centerLeft
они выглядят так:
Уменьшение фактических значков также не помогает, кнопка все еще большая:
Спасибо за помощь
13 ответов
Это не так много, что там есть прокладка. IconButton - это виджет Material Design, который следует спецификации, согласно которой объекты, которые должны быть вставлены, должны иметь размер не менее 48 пикселей с каждой стороны. Вы можете нажать на реализацию IconButton из любых IDE.
Вы также можете тривиально взять исходный код icon_button.dart и создать свой собственный IconButton, который не соответствует спецификациям Material Design, поскольку весь файл состоит только из других виджетов и содержит всего 200 строк, которые в основном являются комментариями.
Просто передайте пустой BoxConstrains
к constraints
свойство и нулевое заполнение.
IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
)
Вы должны передать пустые ограничения, потому что по умолчанию виджет IconButton принимает минимальный размер 48 пикселей.
Два способа обойти эту проблему.
Все еще используйте IconButton
Оберните IconButton внутри контейнера, который имеет ширину.
Например:
Container(
padding: const EdgeInsets.all(0.0),
width: 30.0, // you can adjust the width as you need
child: IconButton(
),
),
Используйте GestureDetector вместо IconButton
Вы также можете использовать GestureDetector вместо IconButton, рекомендованного Shyju Madathil.
GestureDetector( onTap: () {}, child: Icon(Icons.volume_up) )
2023 Решение:
IconButton(
onPressed: () {},
iconSize: 40.0, // desired size
padding: EdgeInsets.zero,
constraints: const BoxConstraints(), // override default min size of 48px
style: const ButtonStyle(
tapTargetSize: MaterialTapTargetSize.shrinkWrap, // the '2023' part
),
icon: const Icon(Symbols.arrow_right),
),
Обертывание IconButton
в контейнере просто не будет работать, вместо этого используйте ClipRRect и добавьте виджет материала с чернильницей, просто убедитесь, чтоClipRRect
Виджет достаточно радиуса границы.
ClipRRect(
borderRadius: BorderRadius.circular(50),
child : Material(
child : InkWell(
child : Padding(
padding : const EdgeInsets.all(5),
child : Icon(
Icons.favorite_border,
),
),
onTap : () {},
),
),
)
Вместо удаления отступа вокруг IconButton вы можете просто использовать Icon и обернуть его GestureDetector или InkWell как
GestureDetector(
ontap:(){}
child:Icon(...)
);
Если вы хотите, чтобы эффект пульсации / всплеска чернил, как IconButton, при нажатии, оберните его с помощью InkWell
InkWell(
splashColor: Colors.red,
child:Icon(...)
ontap:(){}
)
хотя чернила, нанесенные на значок во втором подходе, не будут такими точными, как для IconButton, вам может потребоваться выполнить некоторую индивидуальную реализацию для этого.
Вот решение, чтобы избавиться от лишних отступов, используя InkWell
на месте IconButton
:
Widget backButtonContainer = InkWell(
child: Container(
child: const Icon(
Icons.arrow_upward,
color: Colors.white,
size: 35.0,
),
),
onTap: () {
Navigator.of(_context).pop();
});
Я столкнулся с аналогичной проблемой, пытаясь отобразить значок в том месте, где пользователь касается экрана. К сожалению, Icon
класс оборачивает выбранную вами иконку в SizedBox
,
Читая немного исходного кода класса Icon, получается, что каждый Icon может рассматриваться как текст:
Widget iconWidget = RichText(
overflow: TextOverflow.visible,
textDirection: textDirection,
text: TextSpan(
text: String.fromCharCode(icon.codePoint),
style: TextStyle(
inherit: false,
color: iconColor,
fontSize: iconSize,
fontFamily: icon.fontFamily,
package: icon.fontPackage,
),
),
);
Так, например, если я хочу сделать Icons.details
чтобы указать, куда мой пользователь только что указал, безо всякого поля, я могу сделать что-то вроде этого:
Widget _pointer = Text(
String.fromCharCode(Icons.details.codePoint),
style: TextStyle(
fontFamily: Icons.details.fontFamily,
package: Icons.details.fontPackage,
fontSize: 24.0,
color: Colors.black
),
);
Исходный код Dart/Flutter замечательно доступен, я очень рекомендую покопаться в нем немного!
Мне нравится следующий способ:
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () {},
child: Container(
padding: const EdgeInsets.all(8),
child: const Icon(Icons.favorite, color: Colors.red),
),
),
Вы можете использовать ListTile, он дает вам пространство по умолчанию между текстом и значками, которое соответствует вашим потребностям.
ListTile(
leading: Icon(Icons.add), //Here Is The Icon You Want To Use
title: Text('GFG title',textScaleFactor: 1.5,), //Here Is The Text Also
trailing: Icon(Icons.done),
),
Лучшее решение - использовать Transform.scale
как это:
Transform.scale(
scale: 0.5, // set your value here
child: IconButton(icon: Icon(Icons.smartphone), onPressed: () {}),
)
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Icon(Icons.arrow_back_ios),
),
Чтобы показать эффект всплеска (рябь), используйте InkResponse
:
InkResponse(
Icon(Icons.volume_up),
onTap: ...,
)
При необходимости измените размер значков или добавьте отступ:
InkResponse(
child: Padding(
padding: ...,
child: Icon(Icons.volume_up, size: ...),
),
onTap: ...,
)