Nie mogę znaleźć żadnego przykładu pokazującego, jak utworzyć okrąg IconButton
podobny do FloatingActionButton
. Czy ktoś może zasugerować, jak / co jest potrzebne, aby utworzyć niestandardowy przycisk, taki jak FloatingActionButton
?
88
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap
constraints: BoxConstraints.expand(width: 42, height: 42),
Możesz spróbować, jest w pełni konfigurowalny.
ClipOval( child: Material( color: Colors.blue, // button color child: InkWell( splashColor: Colors.red, // inkwell color child: SizedBox(width: 56, height: 56, child: Icon(Icons.menu)), onTap: () {}, ), ), )
Wynik:
źródło
Wystarczy użyć kształtu:
CircleBorder()
MaterialButton( onPressed: () {}, color: Colors.blue, textColor: Colors.white, child: Icon( Icons.camera_alt, size: 24, ), padding: EdgeInsets.all(16), shape: CircleBorder(), )
źródło
Możesz użyć InkWell, aby to zrobić:
Poniższy przykład pokazuje, jak używać
InkWell
. Uwaga: nie musiszStatefulWidget
tego robić. Użyłem go do zmiany stanu licznika.Przykład:
import 'package:flutter/material.dart'; class SettingPage extends StatefulWidget { @override _SettingPageState createState() => new _SettingPageState(); } class _SettingPageState extends State<SettingPage> { int _count = 0; @override Widget build(BuildContext context) { return new Scaffold( body: new Center( child: new InkWell(// this is the one you are looking for.......... onTap: () => setState(() => _count++), child: new Container( //width: 50.0, //height: 50.0, padding: const EdgeInsets.all(20.0),//I used some padding without fixed width and height decoration: new BoxDecoration( shape: BoxShape.circle,// You can use like this way or like the below line //borderRadius: new BorderRadius.circular(30.0), color: Colors.green, ), child: new Text(_count.toString(), style: new TextStyle(color: Colors.white, fontSize: 50.0)),// You can add a Icon instead of text also, like below. //child: new Icon(Icons.arrow_forward, size: 50.0, color: Colors.black38)), ),//............ ), ), ); } }
Jeśli chcesz uzyskać korzyści
splashColor
,highlightColor
owinąćInkWell
widget za pomocąMaterial
widget z materiału typu koła. A następnie usuńdecoration
wContainer
widżecie.Wynik:
źródło
Możesz łatwo wykonać następujące czynności:
FlatButton( onPressed: () { }, child: new Icon( Icons.arrow_forward, color: Colors.white, size: 20.0, ), shape: new CircleBorder(), color: Colors.black12, )
Wynik to
źródło
Jeśli potrzebujesz obrazu tła, możesz użyć CircleAvatar z IconButton. Ustaw właściwość backgroundImage.
Przykład z przyciskiem:
CircleAvatar( backgroundColor: Colors.blue, radius: 20, child: IconButton( padding: EdgeInsets.zero, icon: Icon(Icons.add), color: Colors.white, onPressed: () {}, ), ),
źródło
RawMaterialButton( onPressed: () {}, constraints: BoxConstraints(), elevation: 2.0, fillColor: Colors.white, child: Icon( Icons.pause, size: 35.0, ), padding: EdgeInsets.all(15.0), shape: CircleBorder(), )
uwaga
constraints: BoxConstraints()
, to za niedopuszczanie dopełnienia w lewo.Miłego trzepotania !!
źródło
W rzeczywistości istnieje przykład, jak utworzyć okrąg IconButton podobny do FloatingActionButton.
Ink( decoration: const ShapeDecoration( color: Colors.lightBlue, shape: CircleBorder(), ), child: IconButton( icon: Icon(Icons.home), onPressed: () {}, ), )
Aby utworzyć projekt lokalny za pomocą tego przykładowego kodu, uruchom:
flutter create --sample=material.IconButton.2 mysample
źródło
Mój wkład:
import 'package:flutter/material.dart'; /// /// Create a circle button with an icon. /// /// The [icon] argument must not be null. /// class CircleButton extends StatelessWidget { const CircleButton({ Key key, @required this.icon, this.padding = const EdgeInsets.all(8.0), this.color, this.onPressed, this.splashColor, }) : assert(icon != null), super(key: key); /// The [Icon] contained ny the circle button. final Icon icon; /// Empty space to inscribe inside the circle button. The [icon] is /// placed inside this padding. final EdgeInsetsGeometry padding; /// The color to fill in the background of the circle button. /// /// The [color] is drawn under the [icon]. final Color color; /// The callback that is called when the button is tapped or otherwise activated. /// /// If this callback is null, then the button will be disabled. final void Function() onPressed; /// The splash color of the button's [InkWell]. /// /// The ink splash indicates that the button has been touched. It /// appears on top of the button's child and spreads in an expanding /// circle beginning where the touch occurred. /// /// The default splash color is the current theme's splash color, /// [ThemeData.splashColor]. final Color splashColor; @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); return ClipOval( child: Material( type: MaterialType.button, color: color ?? theme.buttonColor, child: InkWell( splashColor: splashColor ?? theme.splashColor, child: Padding( padding: padding, child: icon, ), onTap: onPressed, ), ), ); } }
źródło
Ten kod pomoże Ci dodać przycisk bez niechcianego dopełnienia,
RawMaterialButton( elevation: 0.0, child: Icon(Icons.add), onPressed: (){}, constraints: BoxConstraints.tightFor( width: 56.0, height: 56.0, ), shape: CircleBorder(), fillColor: Color(0xFF4C4F5E), ),
źródło
Użyłem tego, ponieważ lubię dostosowywanie promienia obramowania i rozmiaru.
Material( // pause button (round) borderRadius: BorderRadius.circular(50), // change radius size color: Colors.blue, //button colour child: InkWell( splashColor: Colors.blue[900], // inkwell onPress colour child: SizedBox( width: 35,height: 35, //customisable size of 'button' child: Icon(Icons.pause,color: Colors.white,size: 16,), ), onTap: () {}, // or use onPressed: () {} ), ), Material( // eye button (customised radius) borderRadius: BorderRadius.only( topRight: Radius.circular(10.0), bottomLeft: Radius.circular(50.0),), color: Colors.blue, child: InkWell( splashColor: Colors.blue[900], // inkwell onPress colour child: SizedBox( width: 40, height: 40, //customisable size of 'button' child: Icon(Icons.remove_red_eye,color: Colors.white,size: 16,),), onTap: () {}, // or use onPressed: () {} ), ),
źródło
Stworzyłem wersję z poprawnym wycięciem, elewacją i obramowaniem. Możesz go dostosować.
Material( elevation: 2.0, clipBehavior: Clip.hardEdge, borderRadius: BorderRadius.circular(50), color: Colors.white, child: InkWell( onTap: () => null, child: Container( padding: EdgeInsets.all(9.0), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: Colors.blue, width: 1.4)), child: Icon( Icons.menu, size: 22, color: Colors.red, ), ), ), )),
źródło
Rozwiązanie nieistotne:
final double floatingButtonSize = 60; final IconData floatingButtonIcon; TouchableOpacity( onTap: () { /// Do something... }, activeOpacity: 0.7, child: Container( height: floatingButtonSize, width: floatingButtonSize, decoration: BoxDecoration( borderRadius: BorderRadius.circular(floatingButtonSize / 2), color: Theme.of(context).primaryColor, boxShadow: [ BoxShadow( blurRadius: 25, color: Colors.black.withOpacity(0.2), offset: Offset(0, 10), ) ], ), child: Icon( floatingButtonIcon ?? Icons.add, color: Colors.white, ), ), )
Możesz użyć GestureDetector zamiast biblioteki TouchableOpacity.
źródło
Możesz również użyć RaisedButton z obrazem w środku (na przykład do logowania społecznościowego) w ten sposób (do ograniczenia obrazu do określonego rozmiaru potrzebne jest Sizebox z fittebox):
FittedBox( fit: BoxFit.scaleDown, child: SizedBox( height: 60, width: 60, child: RaisedButton( child: Image.asset( 'assets/images/google_logo.png'), shape: StadiumBorder(), color: Colors.white, onPressed: () {}, ), ), ),
źródło
ClipOval( child: MaterialButton( color: Colors.purple, padding: EdgeInsets.all(25.0), onPressed: () {}, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0)), child: Text( '1', style: TextStyle(fontSize: 30.0), ), ), ),
źródło
Wypróbuj tę kartę
Card( elevation: 10, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25.0), // half of height and width of Image ), child: Image.asset( "assets/images/home.png", width: 50, height: 50, ), )
źródło