improper use of a GetX has been detected Flutter - flutter

the improper use of a GetX has been detected. This error is causing me not to load the widget at that point of time. Tried to figure out but still the problem remain. You should only use GetX or Obx for the specific widget. Unable to figure out get x issue that is causing the problem or OBX where to enclose it with. Please help with this scenario.
Thank you.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'specified_books.dart';
import '../pages/styles.dart';
class BookMagazineTapbar extends StatelessWidget {
final String titleText;
const BookMagazineTapbar({Key? key, required this.titleText})
: super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: whiteColor,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(titleText.tr),
],
),
),
body: SpecifiedBooks(
titleText: titleText,
),
);
/*TODO: Below is code for magzines and books, comment scafold from above and uncomment below code to use both if need to use magzines */
// DefaultTabController(
// length: 2,
// child: Scaffold(
// appBar: AppBar(
// elevation: 0,
// backgroundColor: whiteColor,
// title: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// Text(titleText.tr),
// ],
// ),
// bottom: TabBar(
// labelColor: mainColor,
// unselectedLabelColor: greyColor,
// tabs: [
// Tab(
// child: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// const ImageIcon(AssetImage('assets/book.png')),
// const SizedBox(width: 8),
// Text('books'.tr),
// ],
// ),
// ),
// Tab(
// child: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// const ImageIcon(AssetImage('assets/magazine.png')),
// const SizedBox(width: 8),
// Text('magazines'.tr),
// ],
// ),
// ),
// ],
// ),
// ),
// body: TabBarView(
// children: [
// SpecifiedBooks(
// titleText: titleText,
// ),
// SpecifiedMagazines(
// titleText: titleText,
// ),
// ],
// ),
// ),
// );
// }
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:matab/controllers/book_controller.dart';
import 'package:matab/ui/pages/search/search_books.dart';
import 'package:matab/ui/pages/styles.dart';
class SpecifiedBooks extends StatefulWidget {
final String titleText;
const SpecifiedBooks({Key? key, required this.titleText}) : super(key: key);
#override
State<SpecifiedBooks> createState() => _SpecifiedBooksState();
}
class _SpecifiedBooksState extends State<SpecifiedBooks> {
#override
Widget build(BuildContext context) {
final BookController bookController = Get.find(tag: 'bookController');
return SingleChildScrollView(
child: RefreshIndicator(
onRefresh: bookController.refreshList,
backgroundColor: mainColor,
color: Colors.white,
child: Obx(
(() {
if (bookController.isLoading.value) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
return Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height - 100,
child: SearchBooks(
titleText: widget.titleText,
)),
],
);
}
}),
)),
);
}
}

instead of Get.find use Get.put bcz sometimes context not available
//final BookController bookController = Get.find(tag: 'bookController');
final BookController bookController = Get.put(BookController());

GetX's solution for this is to provide initialBinding in GetMaterialApp.
You may not be able to view the code sample below.
Future<void> main() async {
runApp(
GetMaterialApp(
title: "test App",
initialRoute: '/',
initialBinding: HomeBinding(),
getPages: AppPages.pages,
),
);
}
We create HomeBinding in a separate file as follows.
class HomeBinding implements Bindings {
#override
void dependencies() {
Get.lazyPut<MyController>(() => MyController());
Get.put<MyOtherController>(MyOtherController());
}
}
If you implement the above code correctly, when the application starts it will first see what controllers you need and initialize them.

Related

Flutter scrollable layout with dynamic child

