Create Center Aligned Button Menu For different Device Flutter - flutter

I have a problem with this layout. I have a menu button with 6 item and I use a grid for it( I disable the scroll function). When I try it in my Poco F1, it place right in the center of the screen. But when I use a phone with bigger screen, the menu is slightly in the left side of the screen. Is there any way to make it in the center of the screen despite different screen size?
Here is the picture when using Pixel 3 XL
This is my code
Widget _gridView (BuildContext context) {
double cardWidth = MediaQuery.of(context).size.width / 2;
double cardHeight = MediaQuery.of(context).size.height * 31/100;
return GridView.count(
shrinkWrap: true,
childAspectRatio: cardWidth / cardHeight,
crossAxisCount: 2,
scrollDirection: Axis.horizontal,
mainAxisSpacing: 5,
crossAxisSpacing: 3,
children: List.generate(6, (index) {
return
Center(
child: Container(
alignment: Alignment.center,
child:
SizedBox(
child: Column(
children: [
InkWell(
onTap: (){
if(index == 0)
Navigator.of(context).push(new MaterialPageRoute(builder: (context) => new DoctorList()));
if(index == 1)
launchWhatsApp();
if(index == 2)
launchWhatsApp();
if(index == 5)
showMenu(context);
},
child: Container(
width: 80,
height: 80,
child: Image.asset(icons[index]),
),
),
SizedBox(
height: 5,
),
Text(teks[index], style: TextStyle(color: Colors.black, fontSize:14, fontWeight: FontWeight.bold),)
],
)
)
),
);
})
);
}

you can use flutter screen util package and give dimension using it,
it will give dimension according to device aspect ratio

Related

How to animate an image from one container to another in Flutter?

In Flutter, I want to move an image in a container into another container positioned another part of the screen with animation.
Which animation packages do I need to use to do this? Can you help me?
Best wishes...
When I click on one of the playing cards in the image, I want the card to be moved into the container in the center.
Use flutter_draggable_gridview: ^0.0.7
DraggableGridViewBuilder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 3),
),
children: _listOfDraggableGridItem,
isOnlyLongPress: false,
dragCompletion: (List<DraggableGridItem> list, int beforeIndex, int afterIndex) {
print( 'onDragAccept: $beforeIndex -> $afterIndex');
},
dragFeedback: (List<DraggableGridItem> list, int index) {
return Container(
child: list[index].child,
width: 200,
height: 150,
);
},
dragPlaceHolder: (List<DraggableGridItem> list, int index) {
return PlaceHolderWidget(
child: Container(
color: Colors.white,
),
);
},
);

How can I prevent options view of the RawAutocomplete widget from overflowing on screen in Flutter?

I'm currently using a custom widget similar to this chips_input library. However, I don't want to give the options view (the popup list) a static maximum height. What I want to achieve is to dynamically set a maximum height of screen height - popup y offset. In this way, bottom of the options view will be at the bottom of the screen and all of the content inside the options view will be visible through scrolling. Is there any that I can access the textfield's or options view's offset to calculate the height?
My autocomplete widget looks similar to this:
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);
You can do this by putting a height on your SizedBox that uses MediaQuery to get the screen height:
popupOffset = 20;
RawAutocomplete<T>(
...
optionsViewBuilder: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: textFieldWidth,
height: MediaQuery.of(context).size.height - popupOffset,
child: Material(
elevation: 16,
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final T option = options.elementAt(index);
return suggestionBuilder(context, option);
},
),
),
),
),
);

Flutter - Add Layers on top of ListView to scroll

