How to compose Flutter code not being stretched in height - flutter

I have some experience in Java code, and I am familiar with linear code style where command follows by command, but I can't understand how to write Flutter code with inherited widgets style - my code tends to have hundreds of lines for every widget.
I faced with few constraints:
line length limited to 80 chars
trailing comma is required
So my average code looks like this one:
child: Column(
children: <Widget>[
if (widget.headerWidget == null)
const SizedBox(
height: 14,
),
AnimatedContainer(
foregroundDecoration: BoxDecoration(
color: getForegroundColor(),
),
child: Row(
children: <Widget>[
(widget.isFeed)
? (widget.isNew
? Flexible(
flex: 0,
child: Padding(
padding:
const EdgeInsets.only(
left: middlePadding,
top: middlePadding,
),
child: Container(
height: xSmallPadding,
width: xSmallPadding,
decoration: BoxDecoration(
color: AppColors.magenta,
borderRadius:
BorderRadius.circular(
xxSmallPadding,
),
),
),
),
)
: SizedBox(
width:
widget.isViewed ? 0 : 24.0,
))
: const SizedBox(),
And simple widget become 500+ lines in height. How to avoid it?

you can split your code to small widgets (in flutter every thing is a widget) , there's an easy way for that in android studio you can right click on a widget name like a row and then choose refactor after this choose extract flutter widget , by this you will get all the work done and it will be converted to a flutter widget class ,
also you can extract flutter method but i preferer the flutter widget class so you move it to another file.

Related

I want to use remaining available space on my page in Flutter

In the screen, I have a Column, it has a cusotm made widget of specific height. Then, I have Expanded, in which I have a TabBar which has three tabs.
In one of those tabs, I want to show a list. First, I have a padding, which contains column. The column has some text, which should remain at top and the list should be shown in the space which is remaining. I am using Expanded for that, but it is not working.
I can't use ListView directly, and also can't use expanded. It is only working when I am giving it a container of fix size. Now, in different screens, it will look different. So, I want to take all of the remaining space and build the list there. Code for reference -
Here is the doubts screen, which is one of the tabs of main screen -
import 'package:flutter/material.dart';
import 'package:my_board_plus/size_config.dart';
import 'package:my_board_plus/styles.dart';
import '../../api_handling/api_fetch/fetch_doubt_questions.dart';
import '../../data_models/doubt_question_model.dart';
class NewDoubtsScreen extends StatefulWidget {
const NewDoubtsScreen({Key? key}) : super(key: key);
#override
State<NewDoubtsScreen> createState() => _NewDoubtsScreenState();
}
class _NewDoubtsScreenState extends State<NewDoubtsScreen> {
late Future<List<DoubtQuestionModel>> doubtQuestionsList;
#override
void initState() {
doubtQuestionsList = fetchDoubtQuestion();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor2,
floatingActionButton: Container(
width: getProportionateScreenWidth(130),
height: getProportionateScreenHeight(50),
decoration: BoxDecoration(
color: brandPurple,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Center(
child: Text(
'? My Doubts',
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
),
),
body: Padding(
padding: EdgeInsets.only(top: 8.0, left: 5),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Trending Doubts',
style: TextStyle(
color: Colors.white,
),
),
Text(
'View all',
style: TextStyle(
color: brandYellow,
decoration: TextDecoration.underline
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
height: getProportionateScreenHeight(530),
width: double.infinity,
color: Colors.red,
),
),
],
),
),
);
}
}
The red area that you are seeing is the one. I want it to occupy whole area available in the phone screen, so I can show list in it which should be scrollable. In this case, it is occupying all, but in different screens, it might not. So, please give me some suggestions.
You can try to give the height of the container like
height: double.infinity
Or you can give the height of it with substracting the other height from the screen size like
height: MediaQuery.of(context).size.height - getProportionateScreenHeight(50) //the heigth size that you give the other widget that top of it
try to wrap your Padding widget with the Expanded widget,
Expanded widget in column will take the rest of the space of the screen.
also no need to give height to Container widget, so you can remove getProportionateScreenHeight(530) this one

Flutter adding icon right after a long text

I want to add a tapable icon right after a long text. I need to use Text widget since I'm using textDirection and maxLines params.
Any ideas?
The problem:
What I need to get:
as Karen said it we need to use RichText.
Text.rich(
TextSpan(
text:
"I want to add a tapable icon right after a long text. I need to use Text widget since I'm using textDirection and maxLines params.",
children: [
WidgetSpan(
child: Icon(
Icons.error_outline,
color: Colors.red,
),
),
]),
),
the one way is to get char code of an icon, take a look at this answer for more details.
https://stackoverflow.com/a/63479589/10127437
Use a stack, let me show you...
Container(//Stack Widget needs space to work so be sure to add a container that gives it
width: double.infinity, //this makes the container match with the screen width
height: 200,
color: Colors.red,
child: Stack(
children: [
Positioned(//This widget gives position to your button
top: 100,//This will create a space on top
left: 0,//This will create a space on left
child: Container(//Your Container and text widget here
margin: EdgeInsets.only(left: 100),
height: 100,
width: 200,
color: Colors.blue,
child: Text(
"This is my text, my text takes more than one line, I want to present my Icon at the end of this text"
),
)
),
Positioned(
top: 140,
left: 150,
child: IconButton(//Put here your icon widget
iconSize: 30,
icon: Icon(CupertinoIcons.arrow_left_circle_fill),
color: Colors.blue,
)
),
],
),
)

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(),
],
)

How to align an item to the bottom of a list?

I'm trying to make an item go to the bottom of a list. I've tried using Expanded with a child of SizedBox. I've also tried the Align widget. It works with a Column, but not if the parent is a SingleChildScrollView.
What it should look like:
What it does look like:
Code (what it does look like):
return Scaffold(
backgroundColor: Color(0xFFE9E9E9),
body: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16),
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: _SettingsList(tournamentId: tournamentId),
),
Expanded(child: const SizedBox()),
Align(
alignment: FractionalOffset.bottomCenter,
child: buildDeleteTournamentButton(),
),
],
),
);
I think the problem is that you are using the Expanded or Align widget as a child of the list view so it tries to put the widget directly below the other ones. To achieve the first design I would recommend one of this two ways:
Replace your ListView with a Stack and use Align to align your "Delete tournament"-Widget at the bottom.
Replace your ListView with a Column and wrap the Container in an Expanded. Place your "Delete tournament"-Widget as the second child of the Column.
I really hope I could help.

