Make Wrap children fill empty spaces - flutter-layout

I have implemented a Wrap (with WrapAlignment.center) with drag and drop. Users can insert and rearrange items (with text). It means I insert DragTarget around the items. But the DragTargets are small, meaning there is empty space at the edges.It makes it harder to drop, since the users must position the finger with precision. It would make much sense if I could make DragTargets fill the empty spaces, without affecting the layout of the main items.How can I do that?
This seems to be generally reasonable requirement for Wraps.
This is how I construct the Wrap children:
var wrap = Wrap(
runSpacing: 5,
children: children, alignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center);
wrap.children!.add(UnconstrainedBox(child: Row(children: [
createTarget(40, 20),
Draggable<Phrase>(
feedback: Text(...),
dragAnchorStrategy: draggableOffset,
child: Text(...)),
createTarget(40, 20),
], mainAxisAlignment: MainAxisAlignment.center)));
return
Container(
color: getYellow(),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
constraints: BoxConstraints(minHeight: 120),
child: Center(child: wrap));
createTarget
createTarget(double height, double width) {
return DragTarget<Phrase>(
builder: (context, candidateItems, rejectedItems) {
return Container(height: height, width: width,);
}});
So basically, the wrap childrens are rows with [DragTarget, widget, DragTarget] to make sure there DragTargets are always present at the sides of my widgets. Naturally that is no going to make the DragTargets fill. I don't even know where to begin.
Edit:
Here is implementation of wrap that fills horizontally, witch centered Text. I just need to add the DragTargets on each side, filling up empty horizontal space, with Wrap in one line as before
var wrap = Wrap(
children: [Text('Hi')],
alignment: WrapAlignment.center,
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center);
return
ConstrainedBox(
constraints: BoxConstraints(minHeight: 120, maxHeight: 200, minWidth: double.maxFinite),
child: Container(color: Color(0x33000000), child: wrap,));

Related

[FLUTTER]: Cut text depending of height of ListTile

I have the following widget. The problem is I need to cut my subtitle string depending on the height and width of the ListTile. Now, height of the ListTile depends on length of substring I have. Longer is my substring, longer is the height of the ListTile. It looks awkward. Putting ListTile inside Container widget is good, but the substring overlaps the next ListTile content. it looks terrible too. Another solution was using FittedBox, I thought. But, I need the fixed size of each ListTile, without changing the fontSize. That's why the FixedBox doesn't fit me:) It changes the fontSize. I need to cut my string when it reaches the end of the ListTile. How can I solve this?
InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ProductScreen(product),
),
);
},
child: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 4.0,
),
child: ListTile(
title: Text(
product.title.toUpperCase(),
style: Styles.listTitleStyle,
),
subtitle: Text(
product.description,
style: Styles.listBodyStyle,
),
),
),
const Divider(height: 1.0),
],
For your text widget add something like this,
subtitle: Text(
maxLines: 2, //customize your number of lines
overflow: TextOverflow.ellipsis, //add this to set (...) at the end of sentence
product.description,
style: Styles.listBodyStyle,
),

Flutter: Fixed bottom button, central dynamic TextField that moves with keyboard popup

Many variations of this question exist with solutions. I have been unable to find an adequate solution. Is it possible to fix a button at the bottom of the screen which the keyboard is allowed to overlay, but also moves the other text fields up?
I've attached a screenshot example
My current solution works, but the space between the textfield and the post button is a fixed SizedBox height. This shifts the post button around on different screen heights, which is hack.
Is there a way to do something similar to how an Expanded widget fills the empty space, but within a ListView? Expanded throws an error if parent is a ListView, and a parent of Flex would squeeze all the elements when the keyboard comes up.
Widget Layout: (super simplified)
return ListView(
children: <Widget>[
Container(//The photo boxes at top
height: fixed,
),
ListTile(
leading: CircleAvatar(),
title: Container(child: TextField(),),
),
SizedBox(
height: screenHeight * 0.5 - 225
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: RaisedButton(
onPressed: doThing
child: Text('POST'),
),
),
],
),
],
);

How to make a custom table widget in flutter?

I'm making a custom widget for showing a weekly schedule. I want it to look somewhat like a normal table, with the days in the header and the time of day on the vertical axis. Then I want to add events in the calendar, but as an event can span several cells, I can not use the built in table (it has no col/row span).
So I started to make my own table using CustomPaint. It went OK until I came to the header part, which I am stuck on the layout with my idea. In the code I supplied you can see that the header will have the same width as the side bar (with time) and the WeekView (the CustomPaint table). This means I have no idea how to align the header (Monday, Tuesday etc..) with the grid in the WeekView as the space the side bar takes up is not known. And as I want the side bar to scroll with the table, it has to be inside the scrollview. Can I solve this any other way? Maybe with slivers (that I know very little of yet)?
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
WeekSelector(
week: controller.week,
onPrevPressed: onPrevPressed,
onNextPressed: onNextPressed,
),
WeekHeader(),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
child: Row(
children: <Widget>[
Text("09:00"), // here will be a bar for the time
Expanded(
child: WeekView(
startHour: 9,
endHour: 18,
),
),
],
),
),
),
),
],
);
}

