Draggable scrollable sheet in flutter - flutter

When I click on the DraggableHeaderComponent to pull it up, it doesn't work.
When dragging to the bottom of the screen, I want to keep the DraggableHeaderComponent sticky at the top and the rest of the array moving with the scroll.
The image below shows what I mean, but I want to install the header at the bottom.
#override
Widget build(BuildContext context) {
return DraggableScrollableSheet(
minChildSize: 0.145,
initialChildSize: 0.145,
expand: false,
builder: (context, scrollController) => SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
DraggableHeaderComponent(),
Expanded(
child: ListView.separated(
itemCount: list.length,
controller: scrollController,
padding: EdgeInsets.symmetric(vertical: 8),
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, index) => Component(),
),
)
],
),
),
);
}

#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(
child: DraggableScrollableSheet(
minChildSize: 0.145,
initialChildSize: 0.145,
expand: false,
builder: (context, scrollController) => SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
DraggableHeaderComponent(),
Expanded(
child: ListView.separated(
itemCount: list.length,
controller: scrollController,
padding: EdgeInsets.symmetric(vertical: 8),
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, index) => Component(),
),
)
],
),
),
),
),
);
}
Just add SizedBox.expand() widget after scaffold widget. Might work.

Related

Flutter: Is it possible to scroll only items inside ExpansionPanelRadio body:?

I am new to flutter and would appreciate if someone could give me some hints on this:
I have to make few (not fixed number of) widgets which have to be expandable.
When expanded, they contain list of widgets in their body. List is long and it has to be scrollable in order to see all items.
If I put everything (whole expandable widget) inside SingleChildScrollView list items in body are scrollable, but also headers scroll - which I should prevent.
Widget _buildPanel() {
return SingleChildScrollView(
child: ExpansionPanelList.radio(
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadio(
value: item.id,
headerBuilder: (BuildContext context, bool isExpanded) {
return Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Row(
children: [
SvgPicture.network(
"https://some_picture.svg",
height: 80),
Column(children: <Widget>[
Text(' Some Text'),
Text(' label '),
]),
],
));
},
body: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) => ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
));
}).toList(),
));
}
and if I put only body inside SingleChildScrollView like this, then I got Exceptions.
Widget _buildPanel() {
return ExpansionPanelList.radio(
children: _data.map<ExpansionPanelRadio>((Item item) {
return ExpansionPanelRadio(
value: item.id,
headerBuilder: (BuildContext context, bool isExpanded) {
return Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Row(
children: [
SvgPicture.network("https://some_picture.svg",
height: 80),
Column(children: <Widget>[
Text(' Some Text'),
Text(' label '),
]),
],
));
},
body: SingleChildScrollView(
child: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) => ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
)));
}).toList(),
);
}
Is it possible to scroll only list items and to keep header in fixed position?
You need to set height for your body and remove physics, shrinkWrap in order to get what you want, like this:
body: SizedBox(
height: 300,//<-- add this
child: ListView.builder(
itemCount: widgets.length,
itemBuilder: (context, index) =>
ListTile(title: widgets[index]),
scrollDirection: Axis.vertical,
),
),

Flutter: Add ReorderableList inside a ListView

The issue I have is adding a ReorderableList inside a ListView, the ReorderableList does not allow for reordering now. I can scroll the list but the long press for reodering is not active anymore. Here is my code:
Widget get _reorder => ReorderableList(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) => _cells[index],
itemCount: _cells?.length ?? 0,
onReorder: _setListOrder,
);
#override
Widget build(BuildContext context) {
return Container(
decoration: context.logoBackground,
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_reorder,
Text('End of List Widget')
],
);
}),
)
],
),
),
);
}
I did it with ReorderableListView instead of ReorderableList like this:
void _setListOrder(int oldIndex, int newIndex) {
print('old: $oldIndex, new: $newIndex'); // You need to implement the method!
}
var _cells = List.generate(30, (index) { // Your cells
return ListTile(
key: Key('$index'),
title: Text(
'$index',
),
);
});
Widget get _reorder => ReorderableListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) => _cells[index],
itemCount: _cells?.length ?? 0,
onReorder: _setListOrder,
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListView( // I transformed it to simple ListView because you have one children
shrinkWrap: true,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height, // You need this height, or a custom height!
child: _reorder),
Text('End of List Widget')
],
)
],
),
)
],
),
),
),
);
}
If you want to check the documentation, you can do it here!