Column widget draws a line between children when they are wrapped in specific widget with decoration. How can i cure this?

The problem is visible on the attached screenshot.
Code of a main widget:
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
child: Decor(
child: Container(),
),
flex: 1,
),
Flexible(
child: Decor(
child: Container(),
),
flex: 6,
)
],
);
Code of a Decor widget:
Container(
decoration: BoxDecoration(
color: COLOR,
),
margin: const EdgeInsets.symmetric(
horizontal: MEDIUM_PADDING,
),
padding: const EdgeInsets.all(MEDIUM_PADDING),
width: 300.0,
child: child,
);
Answering in advance "Why would you even need to do such a Decor Widget"? Both flexibles will be populated with data of some sort. Second flexible will be with a ListView inside and the first one will be a "Header" for what is inside a ListView. Data is retrieved from server every 10s, so the main widget is wrapped with a StreamBuilder.
Problem is that StreamBuilder cannot be shrinked to the size of its child, whereas ListView can, so I wrap both "Header" and a ListView in Decor so that grey background color doesn't take all available space on a screen which than produces black line seen on a screenshot?
So the question is: is there a way either to remove the black line between two widgets in a column?
Also, if you know magic of how to shrink StreamBuilder to the size of its child please answer here too.
Ok I know that this is not a very nice solution and more like workaround but I think the only way to get rid of the line is to set border color of the container in your Decor widget
Container(
decoration: BoxDecoration(
color: COLOR,
border: Border.all(width: 0, color: COLOR) //added line
),
margin: const EdgeInsets.symmetric(
horizontal: MEDIUM_PADDING,
),
padding: const EdgeInsets.all(MEDIUM_PADDING),
width: 300.0,
child: child,
);
First I thought setting border width to 0 will help it but that didn't work.. Color did