Widget not displaying on Stack and there is no Ink effect on InkResponse

I am working on my first Flutter App and I have encountered two problems.
- The Container widget housing my Image widget does not get displayed on the Stack widget.
There is no Ink effect when tapping the InkResponse container
I have tried rewriting the Container to display the image and by using Image.Network for the url instead of assets but to no avail.
final appLogo = new Container(
child: new Image(
image: new AssetImage('assets/discord.png')
),
);
List<Widget> _getApps(List apps) {
List<Widget> _appWidgets = <Widget>[];
// make a Grid tile of the Apps
for (int i = 0; i < apps.length; i++) {
_appWidgets.add(
new InkResponse(
child: Center(
child: new Stack(
children: <Widget>[
appLogo,
new Container(height: 102, width: 102, color: Colors.red),
],
)
)
),
);
}
return _appWidgets;
}
appLogo should be displayed on the red box (Container) from my expectation and there should be a Splash when I tap on the InkResponse widget.
First of all, your image needs to be added to your pubspec.yaml file like so:
flutter:
assets:
- images/
Once you have that, you can access all your images inside "/images" or any folder name inside your project you want. Now you can access your image in this way:
Image.asset("images/myimage.jpg") // again, this in an example
Bear in mind that images are not affected by the ripple material effect, only the background of it (if the image is inside a bigger container with "empty" space). Second, you need an InkWell with onTap: method in order to show the ripple, to finish everything, you need a Material widget as this one provides the necessary effects.
So, if you want to see a the ripple effect behind the image and having it inside a Stack, you'll need to do something like:
Material(
child: Stack(
children: <Widget>[
InkWell(
onTap: () {}, // The ripple only shows up if you have a onTap method.
child: Container(
height: 300, // 300 is a random value but has bigger height than the image itself.
child: Image.asset("images/myimage.jpg"),
),
),
],
),
)

Flutter LinearLayout weight alternative

I'm Android developer learning flutter. I want my screen looks like this:
|---------------------------------|
| |
| Babe I miss you |
| |
|---------------------------------|
"Babe" and "I miss you" should be two separate elements.
With Android xml I would solve this with LinearLayout and two TextViews with weight=1 for each. What's the alternative for flutter?
P.S. I know that you can solve it with FrameLayout or with RelativeLayout but I want closest to LinearLayout behavior.
Flutter's Row widget is equivalent to android's LinearLayout with android:orientation="horizontal",
and Column widget is equivalent to android's LinearLayout with android:orientation="vertical".
flex property of Flexible widget is equivalent weight property, you can wrap the Text widgets in a Flexible widget and specify the flex property.
Example:
new Row(
children: <Widget>[
new Flexible(child: new Text("Babe"), flex: 1,),
new Flexible(child: new Text("I miss you"), flex: 1,)
],
)
Using an Expanded widget can also produce a LinearLayout effect like so:
Row(
children: <Widget>[
Expanded(
child: Container(child: Text("Babe")),
flex: 2,
),
Expanded(
child: Container(child: Text("I don't miss you"),alignment: Alignment.centerRight),
flex: 2,
),
],
),
Considering the layout in the question you want to display both the texts at the end of screen one at the beginning other at the end you can simply add MainAxisAlignment.spaceBetween property to the row
so you need to modify your code to
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new Text('Babe'),
new Text('I miss you')
]
)
I dont understand why first answer was accepted because it simply adds both the text to right most end of the screen,
Tip: Incase you need some padding around each text wrap each of the text in a Container and add desired padding and margin
You can use row with MainAxisAlignment which will allow you to place elements as per your expectation
Widget textSection = new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new Text('Babe'),
new Text('I miss you')
)
)
Screenshot:
Use Spacer which comes with a flex property (defaults to 1)
Row(
children: <Widget>[
Text('Hello'),
Spacer(), // <-- Use this
Text('World'),
],
)
new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget> [
new Text('Babe', style: AppStyle.AppBarTextStyle,),
new Text('I miss you',style: AppStyle.AppBarTextStyle,)
]
)
)
We can use FractionallySizedBox widget to give weight sum for both width and height.
FractionallySizedBox(
heightFactor: .5,
widthFactor: 1.0,
alignment: Alignment.topCenter,
child: child,
)
For more info:
Link

Resources