Too many postival arguments when adding hero transition, image, and text - flutter

import 'package:flutter/material.dart';
class DetailsScreen extends StatefulWidget {
final int index;
const DetailsScreen({Key? key, required this.index}) : super(key: key);
#override
State<DetailsScreen> createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State<DetailsScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Hero(
tag: widget.index,
child: Image.network(
"https://raw.githubusercontent.com/markknguyen/pictures/master/pic/${widget.index + 1}.png",
),
const Text("Rome"),
),
),
);
}
}
I tried adding const thinking it will resolve the issue but I didn't. The code did not run. I Just wanted to add some sort of text box in a page. const Text("Rome"), is the main concern.

You can't just have your Text widget there with no parent. You need to put your Hero and Text widget in a Column like so:
Center(
child: Column(
children: [
Hero(
tag: widget.index,
child: Image.network(
"https://raw.githubusercontent.com/markknguyen/pictures/master/pic/${widget.index + 1}.png",
),
),
Text("Rome"),
],
),
),
or any other Widget that acceptes multiple children such as Row or ListView based on your needs

The issue is that your Text() widget isn't passed as a parameter. Currently, the code can't compile due to treating your Text("Rome") as a 'mistake', sort of speaking.
Depending on your use-case scenario, you can either use:
a Column() - if you want your widgets to be one after another in a column.
a Stack() - if you want your widgets to be placed one under another.
You'll have to pass the children attribute to both, so for example:
Column(
children: [
Image.network(
"https://raw.githubusercontent.com/markknguyen/pictures/master/pic/${widget.index + 1}.png",
),
const Text("Rome"),
]
)

Related

Flutter - [Get] the improper use of a GetX has been detected. In StreamBuilder

