Drag and Drop Chip widgets - flutter

I was trying to make a list of chips which user can reorder by doing drag and drop gesture,
Here is sample code which you can execute to see the issue,
As being told, Chip class need a Material ancestor, so what is solution to this? Have to keep Chip wrapped with Card all the time?
Error:
The following assertion was thrown building Chip(dirty):
No Material widget found.
Chip widgets require a Material widget ancestor.
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Wrap(
direction: Axis.horizontal,
children: List.generate(_counter, (i) {
var chip = Chip(
backgroundColor: Colors.blue,
label: Text('item ${i}'),
);
return Draggable(
child: chip,
feedback: chip,
childWhenDragging: Container(),
);
}),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
note: I have modified the default click count template to demonstrate my issue

You can wrap it inside a FloatingActionButton.
var chip = FloatingActionButton(
child: Chip(
backgroundColor: Colors.blue,
label: Text('item $i'),
),
);
Hope it helps!

I had encountered the same issue. You can not use chips in the feedback of draggable. What I did is, wrapped my chip in Material with transparent background. The transparent background helps to remove the extra style that gets added from the Material widget.
feedback: Material(
color: Colors.transparent,
child: Chip(
// your code for the Chip
)
)

Related

floatingActionButton (SpeedDial library)

How can I open SpeedDial in a horizontal way in my project like this?
If there are other libraries, that is fine.
You can also create your own custom floating action button. But since you are open to packages too writing an answer in which you can achieve it using a package
Try https://pub.dev/packages/custom_floating_action_button
Add this to pubspec.yaml
custom_floating_action_button: ^0.0.3
You can wrap the scaffold with CustomFloatingActionButton
//add custom floating action button on top of your scaffold
//minimum 2 and maximum 5 items allowed
#override
Widget build(BuildContext context) {
return CustomFloatingActionButton(
body: Scaffold(
appBar: AppBar(
title: const Text('appbar title'),
),
body: Container(),
),
options: const [
CircleAvatar(
child: Icon(Icons.height),
),
CircleAvatar(
child: Icon(Icons.title),
),
//All widgets that should appear ontap of FAB.
],
type: CustomFloatingActionButtonType.horizontal,
openFloatingActionButton: const Icon(Icons.add),
closeFloatingActionButton: const Icon(Icons.close),
);
}

Unable to position AndroidView with video

I am using flutter 3.0.0
In my application I am displaying a native video using platform view.
The video is displaying but it is always displaying on upper left corner and it covers other
widgets even they are in a stack.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Stack(
children: [
Center(
child: ConstrainedBox(
constraints:
const BoxConstraints.expand(height: 200, width: 200),
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child:
const AndroidView(viewType: 'remote-video'),
),
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
MethodChannels.coreMethodChannel
.invokeMethod("load");
},
child: const Text('Invoke'),
),
),
],
),
],
),
);
}
This is how it looks when I run the code
As you can see it is displaying over everything.
Can you provide some advice on how to fix this?
As of 31/07/2022 this seems to be a bug in flutter >= 3.0.0. Following the solution in this question Flutter AndroidView Widget I downgraded to 2.10.5 and then it worked as expected. Hopefully the flutter team will resolve it shortly.

[Flutter]: FAB for only one bottom tab

I have a BottomAppBar that has a FloatingActionButton. However, I only want this button to be seen in one particular screen. In the best case, I'd like to add this button only when the user clicks on that particular screen.
I've found that you can add a FAB like this:
return Scaffold(
extendBodyBehindAppBar: true,
extendBody: true,
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {
...
},
child: const Icon(
Icons.add_sharp,
color: Color(0xFFFFFFFF),
),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: buildBottomNavigationBar(),
);
However, as you can see this Scaffold is shared by all the screens that can be selected in the bottomNavigationBar. How do I add a FAB only for a particular screen?
I'd like the FAB to be embedded into the bottomNavigationBar so I do not want to add a plain button to that particular screen. Thanks.
The answer by #Josip Domazet is absolutely right, but it can be achieved with shorter workaround instead of creating different Scaffold, using conditional operator as
floatingActionButton: _selectedIndex==1
? FloatingActionButton(....) : const SizedBox.shrink(),
Use Stack In your Specific Tab and Add FAB at the bottom :
Example :
Stack(
children[
Container(height: double.infinity,
width: double.infinity) // for full screen
Position(
bottom : 10,
left: 150,
right : 150,
child: FloatingActionButton(
onPressed: () {
...
},
child: const Icon(
Icons.add_sharp,
color: Color(0xFFFFFFFF),
),
)
)
])
Wrap that specific screen with scaffold again and use fab on that screen only.
Turns out the solution was actually quite simple and I was overthinking stuff. I have a variable that keeps track of the currently open screen. So I simply added this little logic to the mother screen that hosts the bottomNavigationBar:
if (_selectedIndex==1){
// Other screen that needs the FAB
return Scaffold(
...,
floatingActionButton: FloatingActionButton(
....
),
bottomNavigationBar: buildBottomNavigationBar(),
);
}
return Scaffold(
...,
bottomNavigationBar: buildBottomNavigationBar(),
);

