How can I have my trailing widget alight to the right? - flutter

I have a ListView and I want to have a switch on the right side of every ListTile. But the switch appears to be aligned to the left. How can I make it align to the right?
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: Padding(
padding: EdgeInsets.all(30.0),
child: Column
(
mainAxisAlignment: MainAxisAlignment.center,
children:
[
Expanded(
flex: 1,
child: Stack
(
children: [
Align(
alignment: Alignment.topLeft,
child: NavigatePopButton(),
),
Align
(
alignment: Alignment.topCenter,
child: Text
(
'Settings',
style: Theme.of(context).textTheme.title,
overflow: TextOverflow.visible,
),
),
],
)
),
Expanded
(
flex: 4,
child: MediaQuery.removePadding
(
context: context,
removeTop: true,
child: ListView.separated
(
itemCount: 3,
separatorBuilder: (BuildContext context, int index) => Divider(height: 1.0),
itemBuilder: (BuildContext context, int index)
{
return ListTile
(
title: Text(settings()[index].value),
trailing: settings()[index].controller,
);
}
),
),
),
]
),
),
);
}
}

ListTile has a Padding of it's own. Try tweaking that value,
For example
return ListTile
(
contentPadding: EdgeInsets.only(right: 0.0),
title: Text(arguments.groups[index]),
onTap: () => onGroupTap(arguments.groups[index]),
trailing: Switch(
value: true,
onChanged: (isSwitched) => print('is switched'),
),
);

I can't replicate the issue you are facing. I see Switch aligned to the right properly. Sample working code below:
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: ListView.separated
(
itemCount: 5,
separatorBuilder: (BuildContext context, int index) => Divider(height: 0.0),
itemBuilder: (BuildContext context, int index){
return ListTile
(
title: Text('Test'),
onTap: () {},
trailing: Switch(
value: true,
onChanged: (isSwitched) => print('is switched'),
),
);
},
),
),
);

Related

ListView doesn't separate objects from doc

I'm trying to create scrollable list of posts, but instead i got static non-scrollable bloc of strings, which is overflowing.
Example:
Oveflowing:
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _writePost,
tooltip: 'Increment',
child: Icon(Icons.create, color: Colors.grey[300]),
),
body: SizedBox(
child: Container(
child: Column(children: [
StreamBuilder<List<Post>>(
initialData: const [],
stream: _socketStream.stream,
builder: (context, snapshot) {
if (_isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: [
...snapshot.data!.map<Widget>(
(post) => Padding(
key: ValueKey(post.id),
padding: const EdgeInsets.symmetric(vertical: 10),
child: ListTile(
title: Text(
post.content,
style: const TextStyle(fontSize: 20),
),
trailing: MaterialButton(
onPressed: () {
_deletePost(post.id);
},
child: const Icon(
Icons.delete,
size: 30,
),
),
),
),
)
],
);
},
),
]))));
}
Moreover, they all go like a single card, without separating.
Edited code, which is scrolling but doesn't separate posts
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _writePost,
tooltip: 'Increment',
child: Icon(Icons.create, color: Colors.grey[300]),
),
body: SizedBox(
height: 500,
child:
StreamBuilder<List<Post>>(
initialData: const [],
stream: _socketStream.stream,
builder: (context, snapshot) {
if (_isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Card(child: ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: [
...snapshot.data!.map<Widget>(
(post) => Padding(
key: ValueKey(post.id),
padding: const EdgeInsets.symmetric(vertical: 10),
child: ListTile(
title: Text(
post.content,
style: const TextStyle(fontSize: 20),
),
trailing: MaterialButton(
onPressed: () {
_deletePost(post.id);
},
child: const Icon(
Icons.delete,
size: 30,
),
),
),
),
)
],
) );
},
),
));
}
I'm tried to find error with documentation, but...
Column and Listview take the maximum available height. therefore, the height of Listview which here is a child of Column should be constrained. You can do so by wrapping your ListView inside Expanded:
child: Column(
children: [
Expanded(
child: ListView(
Also, if your list is long, it is not recommended to set shrinkwrap to true. Because it makes the ListView to load all its items when the layout gets built. So it can slow down performance.
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: _writePost,
tooltip: 'Increment',
child: Icon(Icons.create, color: Colors.grey[300]),
),
body: SizedBox(
height: MediaQuery.of(context).height*0.8, // add this line
child:
// Container( // do not need this
// child: // and this do not need
// Column(children: [ // and this do not need
StreamBuilder<List<Post>>(
initialData: const [],
stream: _socketStream.stream,
builder: (context, snapshot) {
if (_isLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
ListView( // change this to ListView.builder for more performance
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: [
...snapshot.data!.map<Widget>(
(post) => Padding(
key: ValueKey(post.id),
padding: const EdgeInsets.symmetric(vertical: 10),
child: ListTile(
title: Text(
post.content,
style: const TextStyle(fontSize: 20),
),
trailing: MaterialButton(
onPressed: () {
_deletePost(post.id);
},
child: const Icon(
Icons.delete,
size: 30,
),
),
),
),
)
],
);## Heading ##
},
),
// ]) // comment this
// ). // and comment this
)
);
}

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

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"),
],
),
),
);
}
}

How to avoid bottom overflow when keyboard open (in alert dialog)