I want to create a generic Layout which accepts a child Widget as a parameter, that lays out the content as follows:
I have an AppBar at the Top, a Title (headline), and below that the Content (could be anything). At the bottom, I have a Column with a few buttons. If the content is too big for the screen, all those widgets, except the AppBar, are scrollable. If the content fits the screen, the title and content should be aligned at the top, and the buttons at the bottom.
To showcase what I mean, I created a drawing:
It is easy to create to scrollable content functionality. But I struggle with laying out the content so that the buttons are aligned at the bottom, if the content does NOT need to be scrollable.
It is important to say that I don't know the height of the content widget or the buttons. They are dynamic and can change their height. Also, the title is optional and can have two different sizes.
What I tried is the following:
import 'package:flutter/material.dart';
class BaseScreen extends StatelessWidget {
final String? title;
final bool bigHeader;
final Widget child;
final Widget bottomButtons;
const BaseScreen({
Key? key,
required this.child,
required this.bottomButtons,
this.bigHeader = true,
this.title,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final AppBar appBar = AppBar(
title: Text("AppBar"),
);
double minChildHeight = MediaQuery.of(context).size.height -
MediaQuery.of(context).viewInsets.bottom -
MediaQuery.of(context).viewInsets.top -
MediaQuery.of(context).viewPadding.bottom -
MediaQuery.of(context).viewPadding.top -
appBar.preferredSize.height;
if (title != null) {
minChildHeight -= 20;
if (bigHeader) {
minChildHeight -= bigHeaderStyle.fontSize!;
} else {
minChildHeight -= smallHeaderStyle.fontSize!;
}
}
final Widget content = Column(
mainAxisSize: MainAxisSize.min,
children: [
if (title != null)
Text(
title!,
style: bigHeader ? bigHeaderStyle : smallHeaderStyle,
textAlign: TextAlign.center,
),
if (title != null)
const SizedBox(
height: 20,
),
ConstrainedBox(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
child,
bottomButtons,
],
),
constraints: BoxConstraints(
minHeight: minChildHeight,
),
),
],
);
return Scaffold(
appBar: appBar,
body: SingleChildScrollView(
child: content,
),
);
}
TextStyle get bigHeaderStyle {
return TextStyle(fontSize: 20);
}
TextStyle get smallHeaderStyle {
return TextStyle(fontSize: 16);
}
}
The scrolling effects work perfectly, but the Buttons are not aligned at the bottom. Instead, they are aligned directly below the content. Does anyone know how I can fix this?
DartPad you can check here
customscrollview tutorial
Scaffold(
// bottomNavigationBar: ,
appBar: AppBar(
title: Text(" App Bar title ${widgets.length}"),
),
//============
body: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
// controller: _mycontroller,
children: [
title,
...contents,
// ---------------------This give Expansion and button get down --------
Expanded(
child: Container(),
),
// ---------------------This give Expansion and button get down --------
Buttons
],
),
)
],
))
We can Achieve with the help of CustomScrollView widget and Expanded widget.here Expanded widget just expand between the widget
Sample Code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),
);
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var widgets = [];
var _mycontroller = ScrollController();
#override
Widget build(BuildContext context) {
var title = Center(
child: Text(
"Scrollable title ${widgets.length}",
style: TextStyle(fontSize: 30),
));
var contents = [
...widgets,
];
var Buttons = Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {
setState(() {
widgets.add(Container(
height: 100,
child: ListTile(
title: Text(widgets.length.toString()),
subtitle: Text("Contents BTN1"),
),
));
});
// _mycontroller.jumpTo(widgets.length * 100);
},
child: Text("BTN1"),
),
),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 100,
child: ElevatedButton(
onPressed: () {
setState(() {
if (widgets.length > 0) {
widgets.removeLast();
}
});
// _mycontroller.jumpTo(widgets.length * 100);
},
child: Text("BTN2"),
),
),
))
],
);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
// bottomNavigationBar: ,
appBar: AppBar(
title: Text(" App Bar title ${widgets.length}"),
),
body: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
// controller: _mycontroller,
children: [
title,
...contents,
Expanded(
child: Container(),
),
Buttons
],
),
)
],
)),
),
);
}
}
Try this:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp();
#override
Widget build(BuildContext context) {
return MaterialApp(
home: BaseScreen(
bottomButtons: [
ElevatedButton(onPressed: () {}, child: const Text('Button 1')),
ElevatedButton(onPressed: () {}, child: const Text('Button 2')),
],
content: Container(
color: Colors.lightGreen,
height: 200,
),
title: 'Title',
),
);
}
}
class BaseScreen extends StatelessWidget {
final bool bigHeader;
final List<Widget> bottomButtons;
final String? title;
final Widget content;
const BaseScreen({
this.bigHeader = true,
required this.bottomButtons,
required this.content,
this.title,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
body: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
children: [
if (title != null)
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Text(
title!,
style: bigHeader ? _bigHeaderStyle : _smallHeaderStyle,
textAlign: TextAlign.center,
),
),
content,
const Spacer(),
...bottomButtons,
],
),
),
],
),
);
}
TextStyle get _bigHeaderStyle => const TextStyle(fontSize: 20);
TextStyle get _smallHeaderStyle => const TextStyle(fontSize: 16);
}
Screenshots:
without_scrolling
scrolled_up
scrolled_down