FutureBuilder rebuilds because of TextField in Flutter

The problem is when I try to input some text into textfield, the keyboard shows up for a second, and then the whole FutureBuilder rebuilds immediately.
Here is my FutureBuilder
body: FutureBuilder(
future: Provider.of<Activities>(context, listen: false).fetchAndSet(),
builder: (context, snapshot) => snapshot.connectionState ==
ConnectionState.waiting
? Center(child: CircularProgressIndicator())
: Consumer<Activities>(
child: Center(
child: const Text('nothing here'),
),
builder: (context, activities, ch) => SingleChildScrollView(
child: Center(
child: Column(children: [
Container(
padding:
EdgeInsets.only(top: mediaQuery.size.height / 40),
child: Text(time, style: TextStyle(fontSize: 30)),
),
DayContainer(mediaQuery, activities),
Container(
height: 300,
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
children: <Widget>[
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: activities.activities.length,
itemBuilder: (context, index) {
return ElementPicker(
mediaQuery,
// this.callbackN,
activities.activities[index]);
})
],
),
),
),
FloatingActionButton(
onPressed: () => activities.addActivity(
'0Adding0', 'Добавить активность', 0.0, 0.0),
child: Icon(Icons.add),
)
]),
),
),
),
)
Inside of ElementPicker, there is another widget in which there is TextField
You need to initialize your futures in the initState so that whenever the widget rebuilds for any reason (in this case opening of the keyboard), you don't perform the fetchAndSet again:
void initState() {
super.initState();
fetchAndSetFuture = Provider.of<Activities>(context, listen: false).fetchAndSet();
}
...
//in build()
FutureBuilder(
future: fetchAndSetFuture,
builder: ...
);

How to create a combined, scrollable List in a Drawer in Flutter

I wan´t to have a combination of text-widgets and lists inside a drawer. This content should be scrollable.
Here´s my sourcecode:
return Drawer(
child: Expanded(
child: Column(
children: <Widget>[
AppBar(title: Text('Test'),),
Text('Example 1:'),
ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _brands.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
....);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
Text('Another heading')
],
),
),
);
What I want to achive:
The AppBar is fixed at the top
The other content below should be scrollable
I´ve tried different ways with Expanded, Columns etc. but I wasn´t able to get this layout up and running as expected. Thanks in advance for any input!
you can use a single column with the listview places inside an expanded widget
return Drawer(
child: Column(
children: <Widget>[
AppBar(),
Expanded(
child: ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: 100,
itemBuilder: (context, index) {
return Text(index.toString());
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
),
],
),
);
yeilds
For short you can wrap your ListView with Expanded widget, it will fill all available space, but you will able to scroll it. In another case you should wrap ListView with Container and set height property.
For your example:
Drawer(
child: Column(
children: <Widget>[
AppBar(title: Text('Test'),),
Text('Example 1:'),
Expanded(
child: ListView.separated(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: List.generate(100, (index) => index).length,
itemBuilder: (BuildContext context, int index) {
return ListTile(leading: Text("$index"),);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(height: 5),
),
),
Text('Another heading')
],
),
),

How to implement multiple horizontal lists inside a column

I want to implement multiple horizontal lists that contain cards with some details, and now all i get is just white screens(without errors)
This is my code:
Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 50,
itemBuilder: (BuildContext context, int index) {
Card(
child: Column(
children: <Widget>[
Text('fsfssffs'),
],
),
);
},
),
),
SizedBox(
height: 20.0,
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 50,
itemBuilder: (BuildContext context, int index) {
Card(
child: Column(
children: <Widget>[
Text('fsfssffs'),
],
),
);
},
),
),
],
),
);
I want to achieve something like the facebook stories
Use => on List itemBuilder to return the items:
Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 50,
itemBuilder: (BuildContext context, int index) =>
Card(
child: Column(
children: <Widget>[
Text('fsfssffs'),
],
),
);
},
),
),
SizedBox(
height: 20.0,
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 50,
itemBuilder: (BuildContext context, int index) =>
Card(
child: Column(
children: <Widget>[
Text('fsfssffs'),
],
),
);
},
),
),
],
),
);
You were not returning any widget from your itemBuilder method which is why you were unable to see anything on screen.
Basically, there are 2 solutions for this, I am giving you idea using a build() method you can do it in your itemBuilder.
(1) Use => (fat arrow notation)
Example:
Widget build(context) => Text("Hi");
(2) Use return.
Widget build(context) {
return Text("Hi");
}