In this screen i'm facing overflow every time I open keyboard in the alert text field. I already tried to put SingleChildScrollVIew in all the places and it didn't resolve. This is the component which have the alertdialog:
Future<void> _showAlertDialog() async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Type the Name', textAlign: TextAlign.center,
style: TextStyle(color: Colors.white)),
content: TextField(
controller: _nameController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.sentences,
)
);
},
);
}
This is the build function:
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TableCalendar(//default code),
Divider(),
_showList(),
],
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, color: Colors.white,),
onPressed: () => _showCity(context)
),
);
}
The _showAlertDialog is called inside _showCity (see build > floating action button > onpressed)
_showCity:
_showCity(BuildContext context){
_showAlertDialog();
}
But after all attempts, every time I hit the textField in _showAlertDialog and it opens the keyboard, it throws an error:
A RenderFlex overflowed by 33 pixels on the bottom.
How can I handle that?
Update
_showList:
Widget _showList(){
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _sEv.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
},
child: Dismissible(
child: ListTile(
leading: //loremipsum,
title: //blablabla,
subtitle: //dolorsit,
),
),
key: UniqueKey(),
direction: DismissDirection.startToEnd,
background: Container(
alignment: AlignmentDirectional.centerEnd,
color: Colors.redAccent,
child: Icon(Icons.delete_rounded),
),
onDismissed: (DismissDirection direction) {
setState(() {
//my irrelevant code
});
}
),);
},
);
}
UPDATE 2
ScreenShot:
Just wrap the body of this page in SingleChildScrollView like this.
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Scaffold(
resizeToAvoidBottomPadding: false,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ TableCalendar(
//default code),
Divider(), _showList(),
],
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, color: Colors.white,),
onPressed: () => _showCity(context)
),
),
);
}

How to include a RaisedButton in a Container

I want a Raisedbutton that appears after the Container.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Galeria clase 1'),
),
body: Container(padding: EdgeInsets.all(8), child: galeria(array)),
floatingActionButton: FloatingActionButton(
onPressed: _optionsDialogBox,
tooltip: 'Pick Image',
child: Icon(Icons.add_outlined),
),
);
}enter code here
I tried this but there is the next error -> RenderBox was not laid out: RenderFlex#02bd4 relayoutBoundary=up1
body: Column(children: <Widget>[
(Container(
padding: EdgeInsets.all(8),
child: galeria(
array,
),
)),
RaisedButton(
child: Text("Guardar red"),
onPressed: () {
safeNeuralNetwork();
},
),
]),
galeria Function
Widget galeria(List<Uint8List> array) {
return StaggeredGridView.countBuilder(
crossAxisCount: 2,
itemCount: array.length,
itemBuilder: (BuildContext context, int index) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
color: Colors.deepPurple,
child: Column(
children: <Widget>[Image.memory(array[index])],
),
),
);
},
// staggeredTileBuilder: (int index) => new StaggeredTile.fit(1),
staggeredTileBuilder: (int index) => new StaggeredTile.fit(1),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
);
}
StaggeredGridView (or nearly any ScrollView) widget can't work with unbounded (infinite) height like in your case. You can't have a Column widget and a ScrollView inside it without using Expanded or something like that. Why? Because you need something to limit the maximum height of that widget. In this case we will use an Expanded widget. So go and modify your code like this:
body: Column(
children: <Widget>[
Expanded(
child: Padding(
child: galeria(array),
padding: EdgeInsets.all(8.0),
),
),
RaisedButton(
onPressed: () {
safeNeuralNetwork();
},
child: Text("Guardar red"),
),
],
),
With this we basically said: "Hey, go and render this column but please, stick a RaisedButton at the bottom and use the remaining space for the StaggeredGridView.".

Hw to substitute one specific Widget with another One once OnPressed is performed

I have 2 specific Widget which the first One has a RaisedButton which should be clicked and the widget with the RaisedButton will be substitute with another one.
this is my code:
Widget FundsWidget() {
return Container(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Devi acquistare dei crediti per poter vedere i Post di ${widget.user.name}',
style: TextStyle(fontSize: 12),
),
RaisedButton(
elevation: 10,
color: Colors.blue,
child: Text('Acquista Crediti'),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => PostGrid(),
),
),
),
],
),
);
}
and this is called into the main build method, once RaisedButton is clicked, should be substited by another one
Widget PostGrid() {
return Container(
height: 291,
child: GridView.builder(
controller: controller,
itemCount: widget.user.imageUrl.length + 1,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (BuildContext context, int index) {
if (index == widget.user.imageUrl.length) {}
return GestureDetector(
onTap: () => showDialog(
context: context,
builder: (context) => AlertDialog(
actions: [
Image.asset(widget.user.imageUrl),
Text(widget.user.name),
],
),
),
child: Card(
elevation: 5,
child: Image.asset(widget.user.imageUrl),
),
);
},
),
);
}
that at the moment is not into the build method.
how I can perform that?
I think you can use setState method inside your onPresesd and change a bool in it.
and check that bool to set suitable widget like below pattern:
class Test2 extends StatefulWidget {
#override
_Test2State createState() => _Test2State();
}
class _Test2State extends State<Test2> {
bool boolName = true;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child:boolName ?FontWeight:PostGrid ));
}
Widget FundsWidget() {
return Container(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Devi acquistare dei crediti per poter vedere i Post di ${widget.user.name}',
style: TextStyle(fontSize: 12),
),
RaisedButton(
elevation: 10,
color: Colors.blue,
child: Text('Acquista Crediti'),
onPressed: () {
setState(() {
boolName = false;
});
}
),
),
],
),
);
}
Widget PostGrid() {
return Container(
height: 291,
child: GridView.builder(
controller: controller,
itemCount: widget.user.imageUrl.length + 1,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (BuildContext context, int index) {
if (index == widget.user.imageUrl.length) {}
return GestureDetector(
onTap: () => showDialog(
context: context,
builder: (context) => AlertDialog(
actions: [
Image.asset(widget.user.imageUrl),
Text(widget.user.name),
],
),
),
child: Card(
elevation: 5,
child: Image.asset(widget.user.imageUrl),
),
);
},
),
);
}
}