Flutter - How to create a vertical line between two widgets - flutter

I need to create a vertical line between two widgets like this: https://imgur.com/a/22ybF6o
I could do it but for a fixed size. If this size changes, layout got messy like this: https://imgur.com/a/kO9NXlJ
Here's my code:
Widget listItem(TripsData item) {
var startDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.start));
var endDate = DateFormat('dd/MM/yy - HH:mm').format(DateTime.parse(item.end));
return Card(
child: Stack(
children: <Widget>[
drawDestinationLine(Colors.red),
Column(
children: <Widget>[
ListTile(
leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
),
const Padding(padding: EdgeInsets.only(bottom: 2.0)),
ListTile(
leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
),
],
),
],
),
);
}
Does someone have a solution to help me with this?
Let me know if need more code, but StackOverflow didn't let me put more code here..

I used the package timelines 0.1.0 which makes this easily possible
Check on pub.dev and the corresponding Github repo for nice examples.
One of the sample use-cases looks like what you are looking for:

In this case you should use the Stack, Positioned, and ConstrainedBox widgets to create the desired arrangement.
Something like this pseudocode, you will need to supply correct coordinates:
Stack ( children: [
Positioned ( left: 0.0 , top : 0.0 , child:
ListTile (leading: drawDestinationCircle('A', Colors.blue),
title: Text(startDate),
subtitle: Text(item.locationStart),
)),
Positioned ( left: 0.0 , bottom : 0.0 , child:
ListTile (leading: drawDestinationCircle('B', Colors.blue),
title: Text(endDate),
subtitle: Text(item.locationEnd),
)),
Positioned ( left 20.0 , top : 20.0
, child: ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 5.0,
minWidth: 5.0,
maxHeight: 30.0,
maxWidth: 5.0,
),
child: new DecoratedBox(
decoration: new BoxDecoration(color: Colors.red),
)
),
)
]);

Related

Flutter - How can I design List Tile & List View

This is the result that I want.
This is the current output that I have.
How can I achieve this result specifically the lines that are present in between the list tiles? I am using a ListView to show the rules. Below is the code for the ListTile that I am using.
Widget ruleTile(String title) {
return ListTile(
contentPadding: EdgeInsets.zero,
leading: Image.asset(
"assets/images/sun.png",
width: 40.w,
),
title: Text(
title,
style: MyTextStyle.littlesmaller,
),
);
}
You can use Stack and dotted_line package combo to create something like that:
Stack(children: [
DottedLine(
direction: Axis.vertical,
lineLength: linelength,
lineThickness: 1.0,
)
// You ListTile Code
],)
Thanks to #pmatatias comment, I figured it out. This is the updated code I used to get the desired output.
Widget ruleTile(String title, num index) {
Widget connector = const DashedLineConnector(
color: Color(0xFFFACC15),
gap: 3,
);
return TimelineTile(
node: TimelineNode(
indicator: Image.asset(
"assets/images/sun.png",
width: 40.w,
),
startConnector: index == 0 ? null : connector,
endConnector: index == rulesList.length - 1 ? null : connector,
),
nodeAlign: TimelineNodeAlign.start,
contents: ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
title,
style: MyTextStyle.littlesmaller,
),
),
);
}

How to have Label text with graphics over image(product image of e commerce app) in flutter?

I am trying to get a text label with graphics over the image. Labels like new arrival, best seller, limited, on sale just like on the pic attached.
enter image description here
Here's what i think the skeletal layout would be :
return Stack(
children: [
Card(
color: Colors.black54,
child: Image.asset('assets/xyz.png'),
),
Align(
//for bottomRight
alignment: Alignment.bottomRight,
child: Image.asset(
'assets/fireimg.png',
), //can be an SVG converted to png
),
Align(
//for topLeft
alignment: Alignment.topLeft,
child: Image.asset(
'assets/label.png',
), //can be an SVG converted to png
),
],
);
Feel free to give the Padding of your choice.
it has so much code to write , so i will give some examples to achieve that output
in this image ,i mentioned 0 and one .
for all 1
solution 1
you can use image like this way
Stack(
children: [
Container(
width: 200,
height: 200,
color: Colors.amber,// added only for view this example
child:Image() // add Product image here
),
Positioned(
top: 20, //change according to your use case position
left: 0,// change according to your use case position
child: Container(
color: Colors.black, // added only for view this example
decoration: BoxDecoration(image: ),// add label image here
width: 100,
height: 50,
child: Row(
children: [Text('hi')],
),
))
],
)
solution 2
you can use custom paint for label layout
not that
in both solution you have to use stack and position widgets , you can control position according to your use case
for all 0
you can use RotationTransition widgets to achieve this
not that
you have to use stack and position widgets , you can control position according to your use case
for the vertical Text
use this example
String exText = "meta";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('hi'),
),
body: Container(
width: 200,
height: 200,
color: Colors.amber,
child: Column(
children: exText.characters
.map((e) => Container(
child: Text('$e'),
))
.toList()),
),
out put will be

Flutter - How to wrap list of chipsets with a button horizontally together

