I'm investigating integrating Flutter into existing iOS and Android projects. My main experience is in iOS, so this post will be from an iOS perspective. But feel free to substitute UIViewController for Activity/Fragment. I'll give some background on my current understanding, and will have my actual questions at the end of the post.
Our main use case is to embed small Widgets into existing view controllers. I've gone through the Flutter docs and guides and have successfully integrated with our project (it was actually pretty easy!) but have concerns with Flutter's overall design being incompatible with our desired usage.
It seems that Flutter would ideally like to be the entire UI for an application: create and start an engine on app launch, pass the engine to a FlutterView, and make that the root view for the app. Alternatively, Flutter seems happy to own whole flows in the app where you push a fullscreen Widget which does some work, maybe pushes/pops more screens, and eventually returns control back to the native app.
However, in the case where I have a native screen with some UI components where I want to also have a flutter Widget which displays some other data - e.g. a bar graph - it seems that I need to either create separate modules, or separate #pragma(vm:entry-point) functions in my Flutter project for each type of Widget (graph, in this case) that I'd like to display.
My understanding is that each of these Widgets would also need their own Flutter engine instance which loads the proper entry point/route to that Widget's main function which then calls runApp(MyWidget).
So on to my actual questions:
What are the best practices for embedding Flutter Widgets in view controllers?
Is this correct that to have a set of small Widgets that are embedded into a view controller, I'll need to create separate engine isolates for each one?
Is this even the right way to think about using Flutter? I know there are workarounds for engine startup latency with pre-warming and caching, and I could recreate the whole screen in Flutter. But I would like to preserve our native work where I can and have Flutter be an additive change.
Can engines be efficiently reused for separate vm entry points? Would it be "weird" to have a pool of cached engines that can be used on-demand (aside from memory pressure and thread limits)?
I'm still wrapping my head around Flutter, but I've been impressed with its capabilities so far! Please let me know if I'm missing something here.
For anyone coming across this in the future, as of Oct. 21, 2020, the use case of embedding multiple Flutter widgets inside of a native UIViewController is not encouraged. Doing this in a performant manner requires updates to Flutter to better share memory and threads across engine instances.
Related
I am looking for some practices to follow for making my startup's app performant.
Please share the tips/tricks and practices that you follow for making Flutter apps smoother. I have shared some practices that I currently follow. Thank you!
Flutter apps are very performant if some of the performance optimisations are kept in mind while developing the apps. No doubt, apps can become laggy and janky.
1: Use smaller image files:
No doubt, images are essential for any mobile application. And this is the area where performance gets the hit by a good margin, if not managed correctly. I started my journey as an Android Developer and I soon experienced lot of lag and poor performance in my apps. Later, I found that I was using the images which were of several MBs each. The resolution of image assets was much higher than required.
This took lot of time for device to load the assets and draw pixels, increasing CPU & GPU’s work. Sometimes, images even failed to load, making app completely unresponsive.
Here are some tips to follow to avoid performance issues related to image assets.
Try reducing size of you images from tinypng.
Lower the resolution of image here. Make sure the resolution is not more than any higher end device’s resolution.
2: Avoid Unnecessary Animations
Animation is a foe of performance, using animations may cause your device resources to constantly work (since the animation values are generated again & again). CPU constantly needs to generate values & GPU has to redraw widgets.
3: Remove Redundant Widgets
Personally, I used lot of redundant widgets like useless containers & other widgets which did not contribute to overall UI feel of the app. Gradually, I realised that this was becoming my habit. Although this can be subjective. Make sure to use only those widgets which are necessary.
4: Proper State Management
A proper state management solution can make your app very efficient & avoid computational overhead. A typical Flutter app may contain hundreds of widgets. Updating these widgets & redrawing them again & again may cause your device to work more. The proper state management allows only necessary widgets to update their state or redraw. Let’s assume that you are using Provider as your state management tool for the app, Provider will only notify its listeners i.e consumer widgets. Only widgets listening to that Change Notifier Provider will update.
Image description
5: Use Dart Dev Tools (Flutter Dev Tools)
Dart Dev Tools is a combination of some useful profiling tools which can help to determine which widget or functionality is taking much processing power and cause lag or jank. Dev Tools illustrate a clear picture of things happening at main & UI thread.
Image description
6: Use Const Widgets Wherever Possible
It is good practice to use the keyword const for constants that we can initialise at compile time. Let's also not forget to use const as much as possible for our widgets, this allows us to catch and reuse widgets to avoid unnecessary rebuilds that are caused by their ancestors.
7: Avoid Functional Components
Flutter is all about widgets, creating a custom widget can be done in two popular ways. Either create a function returning respective widget (functional approach) or create a whole new widget. It is highly recommended to create either Stateless or Stateful widget rather than creating a function.
I always wonder how apps like Airbnb, Flipkart, and Swiggy update their UI on the fly. Even if I didn’t update the app, Flipkart shows different UIs during festivals, while Swiggy always changes its UI based on the device location.
How I implement this in my react-native-app?
Webview is the solution?
Kindly help me..
Thanks
There are multiple ways you can go about doing this.
One way would be to use WebViews as you've mentioned, this would make it trivial to change the interfaces as it's entierly controled in the servers. But the main issue with this approch will be performance and non native look and feel. These are the two main advantages of using React Native over hybrid frameworks in the first place and therefor, it wouldn't make much sense to use WebViews everywhere. But if there's a small slice of your application that updates regularly(ex - terms of service) you could use a WebView to do the custom views.
A more common way that's low effort would be to have all the code in place for the different looks, but use feature flags to toggle different views. This would work the same way that a dark theme would work. The amount of customization we can do this way is limited because we need to code everything ahead of time.
Another way is to use server driven UIs. With this approch, you will have a pre defined templates in the client that you them populate on run-time with data from the server. For a very simple example, you could have a header image that could be populated with a seasonal greeting image. But instead of simple things like images, this can be much more visible chagnes as well. (ex - List view instead of Grid View)
One more involved way would be to use code push. This would allow things like seasonal UI changes. But this requires a lot more setup and might not provide the best user experience.
Webview is best because this way you can change the UI and the business logic or UI handling logic.
But you have to develop a minimum architecture for that.
Here is my way.
Develop Host layer to use camera, shared preference, file system etc.
Develop a communication layer which will be responsible for communication between your webview and the host layer so that your webview can access all the required device platform(eg. android or ios) features which can not be normally accessed directly from webview.
So now you can render whatever UI(by HTML and CSS) you want, you can put whatever logic you want via javascript also now you can access all the required device features you really need.
So, now you are the king of your app.
Just you have to keep updating the UI or logic in server when you really need.
Some cons are there like
webview in android is different than our normal browser. Some required features are not available.
Its behaviors is different in different API level. So you have to test it very well. For testing, you can use Genymotion.
It does not work well in some old devices/APIs.
Look and feel really matters. But smart design can fix that problem.
If you want your whole app in a single webview then you have to compromise with page transition feature of android or ios. But again smart animation design will fix that.
But this is just a working solution not a smart solution for server driven UI.
I have used some server driven UI frameworks. But they seems to be overhead and lacks some features.
So there should be a framework by which we can render native UI dynamically from server with corresponding business logic change feature and accessibility of all the possible device functionalities.
A few months before I started to develop a Server driven UI framework. I did it little bit. But due to lack of time I really could not complete it.
If someone interested to contribute in this project feel free to contact with me.
I have a solid idea and architecture for this project.
This framework can create a revolution in the world of app development.
email: bedmad82#gmail.com
I am accessing the location data using the geolocation API and storing it inside the state of a component called Location.js, but I want to access the state from a different independent component say Slider.js. What is the simplest and fastest way to access the state? I am a beginner. Any help will be appreciated. ie, How to make a state "global" in some sense because I have some other components that want to access the state of Location apart from Slider.
There are 10 components which would use the location state of Location.js, then I would have to perform a POST operation using the location data and some data from Slider also.
I did some research -
Some are suggesting to send the state data via props, but I never use the Slider component inside the Location component. If this can be done, please elaborate.
Somewhere I found about redux, how can it be helpful? And how do I decide I really need it? If yes, can anyone explain briefly how?
The question you are asking is not specific to React Native, but it could be asked about a regular web app written with ReactJS (I say this because it is often easier to find tutorials, etc. in the bigger community of ReactJS)
That being said you have two options:
Since your components are separate, you could consider creating a wrapper component, often called a Higher Order Component (HOC), which will encompass both of those components. You should have the geolocation call present in the HOC component and send it down via props to any child component that needs it.
Use a state management tool - Redux is the most popular state management tool in the React world, but it is not the only one. Another very popular one is MobX. You can think of state management tools like umbrellas that cover your entire application. You can access state stored in Redux in any component, no matter what the parent-child structure is of your application. Redux is considered to have a complex bootstrap, if you do decide to try it out I highly recommend going through this free course on Egghead.io: https://egghead.io/courses/getting-started-with-redux This course was created by Dan Abramov, the actual creator of Redux :)
I hope this helps ;)
Hello for my opinion is not use Redux and other state management library for small and medium scale application development.
Redux is use for build large scale application for small and medium scale it not necessary.
For accessing data of location you can set it to service file and access this data to anywhere.
Often times, Redux is overkill and has a steep learning curve. You can take a look at XSM. It is very easy to pick up and does not get in the way. Will meet your needs of data sharing crossing components and more.
I would like to know if someone know some Android Framework to conventional applications. For example, a framework like rails which we can see easily the MVC pattern.
See answer here for an overview of Android's limitations, which will give you an idea of why an MVC pattern on Android has not yet emerged: http://www.quora.com/Is-there-any-standard-MVC-framework-in-Android-application-development-If-not-is-it-worth-developing-one
After having posted that answer I have gone ahead and built a fully-featured app using a single-Activity architecture. It allowed us to get past all the major UX limitations that were mentioned while being able to have arbitrary complexity in controller hierarchies (parents with children with sub-children etc.). Overall it worked out great, however you WILL have to build out specialized components (ie: custom back stack mechanism) as well as to store/restore state in a way that plays nicely with Android's own Activity/Fragment lifecycle patterns. There are also certain limitations around Fragment animations which had us pull our hair out at times, which required more custom component workarounds. ie: animations that show both an outgoing and incoming Fragment on-screen at the same time aren't supported on Android, so you will have to resort to taking screenshots of views and placing them into temporary ImageViews so that you create the appearance of transitions that show two fragments at the same time. In the end it's all possible, but you will have to be ready to work around annoying Android limitations while keeping an overall MVC architecture intact.
In summary: make your top-level component an Activity which is primarily responsible for top-level navigation (tab-based, menu-based, etc., as well as back stack and state preservation). The top-level component should not govern any particular screen of your app, instead it manages controllers for every top-level screen. The controllers are all Fragments, and can contain sub-controllers which are also Fragments. All screen transitions are performed using fragment transactions as opposed to Intents/Activities. Passing around data between Fragments is another point of contention as Android generally only supports data-passing through an Activity (ie: Fragment uses its parent Activity). But in this architecture you have need to have Fragments passing data to each other (either parent/child or sibling-sibling relationships).
I don't have this wrapped up into a framework or anything, but if your dev/arch team is sufficiently proficient the architecture is definitely worthwhile shooting for. You will come out with an app that is not subject to the traditional UX limitations of Android... something that very few Android apps can say they've achieved. Also... it generally feels awesome showing you can achieve the same level of UX that iOS apps have for years. It's about time isn't it??
Don't know about the "conventional" part - Android does not play well with MVC architecture natively (mostly because Activities and Fragments take on responsibilities of both views and controllers), and I don't know if there is a standard framework for implementing MVC in Android.
I described some of my insights in more details in this answer.
That said, I created MVC (in fact MVP) template/tutorial application which demonstrates the approach I take to enforce MVP in my apps. You can use this app as tutorial, or clone/fork it and use as Android Studio template for your own apps. The source code is here: https://github.com/techyourchance/android_mvc_template
basically android has MVC pattern, but if you need more features like .net mvc you can use com.divankits.mvc module. Just see one of samples to find out how to use it.
here is more details about module:
bind properties to view(layout) objects
you are able to create field validators
convert model to json
We're developing a prototype using MvvmCross. Eventually we'll add Xamarin to support iOS/Droid, but for now we're starting with a Win Store App.
I suspect what I'm asking is fairly obvious, but some clarification on latest best practices would be much appreciated.
Traditionally we'd build apps where there was a "frame" of some kind that held common menus, footers, etc. The "pages" of the app would be moved in and out of this frame as required. With MvvmCross we construct entirely new and separate views to match each viewmodel (at least by default). It seems wrong to me to have to copy such things as a common AppBar (in the Store App case) into each view manually. I know there are ways to manage this using "standard" Store App patterns (same on other platforms), but what is the standard, recommended (hopefully not too complex) approach people are using with MvvmCross?