Flutter : I want to change an image when you tap the image, and others are not affected by the tap

I am creating a simple app in Flutter. There are 7 images on 1 screen. I need a function that you can change an image when you tap one of the images. However, now when I tap an image, the other 6 images are also changed. I made a variable "isReal" to put into buildButton() and "isReal" would be switched true and false in the For statement which switch "isReal" in buildButton(). But, that did not work. Could you give me some advice on this problem? Thank you.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatefulWidget {
#override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
bool isReal = true;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
// appBar: AppBar(
// title: Text('AnimalSounds'), backgroundColor: Colors.teal),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('cat.mp3', Colors.red, 'images/cat.png',
'images/cat_real.jpg'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('dog.mp3', Colors.yellow, 'images/dog.png',
'images/cow.png'),
buildButton('cow.mp3', Colors.orange, 'images/cow.png',
'images/dog.png'),
])),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('pig.mp3', Colors.green, 'images/pig.png',
'images/elephant.png'),
buildButton('elephant.mp3', Colors.teal,
'images/elephant.png', 'images/rooster.png'),
buildButton('rooster.mp3', Colors.blue,
'images/rooster.png', 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('goat.mp3', Colors.purple, 'images/goat.jpg',
'images/pig.png'),
],
)),
],
),
)));
}
Expanded buildButton(sound, color, simpleImage, realImage) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: color,
child: isReal ? Image.asset(simpleImage) : Image.asset(realImage),
));
}
}
Ok, you have variable isReal that is the same for entire class (i.e. each button use the same variable). So when you change it's value by tapping on one button it affects all other buttons as well.
To solve this issue I would recommend to move button implementation into a separate Statefull widget. This way you can keep your Screen class as Stateless.
UPD:
Obviously you should watch some tutorials on how to make this on your own. But just for this time this is how it should look like after you separate widgets.
What I did here is:
Create new widget class FlipButton
Move code from your method into build function of new widget
Add parameters to constructor
This way when each FlipButton will have it's own isReal variable.
NOTE: I didn't try to compile it so there might be some errors.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//replace all occurances on `buildButton` method with new widget
FlipButton(sound: 'cat.mp3', color: Colors.red, simpleImage: 'images/cat.png', realImage: 'images/cat_real.jpg'),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'dog.mp3', color: Colors.yellow, simpleImage: 'images/dog.png', realImage: 'images/cow.png'),
FlipButton(sound: 'cow.mp3', color: Colors.orange, simpleImage: 'images/cow.png', realImage: 'images/dog.png'),
])),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'pig.mp3', color: Colors.green, simpleImage: 'images/pig.png', realImage: 'images/elephant.png'),
FlipButton(sound: 'elephant.mp3', color: Colors.teal, simpleImage: 'images/elephant.png', realImage: 'images/rooster.png'),
FlipButton(sound: 'rooster.mp3', color: Colors.blue, simpleImage: 'images/rooster.png', realImage: 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlipButton(sound: 'goat.mp3', color: Colors.purple, simpleImage: 'images/goat.jpg', realImage: 'images/pig.png'),
],
)),
],
),
),
),
);
}
}
/// You can copy this widget into separate file for better formatting
///
class FlipButton extends StatefulWidget {
//declare final variables
final String sound;
final Color color;
final String simpleImage;
final String realImage;
//constructor for this class
const FlipButton({
Key? key,
required this.sound,
required this.color,
required this.simpleImage,
required this.realImage,
}) : super(key: key);
#override
_FlipButtonState createState() => _FlipButtonState();
}
class _FlipButtonState extends State<FlipButton> {
//inside the state declare variable that is about to change
bool isReal = false;
#override
Widget build(BuildContext context) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: widget.color,
child: isReal ? Image.asset(widget.simpleImage) : Image.asset(widget.realImage),
));
}
}
You can use Random class from dart:math to generate the next random image.
Exemple :
int imageNumber = 1;
void updateImage() {
setState(() {
//Random.nextInt(n) returns random integer from 0 to n-1
imageNumber = Random().nextInt(7) + 1;
});
}
#override
Widget build(BuildContext context) {
return Center(
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: FlatButton(
child: Image.asset('images/dice$imageNumber.png'),
onPressed: () {
updateImage();
},
),
),
),
);
}

