How do I place my widget in the top Center location using Media Query in Flutter? - flutter

I have the following dial located at the center of my screen.
I have called three different part to construct this dial.
However it seems to be stuck in the center of my screen and I want to shift it to the top center portion. Ive tried changing the alignments but it doesn't seem to work.
This is my code:
This is the dependency I'm using: https://pub.dev/packages/flutter_neumorphic
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
pedometerOuterDial(context),
pedometerInnerDial(context),
Center(child: stepText()),
],
);
}
Widget stepText() {
return Text(
'4800\nSteps',
style: khomeStyle.copyWith(color: kOrange),
);
}
Widget pedometerOuterDial(context) {
final percentage = 30.0;
return Padding(
padding: const EdgeInsets.all(80.0),
child: Align(
alignment: Alignment.topCenter,
child: Neumorphic(
boxShape: NeumorphicBoxShape.circle(),
padding: EdgeInsets.all(10),
style: NeumorphicStyle(
depth: NeumorphicTheme.embossDepth(context),
),
child: CustomPaint(
painter: NeuProgressPainter(
circleWidth: 20,
completedPercentage: percentage,
defaultCircleColor: Colors.transparent,
),
child: Center(),
),
),
),
);
}
Widget pedometerInnerDial(context) {
return Align(
child: Neumorphic(
boxShape: NeumorphicBoxShape.circle(),
padding: EdgeInsets.all(80),
style: NeumorphicStyle(
color: Colors.white,
depth: NeumorphicTheme.depth(context),
),
),
);
}
Also I haven't used Media Query here for any of the dials, so will that be an issue for displaying on other devices?

Since you are using a stack widget, the best way to do this is to use a positioned widget. You can place the widget on top by wrapping it with Positioned and setting the top property to 0.
Here is an example:
Positioned(
top:0,
child:YourWidget(),
),
Alignment won't work for the stack widget because it only aligns the items when there are extra space around it. Example: It works in a Column or Row since they occupy space and allow the widgets inside it to be placed and move around the occupied space.

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 align two widgets in same position on stack

I have 2 widget in stack. One of them is aligned in center. And the widget which is on the top is other stack. And I want show second widget with first widget's top and left position. Here is the explain:
The yellow area is my stack. And first widget is setted like Center(child: myFirstWidget). My second widget is referenced from here it's a resizable widget so it's an another stack and it's childs are "positioned". So I need to set top and left value for initialize. But my main stack filled page So when I set my second widget's top and left to 0. It's shown as below.
But I want to show align it to centered child's top like:
My code snip:
child: Container(
color: Colors.red,
child: Stack(
children: [
Center(
child: Image.file(
File("myfilepath"),
),
),
ResizableWidget(
child: Container(
color: Colors.blue,
),
),
],
),
),
You can adjust the position of the widgets with the Position widget like this:
Positioned(
child: ResizableWidget(
child: Container(
color: Colors.blue,
),
),
top: 80,
right: -5,
),
The value of top and right are just random values, you should check what works for you!
You should make Center the parent of the Stack.
The Stack will be positioned at the center of its parent because of Center, it will get the dimensions of its biggest childs (height and width) and will position other childs according to the alignment value.
Edit : I modified the code to include a placeHolder image. Here I gave it a 6000x2000 size but you can change it to whatever value you want. Code is working as expected, see capture below.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Stack(
alignment: AlignmentDirectional.topStart,
children: [
Image.network('https://via.placeholder.com/6000x2000'),
SizedBox(
height: 50,
width: 50,
child: Container(
color: Colors.green,
))
],
),
),
);
}

How do I stop overflow