I'm new to flutter and have been trying to get a list of chipsets wrapped in a Wrap widget with the ability to add more of them through a button shown in the image. However, the button isn't able to wrap along with the chipset horizontally. Below is an image of the design to make it clearer.
Code:
Container(
child: Wrap(
children: [
Container(
child: Wrap(
children: _chipsetList,
),
),
SizedBox(width: 2),
Container(
height: 35,
width: 35,
child: FittedBox(
child: FloatingActionButton(
heroTag: null,
elevation: 0,
shape: StadiumBorder(
side: BorderSide(width: 2.0)),
onPressed: () {
_getMoreChips(context);
},
child: Icon(Icons.add),
),
))
],
),),
I tried to experiment with SingleChildScrollView property or with Wrap direction but in vain. What could be a way to get this design working?
Seems you want to put chips and the button in the single wrap. To do so, combine them in a single list and use this list as wrap's children
List<Widget> items = List.from(_chipsetList); // copy
Widget button = FloatingActionButton();
items.add(button);
Wrap(
children: items,
)
Or, using spread operator
Wrap(
children: [
..._chipsetList,
FloatingActionButton(),
],
)

Flutter: Overlap Edge of Widget with second Widget

I want to overlap the bottom edge of a widget with another widget so that it looks like this:
I am using a stack to position the arrow button over the card. At the moment I just set the position with an invisible box above it. The issue is that this method only works for that exact resolution - it should be screen size independent.
The necessary code for the widget:
Stack(
children: <Widget>[
Container( //background
height: 100,
width: 100,
),
FloatingActionButton(
child: Icon(Icons.arrow_forward),
onPressed: () {},
)
],
)
Update - April 2021
You can no longer use the overflow property in a Stack widget as it has been deprecated. Use clipBehaviour instead. Source: Flutter docs
You can use the Stack and Positioned widget to achieve this UI.
Stack(
clipBehavior: Clip.none,
children: <Widget>[
Container(
color: Colors.amber,
height: 150,
width: 150,
),
Positioned(
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
print('FAB tapped!');
},
backgroundColor: Colors.blueGrey,
),
right: 0,
left: 0,
bottom: -26,
),
],
),
Output:
Update - March 2022
The Area which is outside of Stack won't be clickable due to the platform limitation, and that is how the Stack widget works.
You can learn more about the same in this issue.
As of November 2019 I'd like to add a second solution:
Using package: https://pub.dev/packages/assorted_layout_widgets
var widget1 = ...;
var widget2 = ...;
ColumnSuper(
children: [widget1, widget2],
innerDistance: -26,
);
The difference from this solution to the one using Stack is that Positioned widgets in a Stack don't occupy vertical space. However, the ColumnSuper will have the size of all of its children widgets. Note I am the author of this package.
You could try my package (signed_spacing_flex). It's exactly the same as a normal Column (or Row and Flex). But it lets you set negative spacing which causes its children to overlap. You can also set which children should be on top when they overlap.
In your case it would be something like:
SignedSpacingColumn(
spacing: -16.0,
stackingOrder: StackingOrder.lastOnTop,
children: [
Container(
height: 100,
width: 100,
color: Colors.red,
),
FloatingActionButton(
child: const Icon(Icons.arrow_forward),
onPressed: () {},
)
],
)
It works with expanded children if you need.

Title not displaying correctly on flexibleSpaceBar

I'm trying to show the title but as you can see, it does not do it correctly.
I tried to put softWrap to true but it is still the same.
The code is from flutter contacts_demo gallery
flexibleSpace: FlexibleSpaceBar(
title: const Text('Fantastic Beasts And Where To Find Them'),
background: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(
'people/ali_landscape.png',
package: 'flutter_gallery_assets',
fit: BoxFit.cover,
height: _appBarHeight,
),
// This gradient ensures that the toolbar icons are distinct
// against the background image.
const DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment(0.0, -1.0),
end: Alignment(0.0, -0.4),
colors: <Color>[Color(0x60000000), Color(0x00000000)],
),
),
),
],
),
),
You can use a ConstrainedBox along with MediaQuery.of(context).size.width
final mediaQuery = MediaQuery.of(context);
final availableWidth = mediaQuery.size.width - 160;
along with
title: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: availableWidth,
),
child: const Text('Fantastic Beasts And Where To Find Them'),
),
I dug into a FlexibleSpaceBar sources and at least now I understand what happens. Turns out that in an expanded state title is scaled up to be 1.5 of its size, so naturally it will overflow offscreen. As user scrolls up, title is scaled down towards its source size of 1.0. At this size it will sit in the top toolbar.
Maybe this information will help someone to base their workarounds on until this is fixed.
I wondered why my hack of wrapping title in ConstraintedBox with maxWidth: MediaQuery.of(context).size.width didn't work. Now I know: I must divide this maxWidth by 1.5.
See also this bug on the Flutter github issue tracker.
The title length in combination with the font size you've set have no way to be displayed on a single line on smaller devices, for obvious reasons.
You may want to play with MediaQuery.of(context).size.width to get the device width and set the header text fontSize accordingly as a fraction of that. Try in the emulator to see which works best for your text length.
const Text(
'Fantastic Beasts And Where To Find Them',
style: TextStyle(fontSize: MediaQuery.of(context).size.width/ SOME_NUMBER),
),
Or just hardcode some font sizes based on some width intervals:
int _getFontSize(BuildContext context) {
int width = MediaQuery.of(context).size.width;
if (width < 300) {
return 10;
} else if (width < 600) {
return 13;
// etc ...
} else {
return 18;
}
}
...
const Text(
'Fantastic Beasts And Where To Find Them',
style: _getFontSize(context),
),
Thanks to dimsuz's answer it is possible to eliminate the upscaling of text in a FlexibleSpaceBar:
SliverAppBar(
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {},
),
],
floating: true,
pinned: false,
snap: false,
flexibleSpace: FlexibleSpaceBar(
title: Text(title, style: TextStyle(fontSize: 20.0 / 1.5)),
centerTitle: false,
background: Container(
color: Theme.of(context).primaryColor,
),
),
expandedHeight: 120,
),
The 20.0 in fontSize I took from here.