I want string to be a widget in flutter - flutter

I mean that I want to get scores code from api:

Well their is a widget called Text()
provide the String as it text then it will accept it
body: Text("any text")

Use Text widget with string text
body: Text(text),

If this is for learning purposes and you want to know how to use a widget as a parameter you can do the following:
Text text = Text("Something"); // This way you specify exactly the type `Text`
or
Widget text = Text("Somethig"); // This way you can associate any widget to text
or
var text = Text("Something"); // var can be used with any type
Then you can use whenever you want in your code as long as it require a Widget as a child whitout any need for casting.
For you to create a widget that you can associate values to it you can go for something like this:
Widget myText({String value}) => Text(value);
There are many approaches depending on your need, and I strongly advice you to follow some tutorials for beginners first like Angela Yu bootcamp or any others and also use Flutter documentation.

Try the following code:
body: Text(text),

String is not and will not be a widget. What you are probably looking for is the widget to display a string in your UI: Text.
In your exemple, you can correct it like this :
return Scaffold(
body: Text("Hello World")
);
See exemple on DartPad

Related

I have a stored List data and how can I localize it in flutter?

I can translate the text inside the widget using AppLocalizations.of(context)!.translated and it work fine
However, when I want to localize a stored List<> data which will be used in listView Builder, I am not able to do so, since it need (context).
My question is how to localize a stored list data(outside widget) and pass to list view builder?
Thanks for your help.
I think you should do 2 things
In case if you have a list in another file, then it should be static like this:
class Presets {
static var presetData = [];
}
after you loaded up your list, you can do these steps:
First,
Create Widgets as children like this:
List<Widget> presetsLoadUp() {
List<Widget> children = <Widget>[];
for(i < yourList.length){
children.add(Text(yourList[i]));
}
return children;
}
You can create your own unique widget inside the children.add method.
Secondly,
Create the list:
...
child: ListView(
children: presetsLoadUp(),
),
If anyone has similar problem, please take it for reference.
I just build another widget to solve this.
What I do is :
build another widget,
then put the list data inside and
return ListViewBuilder.
Everything is same,
just put your list data inside another widget can solve the problem

How to write widget tree test to verify tree hierarchy

I am learning Flutter and I want to write one test for my simple MyAppBarWidget. Below is my widget
class MyAppBarWidget extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("My first widget"),
),
));
}
}
I want to test widget tree hierarchy as
MaterialApp has Scaffold property
Scaffold has AppBar property
AppBar has title property as Text
title is My first widget
Any suggestion what kind of test I should write
I tried below test
void main() {
testWidgets("verify app bar", (WidgetTester tester) async {
await tester.pumpWidget(MyAppBarWidget());
var byWidget = find.byType(MaterialApp);
var text = find.text("My first widget");
expect(byWidget, findsOneWidget);
expect(text, findsOneWidget);
});
}
But this test does not say that my text field is inside AppBar widget
Can someone help me how should I write test to verify this ?
Thanks
I suggest not to test widget hierarchy, you will change it often and always have to adjust the test without actually knowing anything when the test fails or succeeds. It is better to test functionality, the presence of something or the absence, tap events and interaction.
You can also look into golden (screenshot) tests to ensure that screens or pages don't change.
That being said, if you really want to do this you can use
find.ancestor(find.byType(AppBar), find.text("My first widget"));
EDIT
Or with newer versions of the test library, thanks Fred Grott:
find.ancestor(of: find.byType(AppBar), matching: find.text("My first widget"));

Most elegant/efficient way to refactor widgets in Flutter and Dart

Searching online on "how to refactor Flutter widgets" I found that there exist two possible ways that are both functioning as per my testing, still very different from a structural standpoint. The second method, indeed includes and additional building instruction, which should bring a further burden on the app performances right?
This is the code I want to refactor:
Container(
child: Column(
children: <Widget> [
[long code to create a button with many properties],
[long code to create a button with many properties],
[long code to create a button with many properties],
[long code to create a button with many properties],
],),);
These are the main ways I found:
1):
Widget MyButton(Color color, String text) {
return [long code to create a button with many properties];
}
2):
class MyButton extends StatelessWidget {
MyButton(this.color, this.text);
final Color color;
final String text;
#override
Widget build(BuildContext context) {
return [long code to create a button with many properties];
}
}
Which is the best method?
Please take a look and consider this other question:
What is the difference between functions and classes to create reusable widgets?
Short answer: It' better the second method (both efficient and elegant).
In the first method (extract to a function), you are just creating a function that return the encapsulated widget.
In the second method (extract to a class), you are extracting the widget to a new class that extends from StatelessWidget. This difference gives to the Flutter framework a way to make optimizations.

How can you set title and icon for a flutter web app?

