How to position a button on a scrolled container in flutter - flutter-layout

I have several windows that are jpg images of various sizes.
For the small ones, I can simply position a "FloatingActionButton" using screen coordinates:
Positioned(
height: 150,
width: 150,
top: 540,
left: 860,
How can I position them on large jpg images, where I have to scroll ("SingleChildScrollView") further down the jpg? Increasing the "top" value above the maximum screen coordinate does not do anything.

I broke up the large scrolled image into a series of small "containers."
It isn't a very elegant solution, but it works.
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
Expanded(
child: Container(
width: double.infinity,
child: Image.asset('images/Wunderkinder_Tablet_2.png',
fit: BoxFit.fitWidth),
),
),
],
),
Image.asset('images/Wunderkinder_Tablet_4a.png',
fit: BoxFit.fitWidth),
Stack(
children:[
Image.asset('images/Wunderkinder_Tablet_4t.png',
fit: BoxFit.fitWidth),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 210,
height: 161,
child: FloatingActionButton(
heroTag: "btn5",
elevation: 0,
backgroundColor: Colors.blue.withOpacity(0),
shape: BeveledRectangleBorder(borderRadius: BorderRadius.zero),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => sp4artifakt1()),
);
},
),
),
SizedBox(
width: 210,
height: 161,
child: FloatingActionButton(
heroTag: "btn1",
elevation: 0,
backgroundColor: Colors.blue.withOpacity(0),
shape: BeveledRectangleBorder(borderRadius: BorderRadius.zero),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => sp4spiel1()),
);
},
),
),
],
),
],
),

Related

Flutter constraint doesn't fit on any screen size, why?

In my flutter code, I'm trying to make a layout constraint that can fit on multiple screen sizes but on my two emulators which one is 6" and the other is 10", the layout is either too small or too big. why? the layout contains one Column and four rows. the code below shows only the first row. I'd like the squares on the first row to fill in the space side to side automatically. the three bottom rows are hardcoded so disregard them. focused with your answer only on the first row.
here's the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.deepOrangeAccent[100],
appBar: AppBar(
title: Center(child: Text('Kakuro SideKick III')),
backgroundColor: Colors.blueGrey[900],
),
body: Column(mainAxisAlignment: MainAxisAlignment.end,
//crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
print('Just clicked on 1');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('1'))),
),
GestureDetector(
onTap: () {
print('Just clicked on 2');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('2')),
),
),
GestureDetector(
onTap: () {
print('Just clicked on 3');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('3')),
),
),
GestureDetector(
onTap: () {
print('Just clicked on 4');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('4')),
),
),
],
),
6" layout
10" Layout
To answer the question why is rather easy: you're setting explicit constraints (ie. min. and max. height/width), and the widgets cannot shrink/expand beyond that, so they (in most cases, anyway) either overflow the screen, or don't fill it.
What you're trying to achieve can be done using Expanded. If you want to retain the 1:1 aspect ratio, then use it in combination with AspectRatio.
Like so:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 1');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('1'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 2');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('2'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 3');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('3'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 4');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('4'))),
),
),
],
)
Try to use MediaQuery instead a number, it looks like:
minWidth: MediaQuery.of(context).size.width
Exists two ways to use MediaQuery in this case:
MediaQuery.of(context).size.width (takes the whole width from the screen)
MediaQuery.of(context).size.height (the same, but for height)
You can make an calc with that, for exemple:
MediaQuery.of(context).size.width * 0.1 (10% from the whole width)
MediaQuery.of(context).size.height* 0.05 (5% from the whole height)
Try it.

How to use expansion tile inside a container in Flutter?

This is set of expansion tile. Here I want to warp Expansion tile inside a container so that i can give border , shape and shadow to the tile. Also
I want the expanded result as same like this. How can I achieve this. Please help me
I have tried the below pattern. But when I expand I am getting Render overflow error
Container(
height: 80,
width: MediaQuery.of(context).size.width - 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Theme.of(context).hintColor.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5)
],
),
child:
ExpansionTile(
backgroundColor: Colors.white,
trailing: Icon(Icons.arrow_forward_ios_rounded),
initiallyExpanded: false,
title: Text(
'Messages',
style: Theme.of(context)
.textTheme
.subtitle),
children: List.generate(
3, (indexProduct) {
return Text("terwyteuwte");
}),
)
),
please help me..
You can do the following thing
Add the following widgets in ListView() according to your use
class ItemTile extends StatefulWidget {
// final OrderItem orderItem;
// OrderItemTile(this.title);
#override
_ItemTileState createState() => _ItemTileState();
}
class _ItemTileState extends State<ItemTile> {
bool _expanded = false;
#override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 300),
height: _expanded
? 350
: 100,
child: Card(
elevation: 10,
color: Theme.of(context).canvasColor,
margin: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Column(
children: <Widget>[
ListTile(
title: (Text(
'File',
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold),
)),
trailing: IconButton(
icon: _expanded
? Icon(Icons.expand_less)
: Icon(Icons.expand_more),
onPressed: () {
setState(() {
_expanded = !_expanded;
});
}),
),
AnimatedContainer(
duration: Duration(milliseconds: 300),
height: _expanded
? 300
: 0,
width: MediaQuery.of(context).size.width,
child: ItemExpandedTile(),
)
],
),
),
);
}
}
the widget which is shown after expanding
class ItemExpandedTile extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Stack(
children: <Widget>[
Positioned(
top: 5,
child: Container(
height: 90,
width: MediaQuery.of(context).size.width - 75,
padding: EdgeInsets.all(10),
decoration: new BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 15.0,
spreadRadius: 0.5,
offset: Offset(
1.0,
1.0,
),
)
],
),
child: Row(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
'Title',
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.bold),
),
],
),
],
),
),
),
],
),
);
}
}
Th Result:

