There are multiple heroes that share the same tag within a subtree without using FAB - flutter

I am trying to navigate to a route and this exception happen. Have look at my code and I don't think I have a FAB and Hero inside this route. Is it because when you tap on each List item, it will show a dialog with Gridview on it? Someone care to explain to me how can this exception happened? It doesn't produce any error on user thought, just throw an exception.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Daftar Dokter")),
body: ListView.separated(
separatorBuilder: (BuildContext context, int i) => Divider(color: Colors.grey[400]),
itemCount: widget.data.length,
itemBuilder: (context, index) {
Doctor doctor = widget.data[index];
return InkWell(
onTap: (){
_buildDialog(context, scheduleService, doctor.doctorId);
},
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 50,
height: 50,
child: Placeholder(),
),
),
Flexible(
child: SizedBox(
child: ListTile(
title: Text(doctor.name),
subtitle: Text(doctor.specializationName),
),
)
)
],
),
);
}
)
);
}
}

Hope it will solve your issue:
onItem Builder:
itemBuilder: (context, index) {
return Hero(
tag: "itemTag $index",
child: Material(
child: InkWell(
onTap: () {
// _buildDialog(context, scheduleService, doctor.doctorId);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Wisgets(
tag: "itemTag $index",
)));
},
child: Row(
children: <Widget>[
Text("Item $index"),
],
),
),
),
);
},
Child Widget for row
class Wisgets extends StatelessWidget {
final String tag;
const Wisgets({Key? key, required this.tag}) : super(key: key);
#override
Widget build(BuildContext context) {
return Hero(
tag: tag,
child: Scaffold(
appBar: AppBar(
title: Text("Child"),
),
body: Column(
children: [
Text("got $tag"),
],
),
),
);
}
}

Related

How can I add a Container after a FutureBuilder?

How can you add more Containers or Widgets after using FutureBuilder?
I've been trying to combine these 2 blocks of code into one but can't figure out how to do so. I need the 2 buttons from code-block 2 to be added after this ListView.builder. Or does this have to be on 2 separate pages?
#override
Widget build(BuildContext context) =>
Scaffold(
body:
FutureBuilder<ListResult>(
future: futureFiles,
builder: (context, snapshot) {
if (snapshot.hasData) {
final files = snapshot.data!.items;
return ListView.builder(
itemCount: files.length,
itemBuilder: (context, index) {
final file = files[index];
double? progress = downloadProgress[index];
return ListTile(
title: Text(file.name),
subtitle: progress != null
? LinearProgressIndicator(
value: progress,
backgroundColor: Colors.black26,
)
: null,
trailing: IconButton(
icon: const Icon(
Icons.download,
color: Colors.white,
),
onPressed: () => downloadFile(index, file),
));
});
} else if (snapshot.hasError) {
return const Center(child: Text('Error occurred'));
} else {
return const Center(child: CircularProgressIndicator());
}
},
)
);
}
I want to combine the following code into the code above. But can't quite figure out how to do that.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if(pickedFile != null)
Expanded(
child: Container(
child: Center(
child: Image.file(File(pickedFile!.path!),width:double.infinity,fit: BoxFit.cover,),
//child: Text(pickedFile!.name),
)
)
),
if (pickedFile == null)
Expanded(
child: Container(
child: Center(
displayFiles()
)
)
),
Row(
mainAxisAlignment : MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: SizedBox(
height:40,
width: 150,
child:
ElevatedButton(
child: Text('Select File'),
onPressed: selectFile,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
textStyle: const TextStyle(fontSize: 20),
),
),
),
),
SizedBox(
height:40,
width: 150,
child: ElevatedButton(
child: Text('Upload File'),
onPressed: uploadFile,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
textStyle: const TextStyle(fontSize: 20)
),
),
),
],
),
buildProgress(),
],
),
),
);
}
I tried wrapping the buttons inside a Container but I can't figure out where to place the Container in the first block of code.
Do like this
Column(
children: [
Expanded(
child: FutureBuilder<ListResult>()),
//Second page code
Center()
]
)
You may return a Column widget from the builder of FutureBuilder instead of returning a ListView, and make ListView the first child of that Column. The buttons can be defined as second, third....etc children as you please.
itemCount: files.length + 3;
final file = files[index+3];
if(index==0){
(some widget)
}
else if(index==1){
(some widget)
}
if(index==2){
(some widget)
}else return ListTile()

Flutter: Widget Tree