What I'm trying to do is build a flutter web app that, when displayed in the browser, the tab shows an icon and a title (as currently it only shows the world icon and the localhost... title).
Actual Result :
Desired Result :
Edit:
I can now add the title, as this is set in the main function
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Icon(Icons.menu, color: Colors.white,),
title: Text(_your title here_),
)
...
);
}
So, the only thing I need to edit is the favicon
In order to change the title to what you desire, you need to add the parameter title (Which is a String) to your MaterialApp widget.
return MaterialApp(
title: "MyTitle",
home: MyHomeWidget());
Assuming you already have a favicon.ico file, placing it inside the your_project_dir\web folder alongside index.html as shown below is enough for the browser to pick it up.
Following is the result of placing a favicon.ico' in theweb` folder. Make sure to do a clean build.
In other case you can manually mention it using the link tag inside your index.html as explained here in this Wikipedia page.
Edit title
it is the simplest. just use the Title widget on each page or directly inside the materialApp constructor and set title string key to the title text you need.
like this:
...
Title(
color: myColors, //not important in web but still required
title: 'web page title',
child: myChildWidget,
),
...
Edit icon
If your app is only for the web, use the dart:html library to perform change using DOM access.
something like this
import 'dart:html';
...
...
updateIcon(String assetIcon){
LinkElement link = (document.querySelector("link[rel*='icon']") ??
document.createElement('link')) as LinkElement;
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = assetIcon;
}
if your application is multi-platform, you need to create separate main file for the web like main_web.dart. and declare the previous function inside this file.
Now, anywhere you need to set up the icon you just need to call the method after checking the platform using the keyword kIsWeb.
Ex: change icon inside page
...
initState(){
super.initSate();
if(kIsWeb){
WebMixin.updateIcon("assets/home_icon.png"); //WebMixin is just a helper. replace it by your one.
}
}
...
You could set the onGenerateTitle property of your MaterialApp widget, and provide a callback function to build your title. The onGenerateTitle callback is called each time the WidgetsApp rebuilds. This is useful if you want the title of your page to change dynamically or if you want to produce a localized title.
MaterialApp(
...
onGenerateTitle: (BuildContext context) {
return AppLocalizations.of(context).myTitle;
}
...
);
If you're wondering how to change the app name on your device's homepage, you can update the "name" and "short_name" values in web/manifest.json:
"name": "Ideasky",
"short_name": "Ideasky",

How to dynamically add Children to Scaffold Widget

Let's say, I have a chat screen that looks like this.
Now, when the user clicks the "Press when ready" button, the method fetchNewQuestion() is called.
My intention is that this will make a HTTP request, and display the result using
_buildUsersReply(httpResponse);
But, the problem is that this return must be made inside the current scaffold's widget as a child under the existing children, so that it is built at the bottom with the previous ones still there. The result would be like this:
You can find my complete code here.
Is this possible to be done pro-grammatically? Or do I have to change the concept of how I do this?
[Update, I now understand that my approach above is wrong and I have to use a listview builder. CurrentStatus below shows my progress towards achieving that goal.]
Current status:
I have built a list of Widgets:
List<Widget> chatScreenWidgets = [];
And on setState, I am updating that with a new Widget using this:
setState(() { chatScreenWidgets.add(_buildUsersReply("I think there were 35 humans and one horse.")); });
Now at this point, I am not sure how to pass the widget inside the scaffold. I have written some code that does not work. For instance, I tried this:
Code in the image below and in the gist here:
Just for future reference, here is what I really needed to do:
1. Create a list of widgets
List<Widget> chatScreenWidgets = [];
2. Inside my method, I needed to use a setState in order to add elements to that list. Every widget I add to this will be displayed on ths Scaffold.
`setState(() {
chatScreenWidgets.add(_buildUsersReply("Some Text"));
});`
3. And then, load that inside my Scaffold, I used an itemBuilder in order to return a list of widgets to my ListView. I already had that ListView (where I was manually adding children). Now this just returns them through the setState method inside my business logic method (in this case, fetchNewQuestion()).
body: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 0),
child: new ListView.builder(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: 25),
itemCount: chatScreenWidgets.length,
itemBuilder: (BuildContext context, int itemCount) {
return chatScreenWidgets[itemCount];
}
),
),
],
),
);`
I hope this helps future flutter engineers!
forget about the scaffold the idea is about what you really want to change, lets say it is
a list and your getting the data from an array if you update the array, then the list will update,if it is another type widgets then you can handle it in a different way i will edit this answer if you clarify what each part does in your widget as i cant read your full code.
first you have to create an object with two attributes one is the type of the row(if it is a user replay or other messages) and the second attribute is the string or the text.
now create a global list in the listview class from the above object, so you get the data from the user or even as a news and you create a new object from the above class and add your data to it and add it to the list.
item builder returns a widget so according to the the widget that you return the row will be set , so according to the data in the object call one of your functions that return the views like _buildUsersReply(string text).
if you have any other question you can ask :) if this what you need please mark it as the answer.