Flutter Renderboxoverflow

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import '../../Data/Globalvariable.dart' as global;
// import './customexpansionpanel.dart' as ex;
class Districtslayout extends StatefulWidget {
#override
_DistrictslayoutState createState() => _DistrictslayoutState();
}
class _DistrictslayoutState extends State<Districtslayout> {
#override
Widget build(BuildContext context) {
return Consumer(
builder: (context, global.DistrictModel districtModel, child) {
return _totalwig(districtModel.district);
});
}
_totalwig(districts) {
return SingleChildScrollView(
child: Column(children: [
...(districts).map(
(answer) {
return answer['district_id'] == 1000
? Text('Select_Text')
: ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all(24),
fixedSize: MaterialStateProperty.all(
Size(MediaQuery.of(context).size.width, 60))),
child: Text(
answer['district_name'],
style: TextStyle(fontSize: 20),
),
onPressed: () => print(answer['district_id'].toString()),
);
},
).toList(),
]),
);
}
// _createwig(districts) {
// List<Widget> columnContent = [];
// for (dynamic dis in districts) {
// columnContent.add(
// ListTile(
// title: dis['district_id']==1000?Text('Select State'):ElevatedButton(
// onPressed: ()=>print(dis['district_id']),
// child: Text(
// dis['district_name'],
// style: TextStyle(fontSize: 18.0),
// ),
// ),
// ),
// );
// }
// return columnContent;
// }
}
Here I am getting an error of renderbox overflow even though i have wrapped column into SingleChildScrollView in my widget tree i have a sizedbox then a custom widget then a sizedbox then a singlechildscrollview then column
I hope this is sufficient if you want any code you can just comment and i will update the code
import 'package:cowin_slot_tracker/Data/styles/expansionbutton.dart';
import '../../src/By_District/states.dart';
import 'package:flutter/material.dart';
import './districts.dart';
import 'package:provider/provider.dart';
import '../../Data/Globalvariable.dart' as global;
class DistrictHome extends StatefulWidget {
#override
State<StatefulWidget> createState() => DistrictHomeState();
}
class DistrictHomeState extends State<DistrictHome> {
#override
Widget build(BuildContext context) {
return Stack(
children: [
Column(
children: [
Padding(padding: EdgeInsets.only(top: 120)
// color: Colors.white.withOpacity(1),
),
Divider(
thickness: 2,
),
Text("hey"),
],
),
ChangeNotifierProvider(
create: (_) => global.DistrictModel(),
child: Consumer(
builder: (context, global.DistrictModel pinModel, child) {
return Column(
children: [
SizedBox(height: 60, child: StateMenu()),
SizedBox(
child: ExpnButton(
wiget: Districtslayout(),
hint: 'Select Districts',
)),
],
);
}),
),
],
);
}
}
wrapSingleChildScrollView with Expanded, like
Expanded(
child: SingleChildScrollView(
child: Column(
does it solve in your case?

Flutter Web: MaterialApp Title changes every time I pop back

Im building a personal website and everytime I pop back from Projects or Blog Page to my home page the Material App changes from the title i initially put it to the name of the folder carpet of the project. I still don't understand why this happens, so any help would be greatly appreciated.
Note: I'm using the Fluro package for my navigation route.
Image representation of how the MaterialApp Title changes
Blog Page =>Home Page
blog_page.dart
import 'package:flutter/material.dart';
class BlogPage extends StatefulWidget {
#override
_BlogPageState createState() => _BlogPageState();
}
class _BlogPageState extends State<BlogPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
body: WillPopScope(
onWillPop: () async => true,
child: Center(
child: FractionallySizedBox(
widthFactor: 0.8,
child: FittedBox(
fit: BoxFit.fill,
child: Center(
child: Text(
'Hello Stranger!',
style: Theme.of(context).textTheme.headline1,
),
),
),
),
),
),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:webapp/router.dart';
void main() {
FluroRouter.setupRouter();
runApp(
MyApp(),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Personal Website',
initialRoute: 'home',
onGenerateRoute: FluroRouter.router.generator,
);
}
}
home_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import 'package:webapp/widgets/social_media.dart';
import 'package:webapp/widgets/wave_body.dart';
import 'package:webapp/widgets/custom_button_border.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
HomePage() {
timeDilation = 1.0;
}
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
Size size = new Size(
MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height,
);
return DesktopLayout();
}
}
class DesktopLayout extends StatelessWidget {
const DesktopLayout({
Key key,
#required this.size,
}) : super(key: key);
final Size size;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromRGBO(47, 66, 83, 1.0),
body: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
flex: 3,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
flex: 1,
child: Container(),
),
Flexible(
flex: 1,
child: ProfessionalSocialMedia(),
),
Flexible(
flex: 1,
child: Container(),
),
Flexible(
flex: 1,
child: PersonalSocialMedia(),
),
Flexible(
flex: 1,
child: Container(),
),
],
),
),
SizedBox(
height: 15.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomButtonBorder(
stringText: 'Projects',
size: size,
onPressed: () {
Navigator.pushNamed(context, 'project');
},
),
SizedBox(
width: 50.0,
),
CustomButtonBorder(
stringText: 'Blog',
size: size,
onPressed: () {
Navigator.pushNamed(context, 'blog');
},
)
],
),
Stack(
children: [
WaveBody(
size: size,
xOffset: 0,
yOffset: 0,
color: Color.fromRGBO(21, 160, 132, 1.0),
),
],
),
],
),
);
}
}
The Fluro package could be easily be using the Title Widget which changes the Tab name.
That Widget takes a "title (String)" and a "color (Color)" and will update the name over the Tab.
If you're only using Flutter Web you can take advantage of the http class and also replace your url to match your title:
#override
void initState() {
super.initState();
window.history.pushState(null, 'Blog Page', 'blog-page');
}
That will update your URL to "https://my-url.com/blog-page" and adding the Title Widget your tab will say "Blog Page" as well.
#override
Widget build(BuildContext context) {
return Material(
child: Title(
title: 'Blog Page',
color: Colors.white,
child: Container(),
),
);
}
If by any reason you also need Mobile, change your: import 'dart:html'; for the library "universal_html": https://pub.dev/packages/universal_html