Staggered Grid View Not scrolling inside Listview

Red color one is carousal view
Green color one is horizontal ListView
Blue color one is Staggered Gridview widget
So My issue is Staggered Grid View is not srolling up inside Listview
I want to scroll all Content . Any one please help this . My code is :
**
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
physics: new AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
primary: true,
padding: EdgeInsets.symmetric(vertical: 50.0),
children: <Widget>[
CarouselSlider(
height: 180,
//height: double.infinity,
//aspectRatio: 16/9,
viewportFraction: 0.94,
initialPage: 0,
enlargeCenterPage: true,
autoPlay: false,
reverse: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index) {
setState(() {
_current = index;
});
},
items: imgList.map((imgUrl) {
return Builder(
builder: (BuildContext context) {
return Container(
width: 400,
margin: EdgeInsets.all(2.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Image.network(
imgUrl,
fit: BoxFit.cover,
),
),
);
},
);
}).toList(),
),
SizedBox(
height: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(imgList, (index, url) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index ? Colors.grey : Colors.black,
),
);
}),
),
Container(
padding: EdgeInsets.only(left: 15.0,bottom: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Latest Markers',textAlign: TextAlign.left ,overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22.0),)
],
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 0.0),
height: 100.0,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: latestList.length, itemBuilder: (context, index) {
return Container(
width: 100.0,
height: 100.0,
child: Card(
elevation: 3.0,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Align(
child: Image.network(latestList[index],fit: BoxFit.cover,width: 100.0,height: 100.0,),
),
),
),
);
}),
),
Container(
padding: EdgeInsets.only(left: 15.0,bottom: 10.0,top: 25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('PlugXR Markers',textAlign: TextAlign.left ,overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22.0),)
],
),
),
Container(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 0.0),
height: MediaQuery.of(context).size.height,
child: StaggedWidget(),
),
)
],
)
);
}**

Container within a Container size

I created a container within another container within it. The child container is supposed to be smaller than the parent but this is not working. I only see the border of the child container.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.green),
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(color: Colors.red),
child: Card(
child: Text('fffff'),
),
),
),
);
}
you can use a Stack and a Positioned Widget for that like so:
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.blue,
),
child: Stack(
children: <Widget>[
Positioned(
left: 20.0,
top: 20.0,
child: Container(
height: 100,
width: 100,
decoration: BoxDecoration(color: Colors.green),
),
)
],
),
),

Flutter text display issue

Am writing a very basic app that just displays numbers on the screen and you can increase and decrease the value of this number with some buttons.
Works fine, except for some reason the text display often goes nuts. I'll show you what I mean:
The above text is trying to display a value of 20, but it is struggling for some reason, as you can see.
This only appears to be happening with double-digit or higher values. My code:
class _SinglePlayerModeParentState extends State<SinglePlayerMode> {
#override
void initState() {
super.initState();
SystemChrome.setEnabledSystemUIOverlays([]);
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,]);
}
#override
Widget build(BuildContext context) {
Widget numberDisplay = GestureDetector(
onTap: () {
print("GestureDetector");
_incrementBy1();
},
child: Center(child: Text(_numberValue.toString(),
style: TextStyle(
fontSize: 200.0,
color: Colors.white,
),
),
),
);
This code was already displaying these text issues before I rearranged the code to include the following as well:
Widget buttonRow() {
return Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 40.0, right: 20.0),
child: FloatingActionButton(
heroTag: null,
onPressed: _numberValueMinus5,
child: Text('-5'),
),
),
Padding(
padding: EdgeInsets.only(left: 20.0, right: 40.0),
child: FloatingActionButton(
heroTag: null,
onPressed: _numberValueMinus1,
child: Text('-1'),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 40.0, right: 20.0),
child: FloatingActionButton(
heroTag: null,
onPressed: _numberValuePlus1,
child: Text('+1'),
),
),
Padding(
padding: EdgeInsets.only(left: 20.0, right: 40.0),
child: FloatingActionButton(
heroTag: null,
onPressed: _numberValuePlus5,
child: Text('+5'),
),
),
],
),
],
);
}
return MaterialApp(
title: 'Bean Counter',
home: Scaffold(
backgroundColor: Colors.blueAccent,
body: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 90.0, bottom: 40.0),
child: numberDisplay,
),
buttonRow(),
],
),
),
);
}
Not sure what I can do differently here, it's just text!
Any thoughts?
Edit: Testing the FittedBox solution.
#override
Widget build(BuildContext context) {
Widget numberDisplay = GestureDetector(
onTap: () {
print("GestureDetector");
_incrementBy1();
},
child: Center(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(_numberValue.toString(),
style: TextStyle(
fontSize: 200.0,
color: Colors.white,
),
),
),
),
);
}
Results: this is trying to display the number 30:
As you can see, it still isn't displaying properly. I also tried BoxFit.contain, same issue. Information obtained from this reference: https://docs.flutter.io/flutter/painting/BoxFit-class.html
Any other ideas guys? Or did I implement FittedBox incorrectly?
Edit: Tried with AutoSizeText, as recommended below. Code:
#override
Widget build(BuildContext context) {
Widget scoreText = GestureDetector(
onTap: () {
print("GestureDetector");
_incrementBy1();
},
child: Center(
child: AutoSizeText(_numberValue.toString(),
style: TextStyle(
fontSize: 200.0,
color: Colors.white,
),
),
),
);
Results:
Argh! Displaying text on a clear screen. Level: difficult.

Resources