I'm writing an App (1st time) with Flutter on MacOS from VS Code.
All works but when I run the app it is very slow with the synchronization, I mean that if I change something in the home screen, save then click "run on iOS device" it loads the old version, ignoring my edits but after a random time it loads the right version with the correct edits.
I'm working on Catalina 10.15.4 (macbook pro 13 inch early 2015, Xcode updated to the latest version).
This is the code wrote in the home screen, other files are unchanged from the original template.
(I added 3 Images to the LaunchScreen and an other for the Android splash screen).
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BuddyLang'),
centerTitle: true,
backgroundColor: Colors.orange,
),
body: Center(
child: FlatButton(
onPressed: (){},
child: Text('click me'),
),
),
);
}
}
Try Flutter clean and then Restart your app and also check this happen is Flutter run --release
Related
New to Bloc and love having a structured app!
I used the firebase login example:
Flutter Firebase Login Tutorial
Works great and great example. Building upon this example I decided to do it step by step (avoid big mistakes).
I created a bottom navigation with an appbar that has a logout icon. Clicked on logout and it works.
Now I wanted to move the logout to the navigation drawer. I created a statelessWidget dart file called DrawerItems and then I call it from my bottom navigation file (within my scaffold). Here is part of the code of the DrawerItems:
DrawerListItem(
navListIcon: const Icon(Icons.logout_sharp),
strTitle: "Logout",
myFunction: () => context.read<AppBloc>().add(AppLogoutRequested()),
),
When I click on the logout icon, it doesn't do anything. Do I really need to make this statefulWidget? the whole point of bloc is to use stateful widgets as little as possible no?
any insight will be great!
Thank you in advance :D
Ok I figured it out... not really happy about this answer (I like having different files for everything), so if any of you know why this is happening feel free to drop a comment!
I removed the "myFunction" that I was passing and put the read bloc line directly in the drawer stateless class and it worked.
so this is my final code (I kept the old code there too FYI):
Widget build(BuildContext context) {
const drawerHeader = UserAccountsDrawerHeader(
accountName: Text("Account Name"),
accountEmail: Text("Account Email"),
currentAccountPicture: CircleAvatar(
child: FlutterLogo(size: 42.0),
),
);
return ListView(
children: [
drawerHeader,
// DrawerListItem(
// navListIcon: Icon(Icons.account_circle_sharp),
// strTitle: "Account information",
// ),
// DrawerListItem(
// navListIcon: Icon(Icons.filter_list_sharp),
// strTitle: "Filter",
// ),
ListTile(
leading: const Icon(Icons.logout_sharp),
title: const Text("Logout"),
onTap: () {
context.read<AppBloc>().add(AppLogoutRequested());
Navigator.pop(context);
},
),
// DrawerListItem(
// navListIcon: const Icon(Icons.logout_sharp),
// strTitle: "Logout",
// myFunction: () => context.read<AppBloc>().add(AppLogoutRequested()),
// ),
],
);
}
When I move from tabs in the UI it's takes too long to load the chips under the tabs.
I've used the AutomaticKeepAliveClientMixin<> but it broke my Scrollbar and still takes time to load large Chips children from the Wrap Widget. What I would need is a Wrap.builder() but doesn't exist. Is there something I can do to optimize the code to load smoothly?
I have an interactive sample code of the current problem:
https://dartpad.dev/009e9ccae07175074cb77d7792c3692b
Try moving the tabs left to right in the sample to see the performance issue.
If it can't be fixed, I wonder if I can detect when the widget is rendering to show a circular progress indicator while switching tabs.
Any Ideas?
Thanks
Technically the idea of Wrap.builder wouldn't be a solution here because the issue persists even when all the items are in the displayed (nothing to display on demand)
You can make the swiping experience better by delaying the rendering of the tab content until after the swiping animation is done
class _ChipsContentState extends State<ChipsContent> {
bool visible = false;
final List<String> _filters = <String>[];
#override
void initState() {
super.initState();
Future.delayed(kTabScrollDuration).then((value) {
if (mounted) {
setState(() => visible = true);
}
});
}
#override
Widget build(BuildContext context) {
if (!visible) {
return Center(child: CircularProgressIndicator());
}
return ListView(
children: [
if (visible)
Wrap(
spacing: 8.0,
children: widget.chipData.map((chipName) => ChipFilter(chipName: chipName, filter: _filters)).toList(),
),
],
);
}
}
A Wrap.builder() is indeed missing from Flutter. A GitHub issue was opened about this but then closed without a satisfying solution.
I can think of a few workarounds, like using a swiper/carousel, a GridView.builder(), or a List.builder() with Rows inside it. Of course, they're far from being as convenient as a Wrap in this case.
Try Changing your filterChips and "build" methods as follows,
List<Widget> get filterChips {
List<Widget> widgets = [];
for (final chipName in widget.chipData) {
widgets.add(ChipFilter(chipName: chipName, filter: _filters));
}
return widgets;
}
#override
Widget build(BuildContext context) {
// super.build(context);
return Scrollbar(
child: SingleChildScrollView(
child: Wrap(//IS THERE A Wrap.builder()? OR ALTERNATIVE TO DESIRED LAYOUT?
spacing: 8.0,
children: filterChips,
),),
);
}
I'm trying to execute an flutter application, but the image do not appears on the virtual device. After executing the program, it disappears (image), and only appears by deploying it again. What should i do? I'm a newbie programmer. Thanks a lot.
Widget build(BuildContext context) {
return Container(
height: 300,
child: transacao.isEmpty
? Column(
children: <Widget>[
Text("There's nothing to see here... strange...",
style: Theme.of(context).appBarTheme.textTheme.title),
SizedBox(height: 20,),
Container(
height: 200,
child: Image.asset(
'others/images/koala.jpg',
fit: BoxFit.cover,
),
),
],
)
Wait for a while, if the image is big Flutter can take some time to show it.
If you want to load an image in memory and then show it, so it won't take a long time after you navigate to a new screen, call precacheImage.
I just load the image from assets folder and image not showing in the application. But when I load the image using network it loads perfectly.
(I am using linux flat form)
Here is the my code
class Splash extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: new Image.asset('assets/images/login_logo.png'),
//Image.network('https://mobile-di.com/wp-content/uploads/2018/08/flutter-review.jpeg'), //this works
),
);
}
}
in the pubspec.yaml file
assets:
- assets/images/login_logo.png
Make sure that you are adding assets under the flutter: in pubspec.yaml. Also, check if you are adding spaces before assets. In your example, please check with the path of that asset exist. And make sure that you have assets of that name in your project folder.
example:
flutter:
assets:
- lib/img_package/example.png
I've started to learn Flutter Framework and high GPU load when I'm trying to render a list of images which come from the network and have high resolution.
I've created test project on github for demo https://github.com/troublediehard/flutter_imageList_high_gpu_load
Am I doing anything wrong? Is there way to optimise images before render?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Image loading test'),
),
body: buildLists(),
),
);
}
Widget buildLists() {
final imageUrls1 = [
'https://via.placeholder.com/2000',
'https://via.placeholder.com/2001',
'https://via.placeholder.com/2002',
];
final imageUrls2 = [
'https://via.placeholder.com/2003',
'https://via.placeholder.com/2004',
'https://via.placeholder.com/2005',
];
return Column(
children: <Widget>[
buildList(imageUrls1),
buildList(imageUrls2),
],
);
}
buildList(List<String> urls) {
return Container(
height: 150,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: urls.length,
itemBuilder: (context, index) {
return Image.network(
urls[index],
height: 130,
width: 130,
);
}),
);
}
}
There is an open issue in Flutter that characterizes this problem (see this github issue, in particular the links to three issues created from it) as of mid-January 2019. Hopefully it will be resolved sooner rather than later, as more people have been running into it, but I get the impression there's quite a lot of internal discussion around how to properly handle high-res images as it needs to be a flexible and robust solution that works for many use-cases. I believe the high GPU load you're seeing is probably the result of loading up the entire set of images into the GPUs texture buffer, although as a comment states you should expect much difference performance on a real device and in release mode.
The current advice from the flutter devs is to use lower resolution images (i.e. set up your server to serve thumbnails). While this is a slightly annoying response, it is actually something you should think about doing anyways as when you download high-res photos you're 1) using bandwidth, 2) using server memory/processing power, and 3) using additional phone memory (even if images are resized before showing this would still be true). Serving thumbnails should result in a better user experience, even if it means that the both the low-res and high res photos are downloaded separately (when the user taps on the thumbnail for example).