Flutter column widget: childs with different heights

I am trying to create a small test app with a large central area onto which i will render an image and a smaller bottom area that will contains an horizontal scrollable list of widgets. Here is the code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:isolate';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:photo_app_ui_test/fxmanager/fx_manager.dart';
////
void main() {
runApp(SampleApp());
}
class SampleApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
#override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
FxManager fxManager;
bool showLoadingDialog = true;
#override
void initState() {
super.initState();
//loadData();
fxManager = FxManager();
fxManager.init().then( (dynamic) => initInterface() );
}
void initInterface(){
setState(() {
showLoadingDialog = false;
});
}
getBody() {
if (showLoadingDialog) {
return getProgressDialog();
} else {
return getEffectsWidget();//getListView();
}
}
getProgressDialog() {
return Center(child: CircularProgressIndicator());
}
getEffectsWidget() {
return
Column(
children: <Widget>[
Expanded(child: Container(color: Color.fromARGB(255, 255, 0, 0),
child: Center(child: Text("Image")))),
Flexible( child: Container(
color: Color.fromARGB(255, 0, 255, 0),
child: ListView(
scrollDirection: Axis.horizontal,
children: _getListData()
)))
]);
}
_getListData() {
List<Widget> widgets = [];
for (int i = 0; i < 100; i++) {
widgets.add(Padding(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
/*
Expanded(
child: Container(),
),*/
FlatButton(
onPressed: () => {},
color: Colors.orange,
padding: EdgeInsets.all(10.0),
child: Column(
// Replace with a Row for horizontal icon + text
children: <Widget>[Icon(Icons.add), Text("Add")],
)),
],
)));
}
return widgets;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample App"),
),
body: getBody());
}
}
produce this result:
I would like to make the green box's height as small as possible:
If the ListView widget is a direct children of the Column widget, the usual Horizontal viewport was given unbounded height exception is thrown. So i have to embed it inside a Flexible or Expanded.
Desired Output:
getEffectsWidget() {
return Column(children: <Widget>[
Expanded(
child: Container(
color: Color.fromARGB(255, 255, 0, 0),
child: Center(child: Text("Image")))),
Container(
color: Color.fromARGB(255, 0, 255, 0),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: _getListData(),
),
),
)
]);
}
static _getListData() {
List<Widget> widgets = [];
for (int i = 0; i < 100; i++) {
widgets.add(Padding(
padding: EdgeInsets.only(right: 10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
/*
Expanded(
child: Container(),
),*/
FlatButton(
onPressed: () => {},
color: Colors.orange,
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisSize: MainAxisSize.min,
// Replace with a Row for horizontal icon + text
children: <Widget>[Icon(Icons.add), Text("Add")],
)),
],
)));
}
return widgets;
}