Beyond Mobile: Building Flutter Apps for iOS, Android, Chrome OS, and Web (Google I/O'19)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Well done for Flutter for web!

  1. Flutter for web is still slow even Hello World. But I believe it would be improved year after year.
  2. How about SEO in Google (search engine)? Of course it must be fine because this is a Google's technology. But just in case I'd like to make sure whether a dynamically generated website would be crawled precisely by Google's search engine.
  3. I couldn't select & copy any texts in https://flutter.github.io/samples/. I feel it's critical. Can I change this behavior? I confirmed those texts were rendered as normal HTML, not canvas. So I guess it's not hard to make them selectable.
  4. Can it handle the keyboard event?
  5. Vimium doesn't work! It's sad!
👍︎︎ 4 👤︎︎ u/lowasdf 📅︎︎ May 09 2019 🗫︎ replies

awesome!!!!

👍︎︎ 2 👤︎︎ u/miltux 📅︎︎ May 09 2019 🗫︎ replies
Captions
[MUSIC PLAYING] EMILY SHACK: Hello, and welcome to Beyond Mobile-- Building Flutter Apps for iOS, Android, Chrome OS and the Web. I'm Emily Shack. EMILY FORTUNA: I'm Emily Fortuna. EMILY SHACK: And if you would like to live tweet this talk or get in contact with either of us afterwards, all the information you need is up on this slide. Now of course, we are here today to talk to you about Flutter, but first a brief reminder about the Big Bang Theory. The Big Bang Theory tells us that the universe we live in started off as a teeny tiny speck and over time expanded to something much, much greater. Flutter, too, started off as simply an idea, the idea that you should be able to quickly create beautiful, fast, responsive applications with a best-in-class developer experience that you can just take with you everywhere. Over the past few years, the Flutter team has been hard at work expanding that idea into a mature UI toolkit for mobile that checks all of those boxes. And in just a few moments, we're going to show you why Flutter is the best choice for your next mobile app today. But like the universe, Flutter is constantly expanding. And we're also going to show you a sneak peek of the next frontier beyond mobile. Flutter apps from the same code base and with the same tooling and functionality that Flutter developers already know and love for desktop and even the web. Now we're going to be live coding different portions of a single app to guide us through this journey. So if we can switch on over to the devices, we can take a look at that app now. EMILY FORTUNA: We partnered with the agency called Two Dimensions to write an app that we're calling Developer Quest. It is an app that essentially gamifies the process of app development. Through this game you can hire team members, assign them to tasks to work on and all towards gaining users, increasing their happiness, and ultimately shipping that 1.0 app. And along the way, when you complete certain tasks, various mini games will pop up, as you can see on the larger screen down at the bottom. Now we have this running on three different devices, including one of which has maybe gone to sleep. We have it on iOS and Android as well as an iPad down at the bottom. And this is the same code base that you can see that we have a slightly different layout for the different screen sizes. And as Emily mentioned, we will be live coding different portions of this app throughout the talk as we talk about running Flutter on all these different platforms. So if we can go back to the slides, Emily will talk us through how we get there EMILY SHACK: Right. So we're going to be using different portions of this app to demonstrate supporting the mobile, desktop, and web use cases. For those of you who are already familiar with Flutter development, the mobile portion of our talk might be a little bit of a refresher for you, as we will be covering some Flutter basics. However, we will also be introducing some brand new Dart language features. So stay tuned for how you could further streamline your pre-existing Flutter projects. In the second half of our talk, we'll be moving on to new frontiers for everyone in the room. We'll be showing you how to optimize your code for a desktop experience and finally get to the latest and greatest on Flutter for web. With that, I'll pass it back to Emily to talk to us about Flutter on mobile. EMILY FORTUNA: Flutter started out as something of a moonshot, the idea that there must be a better way to write UIs. And we believe we've delivered on that promise. We've got three different apps here, all written using Flutter, and you can see they look very different. This really speaks to the customizability of writing with Flutter. And they're super fast. They are working at-- if we can go back to the previous slide, please. They run at 60 frames per second, and they should feel sleek and responsive as you work with them. This app is the same app running on iOS and Android, and there were no changes that we made to the code to make it run on these devices. But while it looks similar, there are small differences in terms of navigation, in terms of scroll behavior, and this all comes out of the box. This allows you, the app developer, to focus on the interesting parts of your app rather than worrying about making it feel like it's running on the platform appropriately. And lastly, my personal favorite feature of working with Flutter is a feature called stateful hot reload. This allows you to have your app running while you're developing. You can make changes to the code. And you can see them reflected nearly instantaneously on the app. In this animated, GIF you can see that I am making changes to the background color and font size. But it can be used for much more complicated things, like changing functionality and so on. And it really speeds up your app development. And speaking of zippy app development, let's go over to the MacBook and we will work on live coding a portion of our app on the mobile side. So what we have here is the version of our app up and running. There are two tabs if you recall. The first one is the Teams tab and the second one is the Task tab. For live coding on the mobile portion, we are going to be focusing on this Tasks page and adding functionality as well as improving styling, explaining some Flutter layout fundamentals. So in the code we've got our main entry point here, and it's calling runApp with Developer Quest. Developer Quest is a class that extends stateless widget. Widgets are the fundamental building blocks of all Flutter UIs. Everything you see on screen consists of a widget, and Flutter uses the build method to determine what is going to be drawing to screen. So Developer Quest is something of a complicated app. And when I'm looking at a code base that I'm unfamiliar with, one way that I like to orient myself around the code base and find what I'm looking for is to use the Flutter inspector. This is some tooling that allows you to tap on something on the screen, and it shows you the widget tree as well as it jumps to that place in the code so that I know what I need to edit. So in this case, as I mentioned, we're going to be editing the tasks that we add to the page. So Emily has jumped to the task list item class. EMILY SHACK: And I think this is looking OK, but it's pretty contrasty. I'd really like to start by changing the color of this task. EMILY FORTUNA: So that is a pretty easy change. Emily's going to set the color of material container to be white and then the text to be black. Now the reason it was colored that way to begin with is Flutter has this notion of theming for apps. And this gives you all of your widgets sort of default styling so you don't have to specify it everywhere. And in this particular app we had a dark theme, which gave it white text. But Emily is reversing that by specifying it directly. And, thanks to hot reload, there it is, super quick. EMILY SHACK: All right. That's looking a lot better. But now there's more information that I need to know about this task. For example, what's the reward I get for completing it? EMILY FORTUNA: Yeah, so as you can see, the text itself is inside of this Column widget. Column widgets are a pretty common widget that you'll be using to build up layouts. They orient your widgets vertically from top to bottom. And Emily's going to add the spacedHeading function to add something on top of it. Now if you look at the spacedHeading-- it's just above that build method-- you'll see it returns a list of widgets. And you can see the call to spacedHeading has those three dots before it. This is a new feature in Dart 2.3, which is called the Spread Operator. And basically, it allows you to expand that list so that the column has a list of widgets rather than a list of lists. It's sort of unwrapping, if you will. So Emily can hit Save, and there we go. EMILY SHACK: All right. So I'm starting to see more information. But there's still one piece that's missing, and that's the skills that I need to complete this task. EMILY FORTUNA: Yes. So let's look inside spacedHeading. And you can see that there is this task header widget, which is where we're getting our coin information. And inside that, you see it consists of a row with the coin and the text based information of the coin reward we're getting from completing this task. And Emily's adding skill information. Now, she's doing this by putting a for-loop inside of this list for the row. And this is yet another Dart 2.3 new feature. It allows us to iterate through all of the skills that we need and produce SkillDot widgets accordingly, sort of like a list comprehension if you're familiar with that in Python. EMILY SHACK: All right. That's looking a lot better. Now, I think I'm pretty happy with how this task is looking. But it's the only task on the page and I can't do anything with it. I really want to make this more interactive. EMILY FORTUNA: Yes. The whole point of this game is to be able to add more tasks and assign people to work on these tasks. So to do that Emily is going to wrap this widget. EMILY SHACK: One second. EMILY FORTUNA: There's a keyboard shortcut gone awry there. EMILY SHACK: You know what, I'll just-- [INTERPOSING VOICES] EMILY FORTUNA: She's going to wrap it in a inkwell widget, which is a built-in widget that allows you to make the enclosing widgets responsive to touch. So when you tap on it, the On Tap parameter, what you specify in that function, will get called. So we've got a function called Handle Tap that shockingly is going to get called when we tap on it. And we save, we can see it in action here. So we've got that nice inkwell ripple animation and we've got some characters. So let's take a look inside Handle Tap to see what's going on there. Handle Tap is an asynchronous function, and that means we can use this await keyword. What we're doing here is we want to not proceed to the next line until we receive information about which characters we want to assign to this task. So the await keyword tells Flutter not to proceed to the next line until it's received the information that picking the character has completed. So Emily can select characters, and we've assigned them to their task. And-- EMILY SHACK: All right. So I think the task completed, but I didn't really get to see the progress along the way. Is there a way that I could see that? EMILY FORTUNA: Yes. We are lacking some user feedback about what's going on. So we'll put one more thing in that column widget, and it's a progress indicator. And this is just a fancy looking progress indicator that can show the team members that we've assigned to the tasks as well. So this one, this task, is already completed. You can launch it, but let's work through one more task to see it in action. EMILY SHACK: All right. Much more immersive. And look at all those users I have. EMILY FORTUNA: Yes. So let's go back to the slides and we can talk a little bit about the tech behind making this happen. So essentially you've got your code and you're making calls into the Flutter framework. Those are all those built-in widgets, and this does things like gesture recognition. The level below that is the Flutter engine. This is written primarily in C++ and consists of the Skia Graphics Library, the text rendering engine and so on. Below that is a thin runner that starts up the Flutter process on iOS and Android particular to the code. And then of course that runs on x86 or ARM hardware. Now it's important to remember that for you as the app developer, you don't need to know all of this stuff. This is just if you're curious about how it goes under the covers. And when you want to release your Flutter app in production mode, that Dart code gets compiled down to ARM or x86 instructions, so it's super fast. And with that, I will hand it over to the other Emily on the stage to talk to us about desktop style apps with Flutter. EMILY SHACK: Right. So zooming out from Earth to Mars, we find ourselves looking at Flutter for Chrome OS. Flutter for Chrome OS is a newer frontier for the Flutter team, but it actually uses a lot of the same technology under the hood. Although the Flutter team has been hard at work creating a seamless development experience between desktop and mobile, it's likely you'll still need to make some changes to your app to optimize your user experience. This not only includes changes to the way your UI is laid out to reflect a different screen size, but also changes to the ways you allow users to express input. For example, most desktop apps use a keyboard and mouse or trackpad, while mobile users tend to rely much more heavily on touch. Why don't we go ahead and switch over to the Chromebook and see how we can modify our own application to make it more friendly for desktop. EMILY FORTUNA: All right. So we have literally the exact same code, just at the same point we left off on mobile, and it's running on Chromebook. We made no changes to the code. And you can tell it's the exact same code because it's enormous for the screen size. EMILY SHACK: Yeah, I think that we could probably do some work to improve our UI layout here because we're really only doing what we've developed for mobile. So if we jump into the code we can see right now this is our main function. And we can go into the game widget, which is where we're building all of our UI layout. Right now we're just using a single screen to lay that all out, but we would really like to switch between two different widgets based on the size of the current display device. We're going to do that via a call to MediaQuery.of. And that is a handy operator which tells us information about our current device. In this case, we really care about the width of the device. So we're going to check the width and then switch between different layouts, depending on what we get. We're still going to display that basic game screen if we don't beat that threshold so that we know that on mobile, our apps still perform exactly the same. So we can hot reload because of course just works on desktop. We can switch back over and see our app running. EMILY FORTUNA: That looks much better. That is a much better usage of our screen real estate for sure. So one form of input that we have much more commonly on desktops that we don't usually have on mobile is keyboard input. It would be nice if we could modify our app to make use of that. EMILY SHACK: Very true. So one thing that we can do in this app is click on a character and see some information about them, and that brings up a dialogue. In order to dismiss that dialogue, we have to hunt around for that x in the corner. But on desktop, we might want to do something easier, like press the Backspace key to dismiss it. So let's see if we can add that to our app. To do that, we're going to go into the Character Modal widget. The character modal widget is the wrapper for our entire dialog. And we're going to go ahead and wrap everything that's being returned in that build function in another widget called Raw Keyboard Listener. That's going to accept key events so that we can do whatever we want with them in the body of our widget. The Keyboard Listener has an important property, which is that of focus. Now if you think about focus, it might not make sense right now in terms of a dialogue. But when you think about it, you really want the key event that's typed to be piped only to one widget in the app rather than everything that might be able to accept a key event. So we're going to put this widget in focus with a call to requestFocus, and then pass a focus node into our Keyboard Listener. Finally, we're going to implement the onKey method, which is a handy method where all of the magic really happens. That's going to accept a key event or pass us a key event, which we can use to perform some application logic. When we see that key event, we're going to check to see if it matches the Backspace key, and if so, we're going to use a call to Navigator.pop to get rid of that dialog from the screen. One more thing to point out is the use of the Logical key property. The Logical key property is a way that we can allow for international keyboards. So different keyboards across different countries, different languages might have keys laid out in a different way. In the US on English keyboards, we generally have the Backspace or Delete key in the top right corner of the keyboard. But we don't really want that spacing to determine what the key is. We want the key itself to determine it. So when we get that Backspace key with Logical key, we know that it's the right key we're looking for. Now when we go ahead and hot reload we can check out our app. EMILY FORTUNA: So my pointer is here, nowhere near that x. I'm pressing the Backspace key, and it works. EMILY SHACK: All right. So we can accept keyboard inputs. That wasn't a very visual change. Let's do something that everyone's really looking for. What can we do next? EMILY FORTUNA: Yeah, so another form of input that we have on desktop style apps is the ability to respond to mouse hover. And it would be nice if we could modify our app to do that. EMILY SHACK: Very true. So something I think that could be really cool is if we used mouse hover to make these characters animate whenever we hovered over them. To do that, we're going to go into the widget called Character Pool Page. That widget is responsible for building the whole grid of characters on screen. And within there, we have a character list item, which is responsible for building a single character. We're going to go into that widget and wrap everything there just like we did for our keyboard input in a Listener, except this Listener accepts mouse touch and trackpad events. In our case, we care about the onPointerEnter and onPointerExit methods. Those are going to tell us when a hover has started or stopped. When we see those we're going to call startPlaying and stopPlaying, which are methods that we've already written for this widget. But they're not doing much yet, and that's because what we really want them to do is change the state of our widget. But our widget is stateless right now, so we're going to need to turn it into a stateful one so that it can change state within its lifecycle. Luckily, we have a handy IDE shortcut to do that. So we're going to go ahead and convert to stateful, and then we can introduce a new variable in the state class that just got created. And that variable is going to be allowed to change during the widget's lifecycle. Within startPlaying and stopPlaying, we're going to modify that variable using a call to setState. That call is only available to stateful widgets, and it tells the widget that it might be time to rebuild because something in the build function has changed. So we're not actually doing anything yet because we're not using that variable anywhere. So let's go ahead and insert it into our build method. We have this Character Display widget, and that has an isAnimating property. So it's pretty simple. We can just add it in there and go ahead and hot reload. EMILY FORTUNA: And so now as I hover on them, they do a little animation. EMILY SHACK: Very cool. All right. I'm feeling pretty good about our desktop application. But you might all be wondering how it's working under the hood. So why don't we switch back to the slides. You might be surprised to learn that on Chrome OS, the underlying tech stack here is actually very similar to what we showed you for mobile. The main difference is this additional layer called ARC++. ARC++ allows Android apps to run on Chrome OS with the same fidelity as apps that were designed for Chrome OS from the start. From a developer perspective, it's very similar to deploying to an emulator. Except in this case, it's the real target hardware-- your Chromebook. Now for those of you in the audience who are thinking that that tech stack looked a lot like mobile in disguise, we are happy to announce that Chrome OS is not the only way you can create desktop experiences in Flutter. Zooming out from Mars to the further reaches of the galaxy, with the early stage Flutter for desktop project, your apps can run on Mac OS, Linux, and Windows as well. And you can read all about how to do that for your app at flutter.dev/desktop. Now the tech stack behind Flutter for desktop differs a little bit from that of Flutter for Chrome OS. Instead of the Android runner combined with ARC++, we swap out the runner entirely with one specific to the particular desktop platform, whether that's Mac OS, Linux, or Windows. While it is a ways out, the Flutter team is hard at work, ensuring that your code up at the top of the stack can remain unchanged so that you don't really have to think about any of the details below. With that, I will pass it back to Emily to talk to us about Flutter for web. EMILY FORTUNA: So you probably heard a little bit about Flutter for web, and we're excited to show you how that works today. And today we're also even more excited to announce that Flutter for web is now in technical preview. [APPLAUSE] If you go to flutter.dev/web, you can download it, check it out, kick the tires, give us feedback. One thing we do not recommend you do just yet is deploy all of your apps to production with Flutter web just yet. There is still some performance things the team is working out, and maybe a few usability things that we want-- or tooling items that we want to make Flutter for web development even better. However, there's lots of great stuff there already and we're going to show you how it works. So you have probably visited a web page or two in your life and probably have written a web page or two in your life. So you might be curious about how the tech for Flutter on the web works. From you, the Flutter web developer perspective, it is no different from Flutter anywhere else. All those Flutter widgets that you know and use, they work. We did a lot of work under the hood to make that tech stack just work for you. So the nonsolid rectangles are the different parts. We rewrote the Flutter web and the Flutter engine to be the Flutter web engine. And essentially that takes all those lower-- it has a lower level implementation of the Flutter widgets and it has rewritten them. It generates Dart code that produces HTML and CSS. When you can't generate or produce Flutter widgets with the same fidelity as you would normally with just those two, we fall back to the Canvas API. So that is Dart code. And we use the dart2js compiler or the dartdev compiler to then compile that down to JavaScript, which then just runs on your browser. So let's go a little bit deeper into how that works. So as I mentioned you've got your Dart code, which is Flutter. And the Flutter web engine is a lower level implementation of all those Flutter widgets. And that's Dart code that generates HTML, CSS, and Canvas. And the Flutter team is also looking at potentially-- depending on how performance goes and how the web continues to evolve-- swapping out Canvas for the CSS Paint API. As I mentioned, that's all Dart code, and that gets compiled down to JavaScript. And I want to point out that the Dart-to-JavaScript tool chain is actually quite mature. Dart was originally written to be a web programming language. And the Dart team has many years of experience of compiler engineers working on converting Dart to JavaScript. People such as myself who do that. So let us all swap over to the MacBook and we can show you some Flutter web code. EMILY SHACK: All right. So what you're looking at right now is the Style Sphinx Mini game. Hopefully you'll remember that from when we were doing our walk-through of the app at the beginning. This is the mini game that you encounter at critical points in your app development journey. And this is what we have for you today on Flutter for web. Now admittedly this is not the full app. And if we look at the code, we will see why we moved away from the code that we were working on for mobile and desktop. We can see that in these imports we have an import to package Flutter web rather than Flutter, which many of you will be familiar with as the canonical way to find Material widgets. The reason that we have this different import is that the Flutter team, when implementing Flutter for web, chose to fork the implementation so that they could make sure that all of the changes were stable and performant before merging them back in with the mobile Stable widgets. But you should see those imports converging together very soon. All right. Now the rest of that is basically the same as what you would see on desktop or on mobile, the rest of the code. EMILY FORTUNA: Yes. EMILY SHACK: With the exception of that we have not swept over all of the import statements to show you this today. So Emily, how does this work on web? Is this something that we can show for example browser resizing with? EMILY FORTUNA: Yep. So my app is responsive. You can see my Sphinx shrinking based on the available screen real estate. That's all there. EMILY SHACK: All right. Very cool. What about the developer tools that I know I really need in my development process, like the widget Inspector that we showed earlier? EMILY FORTUNA: Absolutely. So having a great UI development experience is the crucial part of working with Flutter. And so we've got our DevTools available just as a separate browser window. You can select a widget and it'll take you to that point in the tree. EMILY SHACK: Awesome. OK. But what about something that's really specific to the web use case, like for example linking? Is that something that I have to write a whole bunch of extra code to get working in my app? EMILY FORTUNA: No. So this is actually really cool. I didn't make any changes for this, but I have deep linking for my app. So you can see in the URL, so sort of my home page. And when I click space to Sphinx, my URL changes. This came out of the box because I have a material app. And if you write material apps, you commonly make use of routes. Those are the different pages that your app will go to. And so it makes use of those route names to automatically generate URLs. So if I change this URL-- of course I could use the Back button, but I'll just demonstrate deep linking that way. That's interesting. EMILY SHACK: We promise it works, or at least it will when we're out of technical preview. EMILY FORTUNA: Yes. EMILY SHACK: But-- that's all well and good, but what about the thing that I care about most as a Flutter developer, hot reload? That's the most important thing to my development process. Is that something that I'm going to have available to me when I'm developing for web. EMILY FORTUNA: Yes. So assuming we're on the right page that we think we are, I'm going to-- I'd like to make a change to the color of this button, make it a little bit more fitting in with the sand theme. So in my Sphinx button I have this-- I'll change the color of the material. And I want to point out that I'm going to be demonstrating hot restart rather than hot reload. The Flutter team is currently working on getting hot reload working as well. But for the moment we've got hot restart, which does not preserve state. And there we go. So-- EMILY SHACK: Just a few kinks to work out. EMILY FORTUNA: I'm guessing that's because it was confused on which page I'm on, but yes. So generally speaking, as you notice hot restart is a little bit slower but still quite fast. And because you have deep linking, which normally works as you expect to, you can still make changes on the page that you're on as well. EMILY SHACK: Very cool. All right. I think I buy that I'm going to be able to do development on web. Why don't we switch on back to the slides to talk about everything we've gone over so far. So now that you've seen where Flutter is today and where it is headed tomorrow, let's go over some of the highlights. Flutter is stable and mature on mobile, giving you a look and feel that is tailored to the target device you're running on from a single code base. It allows you to iterate quickly with hot reload. And finally looking to the future, we are expanding into the desktop and web environments, unlocking the ultimate vision of an app and developer experience that just works everywhere. EMILY FORTUNA: If you would like to learn more about Flutter, we recommend you go to flutter.dev. That's where you can download the APIs-- download Flutter on your machine with the API docs and their codelabs. We have 12 codelabs available on the web. And also, if you're here at I/O, there's a codelab tent where you can check them out. People like us, or exactly us, will be there to answer your questions. Also, Flutter has a great presence at I/O this year. We've got five talks, and I want to call your attention to two in particular that are particularly related to the stuff we talked about today. A little bit later today there's a talk on Dart, which is the technology that makes Flutter amazing. And there was another talk on writing UIs for different screen sizes. And that happened already yesterday, but it should be up-- it's actually up already on YouTube, so you can check it out. If you would like to check out the code that we wrote today, including the web development branch-- and hopefully it will work better for you-- you can go to this URL. And if you would like to play the game, you can download it from the App Store or the Play Store. Flutter Developer Quest is the name. And you can also check it out at the Flutter sandbox as well. There's many different screens for you to play it on. And this link will be on the next slide as well. Thank you so much for coming today, whether you're writing for mobile, desktop, or the web. [APPLAUSE] [MUSIC PLAYING]
Info
Channel: Flutter
Views: 152,823
Rating: undefined out of 5
Keywords: type: Conference Talk (Full production);, purpose: Educate, pr_pr: Google I/O
Id: IyFZznAk69U
Channel Id: undefined
Length: 32min 44sec (1964 seconds)
Published: Wed May 08 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.