So I try to use getx to change some value inside the singleStudentDataMobile open from a streambuilder and it throw this error and I dont know hot to fix this
It is get datafrom firebase and show data and this page will show all details when tap on the listview
`
throw """
[Get] the improper use of a GetX has been detected.
You should only use GetX or Obx for the specific widget that will be updated.
If you are seeing this error, you probably did not insert any observable variables into GetX/Obx
or insert them outside the scope that GetX considers suitable for an update
(example: GetX => HeavyWidget => variableObservable).
If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
""";
this is the code
My Code:-
class singleStudentDataMobile extends StatefulWidget {
const singleStudentDataMobile({Key? key, required rdata}) : super(key: key);
#override
State<singleStudentDataMobile> createState() =>
_singleStudentDataMobileState();
}
final StudentDetailsMobi studentdetails = Get.put(StudentDetailsMobi());
Color Activeiconcolor = blue500;
class _singleStudentDataMobileState extends State<singleStudentDataMobile> {
int getselecticon = studentdetails.selectfield.value;
#override
Widget build(BuildContext context) {
return Obx(
() => Scaffold(
backgroundColor: backgcolor,
appBar: AppBar(
shadowColor: blue500,
backgroundColor: darkblue2,
title: Text("Student Details"),
),
body: Container(
child: Column(
children: [
Container(
padding: EdgeInsets.only(top: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [],
),
),
],
),
),
),
);
}
The error is correct. Looking at the code, I see that there are no variables from the Getx Controller under the Obx.
From the Controller, if you set var test = 10.obs or another variable and show this value under OBX, the problem will disappear.

Queries on Flutter ListView

Im learning about listviews and I have the below two dart files, one using ListView builder and the other Listview. Both output the same result. I have been following the listview guide: https://pusher.com/tutorials/flutter-listviews
Below are my queries on listview:
I understand in the real world the data will be coming from an API and wanted to know which of the below options will be used and why?
Am i correct to understand that any widget like container, text can be child of within a listView?
In option 1 the ListView child is a function _buildListItemsFromLocation(). Is this a good practise or should we move the _buildListItemsFromLocation()code to a separate dart file?
Option1: ListView
class LocationListView extends StatefulWidget {
#override
_LocationListViewState createState() => _LocationListViewState();
}
class _LocationListViewState extends State<LocationListView> {
List<Container> _buildListItemsFromLocation() {
int index = 0;
return locationData.map((location) {
var container = Container(
child: Row(
children: [
Container(
margin: EdgeInsets.all(10.0),
child: Image(
image: AssetImage(location.imagePath),
width: 100.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Container(
child: Text(location.name),
)
],
),
);
return container;
}).toList();
}
#override
Widget build(BuildContext context) {
return ListView(
children: _buildListItemsFromLocation(),
);
}
}
Option 2 - ListView.builder
class LocationList extends StatefulWidget {
#override
_LocationListState createState() => _LocationListState();
}
class _LocationListState extends State<LocationList> {
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: locationData.length,
itemBuilder: (context, index) {
return Row(
children: [
Container(
margin: EdgeInsets.all(10.0),
child: Image(
image: AssetImage(locationData[index].imagePath),
width: 100.0,
height: 100.0,
fit: BoxFit.cover,
),
),
Container(
child: Text(locationData[index].name),
)
],
);
}
);
}
}
I use method 2 because it is easy to understand and follows the order from top to bottom so it is easy to read the code.
Any widget can be a child of another widget. Depending on how and what you use them for.
Many people say that we should create another class and then call it again rather than split as above because it affects the performance of the app. In case of using a lot but only in one screen, you can use the same method as your own.
The answer may be flawed, have nothing to give yourself.
If you don't know in advance list size, then create it through builder
1.1 If you create list and you know that elements count won't be more than ten or
twelve, you can create ListView from example1
Any widget can be in ListView. For convenience there is widget called
ListTile, which contains leading, trailing, title, subtitle widgets
its's ok

Flutter : create a custom reusable widget image

I try to create a reusable widget but some error happens...
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class CustomLogo extends StatelessWidget {
#override
Widget showLogo(var nameImage, double radiusImage, double LeftPadding) {
return new Hero(
tag: 'hero',
child: Padding(
padding: EdgeInsets.fromLTRB(LeftPadding, 70.0, 0.0, 0.0),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: radiusImage,
child: Image.asset('assets/' + name),
),
),
);
}
}
And I don't understand override and the "construction" of the widget, how I can use var in the widget
You have to create a constructor to get values from where you are trying to call.
In following way you can create separate widget and pass arguments.
Moreover, here one mistake is left and it is hero tag. you are setting constant hero tag, which is fine if you are calling this widget once in a screen. if you are using this widget twice then it will not work because two hero's can’t have same tag in one screen. so, i also suggest you. to assign tag dynamically.
class CustomLogo extends StatelessWidget {
final nameImage;
final radiusImage;
final leftPadding;
CustomLogo({this.leftPadding, this.nameImage, this.radiusImage});
#override
Widget build(BuildContext context) {
return new Hero(
tag: 'hero',
child: Padding(
padding: EdgeInsets.fromLTRB(leftPadding, 70.0, 0.0, 0.0),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: radiusImage,
child: Image.asset('assets/' + nameImage),
),
),
);
}
}
How you can call or use this widget.
CustomLogo(leftPadding: 10,radiusImage: 5,nameImage: "hello",)

Move, zoom and resize Positioned widget inside Stack widget in Flutter

I would like to be able to move, rotate and zoom every element that you see in the image: 3 pictures and 1 text for example.
Those elements are Positioned widgets (the red boxes) inside a Stack widget.
I'm trying to use the package matrix_gesture_detector (https://pub.dev/packages/matrix_gesture_detector), but the problem is that I can't perform the given actions on the Positioned and I can't wrap it inside any other widget (like MatrixGestureDetector for example) that handles all actions, because "Positioned widgets must be placed directly inside Stack widgets".
If I use MatrixGestureDetector as a child of the Positioned I'm able to perform all the actions, but only inside the Positioned boundaries
How can I perform those actions directly on the Positioned? Or can I use some other widget instead of Stack/Positioned?
For me it worked pretty well.. Try something like this:
First i made a widget so that each widget can have its own Transformer Matrix
class TransformerWidget extends StatefulWidget {
final Widget child;
TransformerWidget(this.child, {Key key}) : super(key: key);
#override
_TransformerWidgetState createState() => _TransformerWidgetState();
}
class _TransformerWidgetState extends State<TransformerWidget> {
final ValueNotifier<Matrix4> notifier = ValueNotifier(Matrix4.identity());
#override
Widget build(BuildContext context) {
final ValueNotifier<Matrix4> notifier = ValueNotifier(Matrix4.identity());
return MatrixGestureDetector(
onMatrixUpdate: (m, tm, sm, rm) {
notifier.value = m;
},
child: AnimatedBuilder(
animation: notifier,
builder: (ctx, child) {
return Transform(
transform: notifier.value,
child: widget.child,
);
},
),
);
}
}
Secondly i wrapped the widget on Stack like this:
Stack(
children: [
TransformerWidget(
Container(
color: Colors.white30,
),
),
Positioned.fill(
child: Container(
transform: notifier.value,
child: TransformerWidget(
FittedBox(
fit: BoxFit.contain,
child: Icon(
Icons.favorite,
color: Colors.deepPurple.withOpacity(0.5),
),
),
),
),
),
TransformerWidget(
Container(
decoration: FlutterLogoDecoration(),
alignment: Alignment(0, -0.5),
child: Text(
'use your two fingers to translate / rotate / scale ...',
style: Theme.of(context).textTheme.display2,
textAlign: TextAlign.center,
),
),
),
It worked great! Except that if you pinch or something touching two of the widgets, both get transformed.. Still do not know how to fix this, but it works for now! :D

How to align widget to another widget in Flutter?

I have a RaisedButton widget inside of a Center widget as one of the widgets in a Column of widgets. I want to add a CircularProgressIndicator to the right side of this button and show it when the button is pressed. Yet I want to leave the button centred when the progress bar is shown. In other words I want the button always be in the center and the progress bar aligned to this button.
I tried to use a Row here but this pushes the button and it becomes not centred any more.
EDIT1: Looking at the result of the solution provided by #Anil Chauhan (thanks for the answer):
Like I said before that I tried to use Row like he did, the problem is that in this case the button is not in the centred in the screen and is pushed by the progress bar. And I need it to stay in the middle of it's row.
EDIT2: #Anil Chauhan edited answer now works for a specific case in which the button is predetermined size. But if the size of the button is changed based on the language of the text (in apps that have several languages) this solution will not work.
This is the reason the question I asked is: "How to align widget to another widget". Because if I could that I don't have to worry about the button text size any more.
What would be the right way to handle this in Flutter?
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
bool _showIndicator = false;
void _onButtonClicked() {
setState(() {
_showIndicator = !_showIndicator;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children: <Widget>[
const Expanded(child: SizedBox()),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: RaisedButton(
child: Text("I am Too Big"),
onPressed: _onButtonClicked,
),
),
Expanded(
child: _showIndicator
? const Align(
alignment: Alignment.centerLeft,
child: CircularProgressIndicator(),
)
: const SizedBox(),
),
],
),
),
);
}
}
Here is my explanation:
The RaisedButton size is depends on its child. If you add it to Row it will automatically align to left(or start).
Expanded widget will fill the remaining space in Flex widget(Row & Column are child classes of Flex). If you add more than one Expanded widgets, it will split equally. So I added two Expanded to both the side of button to make it center.
Now We should give child for Expanded Widget.
For the first one(left) we don't have anything to display so I added SizedBox.
For the second one(right) we need CircularProgressIndicator. so I added it.
The Expanded widget will try to make its child to fill the space inside of it. So the CircularProgressIndicator will become Ellipse shaped. We can avoid this by using Align Widget.
Try this:
Updated:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyAppOne(),
);
}
}
class MyAppOne extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyAppOne>{
bool show = false;
#override
Widget build(BuildContext context){
return Scaffold(
body: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
alignment: Alignment.center,
child: RaisedButton(
onPressed: () {
setState(() {
show =!show;
});
},
child: Text('Show'),
),
),
Positioned(
right: MediaQuery.of(context).size.width * .20,
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(10.0),
child: show ? CircularProgressIndicator() : Container(),
),
)
],
)
);
}
}
Flutter's Column and Row widgets have two convenient properties called mainAxisAlignment and crossAxisAlignment. I assume since you're using a Column and want the CircularProgressIndicator to the right of the button, you might be want to use crossAxisAlignment since the cross-axis of a Column is along the horizontal.
If possible, please share your code for better understanding and support of the issue.