I am making a reader app and I have a ListView.builder which is loading multiple Images from the API. Now I want to add a layer on top of the ListView with 2 transparent containers so that when I click the left container the list goes up and when I click the right container the list goes down. I tried adding the ListView to stack but then the scrolling ability of the list is gone. This is my code so far:
return Scaffold(
body: Stack(
children: [
ListView.builder(
controller: _scrollViewController,
cacheExtent: 1000,
itemCount: _picLinkMap.length,
itemBuilder: (BuildContext ctx, int index) {
return buildImageLoader(
_picLinkMap[index], index + 1);
},
),
Row(
children: [
GestureDetector(
child: Container(
width: mySize.width * 0.5,
color: Colors.black38,
),
onTap: () {
print("Tap Left");
},
),
GestureDetector(
child: Container(
width: mySize.width * 0.5,
color: Colors.red.withOpacity(0.5),
),
onTap: () {
print("Tap RIGHT");
},
),
],
),
],
),
);
I only want to scroll about half the height of the screen on tap.
I searched the web but did not find a suitable solution.
ScrollController _scrollViewController = ScrollController();
...
var jumpTo = (MediaQuery.of(context).size.height - 104)/2;
//104 is random number for the rest of the screen widgets (e.g. appbar ..)
_scrollViewController.jumpTo(jumpTo); //pixel value
...
ListView.builder(
controller: _scrollViewController,

Select number of items in list using gesture in flutter

I am new to flutter and have to implement a functionality to select correct words from list of alphabets.First of all here is the image which i have to make.
The alphabets and the correct words will come from the server side.What is was thinking is that i will place all the Alphabets in grid view/list view and when user will select words by using gesture on the alphabets . I know that what i am thinking may be wrong.If thats the case then please tell me the correct way to achieve what is given in the image ? Thanks in advance.
After doing some more research I think I can point you in the right direction and I wrote a small demonstration app that should help you so I found a good article explaining why I was having issues nesting widgets that both receive touch input. It is slightly complex but the gist of it is. If multiple touch inputs are detected they are handled in what is called the GestureArena and the child widget always wins. You can define your own GestureFactory and use RawGestureDetector to work around this issue. However, this might be more than you need for your application and in my opinion is the more complicated route. The route I went still involves just GestureDetector obviously you would need to expand on this as it only draws one oval at this time but that should be easy.
Offset position = Offset(0, 0);
bool isTapped = false;
double width = 50;
double height = 50;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: GestureDetector(
child: GridView(
physics: NeverScrollableScrollPhysics(), //Very Important if
// you don't have this line you will have conflicting touch inputs and with
// gridview being the child will win
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 2,
),
children: <Widget>[
...letters
.map(
(letter) => Text(
letter,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.amber,
fontSize: 18,
),
),
)
.toList(),
],
),
onTapDown: (TapDownDetails details) {
//User Taps Screen
print('Global Position: ${details.globalPosition}');
setState(() {
position = Offset(
details.globalPosition.dx - 25,
details.globalPosition.dy - 25,
);
isTapped = true;
});
print(position);
},
onVerticalDragUpdate: (DragUpdateDetails details) {
print('${details.delta.dy}');
setState(() {
height += details.delta.dy;
});
},
onHorizontalDragUpdate: (DragUpdateDetails details) {
print('${details.delta.dx}');
setState(() {
width += details.delta.dx;
});
},
onTapCancel: () {
//User has released finger from screen
//Validate Word??
},
),
),
),
Positioned(
top: position.dy,
left: position.dx,
child: Container(
height: height,
width: width,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
side: BorderSide(
color: isTapped ? Colors.blue : Colors.transparent,
width: 3.0),
),
),
),
),
],
),
);
}
Flutter Deep Dive: Gestures found this very helpful key to figuring this all out.

Flutter GridView.builder is Generating Unwanted Extra Space

I am trying to display a row of buttons. Since the number of buttons depends on the number of elements in a List, I have to use GridView.builder to dynamically create the right amount of buttons. Unfortunately it seems that GridView.builder is taking up alot of unnecessary space. Anyone know what is wrong here?
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// Dice buttons
Flexible(
child: GridView.builder(
itemCount: dices.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: dices.length,
),
itemBuilder: (BuildContext context, int index) {
return new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonTheme(
minWidth: 50.0,
height: 50.0,
child: RaisedButton(
child: Text(
dices[index].toString(),
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
color: usedDices[index] || !expectNum
? Colors.grey
: Colors.black,
onPressed: () {
if (!usedDices[index] && expectNum) {
setState(() {
numUsed[turn] = dices[index].toString();
numUsedIndex[turn] = index;
});
expectNum = false;
usedDices[index] = true;
}
},
),
),
]);
})),
Link to Pic: https://drive.google.com/file/d/1_Jr4rz9GJ-D8-Xjxs2w8Sn8lOdnBBqTc/view?usp=sharing
As you can see are lots of unnecessary space here and it seems to be the reuslt of GridView.builder
That space is the result of Flexible, which fills the available space. You will see that if you replace it with a Container and give it a height, it won't produce that much space below.
Just had this problem, top SliverPadding is set to 20.0 by default. Looking at docs I see:
/// By default, [ListView] will automatically pad the list's scrollable
/// extremities to avoid partial obstructions indicated by [MediaQuery]'s
/// padding. To avoid this behavior, override with a zero [padding] property.
So,
GridView.builder(
// shrinkWrap: true,
padding: EdgeInsets.zero,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 1,
mainAxisSpacing: 1,
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Container(
color: Colors.black,
);
},
itemCount: 10,
),
or
If you put a widget before the ListView, you should wrap the ListView with a
MediaQuery.removePadding widget (with removeTop: true)