I am still new to coding, I have created multiple textbutton.icon's but they overflow. How do i stop the overflow. Even if i put is in a row or column it still overflows. I also would like to put more spacing between each row of buttons but that just makes it overflow more. Here is the multiple class code:
class home_buttons {
List<Widget> jeffButtons = [
Button1(),
Button2(),
Button3(),
Button4(),
Button5(),
Button6(),
Button7(),
Button8(),
Button9(),
];
}
Here is the button code:
class Button1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 9.0, 0.0, 0.0),
child: TextButton.icon(
onPressed: () => {},
icon: Column(
children: [
Icon(
Icons.search,
color: Colors.white,
size: 75,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Contact Us',
style: TextStyle(
color: Colors.white,
),
),
),
],
),
label: Text(
'', //'Label',
style: TextStyle(
color: Colors.white,
),
),
),
);
}
}
You can wrap your widgets with the SingleChildScrollView to enable scrolling.
Or if you want to fit the screen inside a Column or Row Widget you can wrap individual widgets with a Flexible Widget
Flutter listview normally have undefined height. The total height of listview is defined based on the items in the list. So when you declare listview directly you get overflow issue.
So as a solution you need to specify the height for the outer container, or use sizedbox to define the height.
Specifying height will solve your issue of overflow. To provide space between buttons you can also wrap that in a container and use the benefit of margin or padding to handle it efficiently.
Please find this code snippet to use Media to find height of device
Container(
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: SingleChildScrollView(
child: Column(
children: [
Here instead of SingleChildScrollView You can use listview or listbuilder which will solve your overflow issue
Hope this helps. Let me know If you want more details. Thanks

Making a 2x2 grid in Flutter

I'm trying to create a 2x2 grid for displaying some info in cards. Disclaimer: I'm totally new to Dart and Flutter, so expect a lot of ignorance on the topic here.
These cards should have a fixed size, have an image, display some text... and be positioned from left to right, from top to bottom.
First, I tried to use the Flex widget, but it seems to only work horizontally or vertically. Therefore, my only solution was to use two Flexes, but only showing the second when the amount of elements is higher than 2 (which would only use one row).
Then, I tried using GridView, but it doesn't work in any possible way. It doesn't matter which example from the Internet I copy and paste to begin testing: they just won't show up in the screen unless they're the only thing that is shown in the app, with no other widget whatsoever. I still don't understand why that happens.
This is my current code:
First widgets in "home_page.dart":
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 30)),
Text(
'App test',
style: TextStyle(fontSize: 24),
),
EventsList(key: new Key('test')),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
The "EventList" part is a widget that should represent the grid functionality I explained before. This class gets some info from a service (which currently just sends some hardcoded info from a Future), and paints the given widgets ("Card" items, basically) into the EventList view:
class _EventsListState extends State<EventsList> {
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Event>>(
future: new EventsService().getEventsForCoords(),
builder: (context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Flex(
direction: Axis.horizontal,
verticalDirection: VerticalDirection.down,
mainAxisAlignment: MainAxisAlignment.center,
children: generateProximityEventCards(snapshot.data),
));
} else {
return CircularProgressIndicator();
}
});
}
List<Card> generateProximityEventCards(List<Event> eventList) {
// Load Events from API
print(eventList);
// Render each card
return eventList.map((Event ev) {
return Card(
child: Padding(
padding: EdgeInsets.only(bottom: 15),
child: Column(
children: <Widget>[
Image(
fit: BoxFit.cover,
image: ev.imageUrl,
height: 100,
width: 150,
),
Padding(
child: Text(ev.name),
padding: EdgeInsets.only(left: 10, right: 10),
),
Padding(
child: Text(ev.address),
padding: EdgeInsets.only(left: 10, right: 10),
),
],
),
));
}).toList();
}
}
This is how it currently looks:
As I said before, I understand that the Flex widget can't really get that 2x2 grid look that I'm looking for, which would be something like this (done with Paint):
So, some questions:
How can I get a grid like that working? Have in mind that I want to have more stuff below that, so it cannot be an "infinite" grid, nor a full window grid.
Is it possible to perform some scrolling to the right in the container of that grid? So in case there are more than 4 elements, I can get to the other ones just scrolling with the finger to the right.
As you can see in the first image, the second example is bigger than the first. How to limit the Card's size?
Thank you a lot for your help!
The reason the gridview was not working is because you need to set the shrinkWrap property of theGridView to true, to make it take up as little space as possible. (by default, scrollable widgets like gridview and listview take up as much vertical space as possible, which gives you an error if you put that inside a column widget)
Try using the scrollable GridView.count widget like this and setting shrinkWrap to true:
...
GridView.count(
primary: false,
padding: /* You can add padding: */ You can add padding const EdgeInsets.all(20),
crossAxisCount: /* This makes it 2x2: */ 2,
shrinkWrap: true,
children: generateProximityEventCards(snapshot.data),
...
Is this what you exactly want?
do let me know so that I can update the code for you
import 'package:flutter/material.dart';
class List extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Text('Inicio', style: TextStyle(color: Colors.black, fontSize: 18.0),),
),
body: GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: List.generate(
50,//this is the total number of cards
(index){
return Container(
child: Card(
color: Colors.blue,
),
);
}
),
),
);
}
}

Image to take the height and with of parent element

so today i did good with advancing in learning to make an app with flutter , i made a ListView , but the image didnt take the full height and with of the parent element , i tried some solutions but it didnt workout
this is the class
class FlowersItem extends StatelessWidget {
final String imgAssetPath;
FlowersItem({this.imgAssetPath});
#override
Widget build(BuildContext context) {
return Container(
width: 200,
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 30),
margin: EdgeInsets.only(right: 16),
decoration: BoxDecoration(
color: Color(0xff29404E),
borderRadius: BorderRadius.circular(12)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(children: <Widget>[
ClipRect(
child: FittedBox(
child: Image.asset(imgAssetPath),
fit: BoxFit.fill,
),
)
],)
],
),
);
}
}
List<FlowersItem> flowers = [
FlowersItem(
imgAssetPath: 'assets/images/flower1.jpeg',
),
FlowersItem(
imgAssetPath: 'assets/images/flower-pot.png',
),
FlowersItem(
imgAssetPath: 'assets/images/flower-pot.png',
),
FlowersItem(
imgAssetPath: 'assets/images/flower-pot.png',
),
FlowersItem(
imgAssetPath: 'assets/images/flower-pot.png',
),
];
Have you tried BoxFit.cover? I think that's what you are looking for.
It generally works for me when I want to fill out and entire box with an image.
have you tried Expanded class?
So, Expanded class is A widget that expands a child of a Row, Column, or Flex so that the child fills the available space.
you could find the documentation here.