There are two Widgets I created, and a main Widget. But i am getting an Error:
"package:flutter/src/rendering/proxy_box.dart': Failed assertion: line
1899"
Main Widget:
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: [
buildHeader(),
buildMenu()
],
),
);
}
First Widget:
Widget buildHeader() {
return const Center(
child: Card(
child: SizedBox(
width: 300,
height: 100,
child: Center(child: Text('Elevated Card')),
),
),
);
}
Second Widget:
Widget buildMenu() {
return Drawer(
child: FutureBuilder<List<Menu>>(
future: listMenus,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: (snapshot.data as List<Menu>).length,
itemBuilder: (context, index) {
var menu = (snapshot.data as List<Menu>)[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 4),
child: Card(
child: ListTile(
onTap: () {
// print(listMenus[index]);
},
title: Text(menu.folder),
),
),
);
},
);
} else if (snapshot.hasError) {
return Center(
child: Text("${snapshot.error}"),
);
}
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
),
);
},
));
}
.....................................................................
The main widget is returning a drawer and the second widget is also returning a drawer. In second widget replace the drawer with an Expanded widget or SizedBox of specific height and width
EDIT
I checked your codes with some dummy data and getting the result as expected
import 'package:flutter/material.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(home: Center(child: DemoClass()));
}
}
class DemoClass extends StatelessWidget {
DemoClass({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Column(
children: [
buildHeader(),
buildMenu(),
],
),
),
);
}
}
Widget buildHeader() {
return const Center(
child: Card(
child: SizedBox(
width: 300,
height: 100,
child: Center(child: Text('Elevated Card')),
),
),
);
}
Widget buildMenu() {
return Expanded(
child: FutureBuilder<List<Menu>>(
future: listMenus,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: (snapshot.data as List<Menu>).length,
itemBuilder: (context, index) {
Menu menu = (snapshot.data as List<Menu>)[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 4),
child: Card(
child: ListTile(
onTap: () {
// print(listMenus[index]);
},
title: Text(menu.folder),
),
),
);
},
);
} else if (snapshot.hasError) {
return Center(
child: Text("${snapshot.error}"),
);
}
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
),
);
},
));
}
Follow the snippet and dont need multiple drawer. And handle overflow by wrapping ListView with Expanded
return Scaffold(
drawer: Drawer(
child: Column(
children: [
buildHeader(),
buildMenu(),
],
),
),
);
Widget buildMenu() { ....
return Expanded(child: ListView.builder(
Snippet structure
class SG extends StatefulWidget {
SG({Key? key}) : super(key: key);
#override
State<SG> createState() => _SGState();
}
class _SGState extends State<SG> {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
child: Column(
children: [
buildHeader(),
buildMenu(),
],
),
),
);
}
Widget buildHeader() {
return const Center(
child: Card(
child: SizedBox(
width: 300,
height: 100,
child: Center(child: Text('Elevated Card')),
),
),
);
}
Widget buildMenu() {
return FutureBuilder<List<Menu>>(
future: listMenus,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Expanded(
child: ListView.builder(
itemCount: (snapshot.data as List<Menu>).length,
itemBuilder: (context, index) {
var menu = (snapshot.data as List<Menu>)[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 4),
child: Card(
child: ListTile(
onTap: () {
// print(listMenus[index]);
},
title: Text(menu.folder),
),
),
);
},
),
);
} else if (snapshot.hasError) {
return Center(
child: Text("${snapshot.error}"),
);
}
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
),
);
},
);
}

Flutter draggable scrollable sheet

does anyone know why my draggable scrollable sheet doesn't work or why I can't see it?
I tried it in another way it worked, but I didn't use the SafeArea-Widget,
import 'package:flutter/material.dart';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
//AppBar
),
body: SafeArea(
child: ListView(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
dateday,
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
SizedBox.expand(
child: DraggableScrollableSheet(builder:
(BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
],
),
),
);
}
}
Thanks for your help!
Replace the ListView with a Stack:
body: SafeArea(
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
dateday,
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
SizedBox.expand(
child: DraggableScrollableSheet(
builder:
(BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
],
),
),
You can use LayoutBuilder and BoxConstraints to provide height and use Expanded flex to control DraggableScrollableSheet's scroll area
code snippet
SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth),
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
"dateday",
...
Expanded(
flex: 3,
child: SizedBox.expand(
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DraggableScrollableSheet'),
),
body: SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
print(constraints.maxWidth);
print(constraints.minWidth);
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth),
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
"dateday",
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
),
Expanded(
flex: 3,
child: SizedBox.expand(
child: DraggableScrollableSheet(builder:
(BuildContext context,
ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
),
],
),
);
}),
));
}
}

Listview not showing inside a Row in Flutter

I am trying to show a listview after some texts in a column. The text shows properly inside the first Row until I add a listview inside the next row. Everything disappears after adding the ListView.
Here is the Code:
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
"Prayer Time",
style: TextStyle(fontSize: 20, fontWeight:
FontWeight.normal),
),
],
),
Row(
children: <Widget>[myList()],
),
],
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add Alarm',
child: Icon(Icons.add),
backgroundColor: const Color(0xff0A74C5),
),
);
}
Expanded myList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, position) {
return Card(
child: Text(androidVersionNames[position]),
);
},
itemCount: androidVersionNames.length,
)
);
}
}
change like this:
Expanded(
child: Row(
children: <Widget>[myList()],
),
),
Your ListView should have a fixed Size. Try to wrap the ListView inside a Container.
I run your code and fixed it. Replace your myList() with this code bellow:
Expanded myList() {
return Expanded(
child: Container(
width: double.infinity,
height: 200,
child: ListView.builder(
itemBuilder: (context, position) {
return Card(
child: Text(androidVersionNames[position]),
);
},
itemCount: androidVersionNames.length,
),
)
);
}

How I can put Widget above Widget using List<Widget> widget in Flutter?

Is it possible to stack multiple widget ?
I have widgets variable that wanted to be placed below InkWell widget.
How should I solve this ?
This is my code :
final List<Widget> widgets = [Home1(), Home2(),Home3()];
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: new PageView.builder(
controller: new PageController(
viewportFraction: 1.0,
),
itemCount: widget.length,
itemBuilder: (BuildContext context, int i) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 5.0,
vertical: 22.0,
),
child: Material(
borderRadius: BorderRadius.circular(15.0,),
elevation: 1.0,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Hero(
tag: widget[i],
child: Material(
child: InkWell(
onTap:() => Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => Home(),
),
),
child: ..........?????????
),
),
),
],
),
),
);
},
),
),
);
}