How to display a snackBar in scaffold is body is composed of Stack?

I am trying to display a snack bar on my screen. But the snack bar is covering the whole screen instead of just being displayed at the bottom. Here is my code.
Scaffold(
key: _scaffoldKey ,
backgroundColor: Colors.pink,
body: Stack(
children: <Widget>[
Text('Display Scaffold'),
Positioned(
top: 110,
child: Container(
child: FlatButton(
onpressed: (){
final snackBar = SnackBar(duration: Duration(seconds: 4),
content: Center(child: Text('Welcome')),
) ;
_scaffoldKey.currentState.showSnackBar(snackBar);
}
),
),
),
),
);
Remove Center widget. This makes the widget as big as the parent allows.
If you need to center your text, just use textAlign: TextAlign.center property in Text widget.
Have you try this ?
Scaffold.of(context).showSnackBar(snackBar);
instead of
_scaffoldKey.currentState.showSnackBar(snackBar);
It may be the solution.
I hope it could help you !

How to make bottomNavigationBar notch transparent

I want to make the notch margin spacing (space between FAB's sides and bottom bar) like android material design explain in Inset FAB, It looks like a zoom background text in this small visible round portion. How we can make notching space transparent to see the text behind it?
However, mine bottom bar is not showing like that
My implementation
Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.white,
child: Image.asset("images/paw.png"),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Map()));
},
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.menu),
color: Colors.transparent,
onPressed: () {},
),
],
),
color: Utiles.primary_bg_color,
),
body: Container(...)
You need extendBody: true in Scaffold
class SO extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
appBar: AppBar(),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text('text text text text text text text text text text text text text text text text text text text text ');
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: () {},
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 12,
color: Colors.blue,
child: Container(
height: 60,
),
),
);
}
}
BottomAppBar + BottomNavigationBar
The question title asks about BottomNavigationBar so I'm adding this answer to help people using both a BottomAppBar with a BottomNavigationBar.
If you're not using BottomNavigationBar, ignore this.
NavBar Covers Notch
By default, a BottomNavigationBar used as a child inside a BottomAppBar, will cover the notch like so:
We need to remove its color & shadow to let the notch show.
Using BottomNavigationBar in BottomAppBar
To keep the notch visible...
BottomNavigationBar needs:
a backgroundColor specified, with 0 alpha (completely transparent)
otherwise, the default onBackground theme color is used, covering the notch
elevation: 0 to remove an ugly shadow under BottomNavigationBar
the transparent backgroundColor makes the shadow visible & horrendous
BottomAppBar needs:
shape: CircularNotchedRectangle() obviously, to have a notch for the FAB
elevation: 0 to remove a slight shadow under the notched FAB (barely visible)
Scaffold needs:
extendBody: true to allow body content to flow underneath notched FAB
SafeArea needs:
if using SafeArea, use bottom:false arg, so our body can flow below past the BottomNavigationBar, under the FAB
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
extendBody: true, // CRITICAL for body flowing under FAB
body: SafeArea(
child: Center(
child: Container(
color: Colors.greenAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
),
bottom: false,
// ↑ SafeArea(bottom:false) allows Scaffold body:+extendBody: to hit bottom edge
),
// ↓ Location: centerDocked positions notched FAB in center of BottomAppBar ↓
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
bottomNavigationBar: BottomAppBar( // ****** APP BAR ******************
clipBehavior: Clip.antiAlias,
shape: CircularNotchedRectangle(), // ← carves notch for FAB in BottomAppBar
color: Theme.of(context).primaryColor.withAlpha(255),
// ↑ use .withAlpha(0) to debug/peek underneath ↑ BottomAppBar
elevation: 0, // ← removes slight shadow under FAB, hardly noticeable
// ↑ default elevation is 8. Peek it by setting color ↑ alpha to 0
child: BottomNavigationBar( // ***** NAVBAR *************************
elevation: 0, // 0 removes ugly rectangular NavBar shadow
// CRITICAL ↓ a solid color here destroys FAB notch. Use alpha 0!
backgroundColor: Theme.of(context).primaryColor.withAlpha(0),
// ====================== END OF INTERESTING STUFF =================
selectedItemColor: Theme.of(context).colorScheme.onSurface,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit_outlined,
size: 40,
color: Theme.of(context).colorScheme.onBackground),
label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm,
size: 40,
color: Theme.of(context).colorScheme.onBackground),
label: 'Edit')
],
),
),
);
Result
With the above pieces in place you should see something like this:
Use, extendBody: true
From the docs,
extendBody: true ensures that that scaffold's body will be visible through the bottom navigation bar's notch
Do:
return Scaffold(
extendBody: true,
(...)
after
body: SafeArea(
bottom: false,
(...)
after "no add backgroundColor"
BottomNavigationBar(
//backgroundColor:
If you use safe Area ,then extended Body and probably other methods doesn't work. So set the safe Area to (false).