Diving into O and the Support Library (GDD Europe '17)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
DAN GALPIN: Can you hear me? All right. I'm Dan Galpin, and Lisa Wray and I will be giving you a tour of the highlights of the latest platform and support library updates. And we've got so much to cover, so I'm just going to jump right into it. So one of the biggest changes to know is we added adaptive launcher icons. And this is a big deal because if you have any of these phones from these lovely OEMs, you saw they are using their own custom launchers with custom icon shapes. And Android icons, shapes and sizes are all random. And so what they would do, like with Chrome and the Play Store here, they would shrink the icon, and stamp on it a random color or shape that they choose. And we thought, you know, we can do something better for this. So what we did is we created adaptive icons. And to enable this kind of customization, your app provides icons in two layers-- background and foreground. So if the OEM defines a rounded rectangle mask shape, the user will see this. And if they define a circular shape, it's going to look like this. And this is cool. And this goes every single way or place your icon appears in the system UI, such as inside the setting app list, the recents or overview title bar, and your shared sheet dialog. So to support wider ranges of icon sizes, because not every launcher makes the icons the same size, as you've also probably noticed, bigger than 48 DP, we now recommend that apps contain an icon asset of at least 72 DP in size with a visible area. Sort if an OEM or third party launcher wants to render icons in 60 DP, it will not be super sampled. Now, the actual size of this foreground and background layer that we want to update to is 108 DP. And we recommend that both the foreground and background layers are actually padded with 25% of the extra image around each side. And the reason we do this is because we want to use it to add delightful animations such as parallax and pulsing. And this is just an example. No, we haven't actually added this to a shipping launcher, but someday we might. So you can now control how your brand is going to look no matter what icon shape your OEM chooses while integrating well into their visual design. This is actually important. So here's what we've done. We've added this adaptive icon drawable class to Oreo, and it supports the foreground and a background inner tag that supports one drawable attribute. And also as a [INAUDIBLE] to help us out, we added this fractional inset value. And this means your insight can now be density invariant, which is really, really cool. So as it turns out, 18 over 8 is 16%. So if you use this value to pad your 72 DP launcher icon there will be no APK size increase from a non-adaptive icon that's big enough. But better yet, the really cool thing is that because these are only used in O, in Android N the vector drawable became expressive enough to support most of the SVG format. So you can actually now make vector icons, which is really cool. So once again, O made a bunch of critical changes to other areas, too. Not just adaptive icons, we made critical changes to notifications. Now, in previous releases of Android, the user could only block all the notifications for an app for sending a spammy notification. But in Android O, of course, we introduced notification channels, which are named categories of notifications that share the same behavior so users can control them. And the user can also click here to see all the categories. And clicking on the category reveals per-category things like vibration and sound, et cetera. And of course we also added these dots in the launcher, which are a low-stress way to see if apps have notifications. I don't have to look how many numbers there are. Long pressing the icon also reveals the notification. And widgets can also really be installed easily in this way, which is so cool because people don't have to stress and figure out how to install them. All right, and all the stuff used to customize per notifications now applies to the whole channel. This is pretty cool. You can set all this stuff on a channel. OK, I do have a bullet point slide here. I'm sorry. But seriously, don't overwhelm your users with channels. Make the distinctions between them make sense. Give them reasonable defaults. And of course, you can use notification compact to set channel information. And remember that if you don't use channels and you're targeting Oreo, your notifications aren't going to show up. All right, let's talk about shortcuts and app widgets. So way back in Android 7.1 we added these nifty launcher shortcuts. And users can drag them and pin them to the launcher. An app could request that a shortcut gets pinned, but there was no indication to the app that it actually worked, and the user wasn't notified that it was happening, which wasn't really great for users or developers. And it doesn't work anymore if you're targeting O. So we now have the new way with Shortcut Manager. And it has an API. And it takes the same shortcut info as we used in Android 7.1, but the launcher will now ask the user whether to add the shortcut and where to place it. So the app can now adapt to-- and the app also has the ability to actually update the shortcut icon later, as well, with this. And custom shortcuts are also in 7.1. It allowed shortcuts to be added from the widget tray with an optional configuration screen. And the Oreo API is an improvement there, as well. As before, you register the custom shortcut activity with the Create Shortcut Intent folder. And in 7.1 it would return the shortcut as intent extras directly to the activity return, which is OK. But now we wrap all of that functionality, which also allows the app to update the shortcut. So again, just making the launch better. And this has been a really long time coming. But we actually have a way for you to surface your app widgets in your app. You no longer have to beg the user to find it in the launcher. You can say, hey, I've got an app widget, please install it on your behalf. And they get prompted, and they get added to the home screen, and it's just awesome. I can't believe it took us this long. All right, let's talk about Autofill. All right, so apps that use standard views automatically work with Autofill. But you can help it do a better job by providing hints, like postal address. You could also mark fields that Autofill should ignore. You can integrate it more deeply. So you can actually request Autofill in your app. And you can use Autofill on completely custom views such as those are drawn with OpenGL or Vulcan by providing an Autofill virtual structure. And no matter how you build your apps, you should really consider doing this. And this is kind of cool. You have a website, the Google Autofill provider can actually share credential information between your web and your app if you create a digital asset link. And this is pretty straightforward. You've got to put something on your server, some JSON here, which allows you to define that you want to share your login credentials between your website and your app. And then you go and modify your manifest with this string that points to a similar JSON resource that contains a list of web targets and permissions just like what you've hosted on your website. And that's it. With these two steps you can share credentials between your website. And this works for Autofill, and it's also the first step in implementing Smart Lock. So you might want to do that also, which this lets your users automatically sign in. But if you don't want to go all the way to Smart Lock, this is a really cool way of leveraging that credential information between your mobile app and your website. Some other O stuff. We added a whole bunch more cool StrictMode behavior, which is great. We now actually-- this is great for finding bad app behaviors. We can detect unbuffered I/O with thread policy, and VM policy allows you to detect untagged sockets, as well as when a content URI is sent that doesn't grant the calling app read or write permission, because it's not very useful to have a call-- yeah. And we've also added seekable file descriptors from document providers, so you can use this for large remote sources such as big audio and video files. OK, another thing we did is we actually added proper support for caching. So the quota here can change depending how frequently the user actually interacts with your app and the amount used while the allocate actually takes deletable cache into account. So pretty slick. And there's tons of more stuff in O, I'm not going to go through it all here. Most of you have seen a lot of this stuff. But we have enhancements to accessibility, including the ability for users to add an accessibility button on devices that have soft navigation, something else for that bar. Paging and content providers. A bunch of great stuff to make the runtime faster as I mentioned before, such as a concurrent copying collector and a whole bunch of changes in media. All right, but let's get into the support library. So you know what I'm going to say here, which is devices that are running SDKs less than 14 comprise less than 1% of the Play Store active users. So we've updated the support libraries [INAUDIBLE] SDK level. And as you might have guessed, we got rid of these two guys. We'll be focusing on the SDK versions that most developers are actually targeting. So the minimum version is now 14, and Google Play services also recently dropped that support in version 10.2. However, you can still use an older version of the support library if you really, really want to still target gingerbread [INAUDIBLE].. And dropping API 14 gives us a bunch of benefits. Removed over 1,400 methods. And remember, we still have a 65k method, [? decs ?] limit on API is less than 21. And there's more to go in later versions. Our public API surface reduced by 30 classes for 100 methods. And what we need to do now is you can still use a lot of these things as they are, but you should start actually getting rid of the deprecated stuff because we're actually going to get rid of it to even make things smaller. And of course, we're using the Google Maven repository for this, which you can specify in your build gradle. This is on Android Studio 2.3. And if you're using 3.0 plugins you can actually just say Google, which is kind of sweet. All right, text and fonts, which is one of my favorite things. I love fonts. In the old world, how many people actually did custom fonts on their Android app? Yeah, a lot of you. You know how much it kind of sucked. You had to load typeface into the constructor, and then you could go and use this custom text view everywhere, and you know, yeah. But now we have a new resource type which both accepts single font files as well as families. And font files get a resource ID. And you can also make these families, which are groups of fonts that are together. So you can define them and say, like, I want normal to be this font, and I want bold to be this font, and you know, et cetera, very, very sweet. And this one generates r.font, .myfont. And this is super easy to use in XML. The text view font family attribute is used and it can handle families, which is even better. So you just get to use the same thing you've been using all the time. Both textile attribute as well as style spans are supported, which is really great. And you can also define them in styles as usual. You can use them in code by resources compat. And more importantly, it's supported on API 14 above with the support library. So go out there and use more fonts. And the only problem, of course, is that fonts actually bloat the size of your app. So we had to think about this. The top 25 fonts in Google Fonts actually average 500 kilobytes or more. And they're not optimized for mobile, necessarily. So we're like, what do we do? How do we fix this? So of course we added downloadable fonts. And the font provider fetches and service fonts to your apps. So more importantly, you don't have to bundle them anymore. And this is really cool too, because this font provider's actually shared between apps. So it gives you memory, gives you network, it gives you space savings. And with Google Play services and Google Fonts you get over 800 fonts. So it's really nice. And in code you can request these fonts using a font request, which [INAUDIBLE] things like authority, and package, inserts, or security, and callbacks for success or failure now exist. And of course you just use fonts contract compat, and you do control what thread this runs on, so don't run it on the UI thread. And this you can also throw it in XML. So it's really easy to use. The search is actually a string array. And it actually is pretty cool. So we've also done full integration with Android Studio. It looks like this. We have some boring text in a layout, and we go and select More Fonts. You see where you've got Google Fonts here, you've got this beautiful selection of fonts. But it's so many I'm just going to search for one. There we are. Yesteryear, we say downloadable font, and it's going to show up in the layout editor, and then it's going to add this beautiful file-- actually two files-- to the project. So pretty sweet. So check out the sample app, the Google Fonts docs, and the guide on developer.android.com for all the info. And best of all, downloadable fonts are all supported in API 14 plus. All right, so there's nothing worse than when someone sends you a message, and you get a box that provides no information. We call this tofu because it's box. So it's time to get rid of this-- and this is there because the system is always bundled the emoji font, and unicode keeps adding new emoji, and it's impossible for us to keep up unless we can make it show up in older versions. So the support library has access to this new font. And it checks per glyph if it can be rendered, or it replaces this with these emoji [? stamps ?] if it can't, which is great. There are two ways for you to use it in your app. The download configuration just happens to integrate with downloadable fonts. So you just add your dependencies, you make your font request, and you initialize it in your application on create. Very simple. It means you don't have to actually bundle the emoji font with your app. But you can. If you're targeting a non-GMS devices, you can do that. It'll add about 7 megabytes. And you configure it in a similar way, again, with a just bundled emoji pack config. So very straightforward. Again, you can just-- you have to use these emoji text views. Instead of text view, you can use emoji edit text, and emoji button instead of edit text and button. And you don't have to use these, but if you don't use them, you have to integrate it into your own custom views yourself. So we do supply these to help you out. And so now tacos and unicorns both exist. Important things for us to get across. So check out this sample on [? DAC, ?] there's more information. Now, one caveat here. We didn't actually back port this all the way to kit-kat. This does require API 19 plus. So that's the one minor caveat here. But again, so get tofu on some older devices if you try to set this up to use it both ways. TextView autosizing. This is a feature I've wanted, and how many people have built their own TextView autosizer? Yes, I've been wanting this feature forever. So I'm so happy that it's finally here in the platform. Text actually resizes to fill in its container. I can't tell you how excited I was when we built this thing. So you use auto size text type uniform. And you can use an array of preset sizes or an array of values, or a set of min and max size with a stack. That's really easy. And once again, we've brought this to API 14 plus. We bring improvements to VectorDrawable. This gives it feature parity with support for fill types. So if it looks like this in Android Studio and you shove this in, this might be what you get before because you get these weird artifacts because we're using these even-odd fill rules, and we didn't support that. There was a big TBD in the source code of you went and looked. So a fill rule defines how this render designs, which of the regions are inside, and which are outside. And we added support for this, which we actually fixed finally in SDK 24 and we've backported it to 14 plus. So this is really cool. It means your vectors are more likely to work, which if you've ever had to deal with, you know how awesome this is that we finally fixed it. We also ported the stuff from animated drawable compat for path data morphing. And this is really cool. This is an example of using shapeshifter, Alex Lockwood's tool, to generate compatible images with matching path formats. And let's look along at what's going on here at the XML level. We start with our vector, defining our starting image, a buffalo. We've extracted the path data. And for the buffalo, hippo and elephant, they're string resources. And then we use an object animator. Pretty sweet. So again, we're specifying the path values to morph a buffalo to a hippo. And once again, we tie it all together in an animated vector XML. Now we can actually do stuff with bundled XML formats to make this even cleaner. So again, we can actually use an attr element here, and it in-lines the XML from the buffalo drawable. And then we can do the same with the animation attribute. And so we have a bundle package that actually includes the entire vector drawable animation, which is really cool. We also have a path interpolator. Once again, that's parity. So this one is kind of complicated, but we can take a simple example and show how it works. So for a UX designer, it wants to shrink a [INAUDIBLE] square, but they want to have an interesting acceleration curve as it shrinks, we can use a path interpolator. And this is kind of cool. We can make a curve that that drops off quickly, snaps back a small amount and slowly tapers off. Here's our morph animation, and we'll set the interpolator to be our path interpolator. So once again we can bundle it in a single file using these attrs, and this results in this slightly more cool animation. Still just a rectangle. OK, final thing I'm going to talk about is transition support library. So if you've noticed that we actually added some additional transition type in Lollipop and above, things like path motion, and propagation, and all of this is available in the transition library. So when you use the transition XML with a support library, you have to specify this dash dash no dash version transitions as an APT option. And after that, you can use all the same transition XMLs that you use for platform transition API on API 14 and above. And the reason I'm talking so fast is because I want to get my amazing collaborator on here, who is really the star of the show. I'm just the opening act. I'd like you to welcome Lisa Wray, who's going to talk about some amazing animation features. LISA WRAY: Thank you. So I only have one thing to talk about, and that's physics-based animations. So we've known for a long time that motion is important in material design. Natural movement inspired by forces in the real world. And I've tried, I really have. But it hasn't always been easy. So the support library has now introduced two implementations of physics-based animation. Not approximations of motion with a stock interpolator, but motion based on natural forces. Could you have done this before? Maybe, but it wouldn't have been easy. With dynamic animation, these ideas are now central to the way we can animate. So my hope is to make this type of motion easy for you to think about and easy for you to use in your app. Some things that are easy now that were hard before. Responding to user interaction-- by which I just mean a touch-- chaining animations, modifying them on the fly; getting great natural movement with much less visual jank. So I'm going to step through the mechanics of the two dynamic animations we have right now and then we'll mix it up. So the first, a fling animation. It starts with an initial velocity, it slows down, and it ends gradually. So every time that color changes, it's starting a new fling. And here's the simplest fling that you can possibly make. Ball is a view. Translation y is the property we're changing. And its velocity is pixels per second. I discovered while making this that pixels are a lot smaller than I thought. Everything else is defaults. And so that's what you just saw. You can customize a fling by changing its friction, the factor by which it slows down. So here's an example of friction. So from left, you have high friction to low friction on the right. So the less friction that you have, the more distance your view will travel for a given velocity. And here's a spring animation. And it looks just like what we'd imagine from the motion of a physical spring. It exerts a force back to the endpoint of the spring, and you can even get a bounce. So every time the color changes that is a new spring animation. And here's the simplest spring you can possibly make. Ball is a view, translation y is the property we're changing, and zero is where it's going to stop, which is its final translation at equilibrium. And its velocity is pixels per second. And everything else is defaults. And it just goes. So to customize this, you can call getSpring on your animation, and that gives you its internal spring force object. And that has a damping ratio, a stiffness, and you can see that the final position. Damping is the ratio by which the size of your bounce is reduced over time. And the default is medium bouncy. In general, the lower the number, the more oscillation you'll see-- a.k.a. bouncing-- before the force is going to reach equilibrium. At 1 you get critical damping, which means no bounce, and at 0 you get no damping, which means infinite bounce. Don't do that. In general, please do not under-damp your views. This crazy bouncing is what made me think at first, why on earth would you ever want to do this to a view? So try little or no bounce, and I think you'll be surprised how useful this animation can be. Stiffness is like the stiffness of a physical spring. So for a given starting velocity, how far will it travel from the endpoint, and how fast will it be pulled back? This example has no bounds so that you can see the difference in the stiffness better. The lowest stiffness is on the left, so it's traveling further. The highest stiffness is on the right. And you can also create your own external spring force in order to share it among multiple animations. We'll see why you might want to do that in a moment. So one thing you might want to do with these animations is allow user input. So velocity tracker is one option to handle this. It's an older, but a goodie. This class has been around since API 1. It does what it says on the tin. It tracks velocity from a user's touch. You can also use just your detector if you only care what the end state of the fling is because its fling callback has velocity. So how would you use this? We're going to go with velocity tracker for now. You'd use it in a touch listener on the parent of the view you want to track. Parent is important. Call velocity tracker to obtain to get an instance of the tracker, then you can feed in the user's touch events, starting with down and continuing with move. Then in action up you'll call compute current velocity, and it will compute a nice velocity for you. After you're done make sure to clear it. That velocity is going to come in two components, x and y. Then you're going to start two dynamic animations at the same time-- one for the x velocity and one for the y velocity. This would be a good reason to share a spring force. They're going to run simultaneously. And as you can see, this is enough. This gives you a smoothly moving interactive two-dimensional animation . As you can see, it works pretty well. Just be careful when you fling because they do not automatically stay on the screen. And when they're gone, they do not come back. Just like other animations you're familiar with, dynamic animation also has end and update listeners. So that's how I was chaining them in my earlier demonstration and changing the ball colors to repeat over and over again. So let's chain two fling animations. We're going to fling just as we did before using the velocity from our drag listener and velocity tracker. And we're going to create two fling animations at the same time-- one for x and one for y-- to get natural movement. Then we're going to stop the first animation at the edge and create a new one in a different direction, giving the impression the ball has bounced. This time we'll add an update listener and an end listener to each of our flings. On each update, we'll check to see if the ball has slipped outside the bounds of its parent. There's probably a better way to do this, but that's an exercise for the reader. If it did go outside we'll cancel the animation. That means we'll get a callback to on animation end. If we canceled it, meaning it hit the edge, then fling it back. As you can see, I made an extension function on view here because I got tired of typing. We'll use the velocity past here, which is the remaining velocity from the canceled animation. And we'll use it in the opposite direction, which is the minus sign you'll see there. Of course, it's not exactly that simple. What this does is it flings the ball straight back at you because it reverses both of its velocities, x and y. So what we really want is natural reflection. We want it to only reverse its velocity on one axis but continue on the other. And that's what will give us this 90-degree bounce angle. So it's not too hard. It looks like this. If it's hitting the horizontal edge, reverse x. Otherwise, reverse y. And we get a nice reflection or bounce. And it also works with different animations. Ever seen something like this? There's an app that keeps trying to do this on my home screen. I don't why I'm encouraging you to do this, but it's interesting because it's quite simple. And it's sort of a sticky effect, where if you fling it to the edge, it sticks there and absorbs the extra momentum with a spring bounce. So if you do this, it's going to look something like this. The thing to note here is that we're using the ball's current translation value as its end value for the spring. So we're going to fling as before, put an end listener. And then when we get the callback, go ahead and oscillate until you reach equilibrium, dissipating the remaining velocity. Chaining springs. There was a really cool demo in the Google I/O talk I went to of three balls connected with springs. I'm not going to explain that here because they did a great job already in that talk. So if you want, go look it up and then come back. So here's a real layout from an Android app using the same effect. This is inspired by a screen in the plaid app by Nick Butcher-- sorry, Nick-- where as part of the screen transitions, there's several onscreen components that translate up subtly one after another. So in that effect, the distance translated, the delay of each element, and the interpolation used to simulate acceleration and deceleration are all hard coded by hand. That's a pain in the butt. Here it's all done with the same chained spring we just saw with the balls. I'll go through how that works. So what's actually going on here? These two springs are almost exactly the same effect. Obviously the top ball, the blue ball, is the lead, the yellow ball follows it, and the green ball follows the yellow ball, almost as if they're chained together with bouncy springs. In the actual app example, the lead view is the headline and icons. The next view, the paragraphs, follow it, and finally, the FAB is following the paragraphs. You can see here that there's no rule that these views actually have to be in a line in terms of position. They can be anywhere. What matters is the propagation of effects from one animation to the next. So how do we do this? Instead of a touch listener, I started with a fixed spring animation on the headline. The thing to notice here is that instead of giving it a velocity, I gave it a start value. Basically I said, pull the spring back this far and start it there. And I gave it an update listener, which we've seen before. Then I made a spring animation for the paragraphs, exact same thing. In the listener getting callbacks from the headline, I call animate to final position on the paragraph animation. This [? isn't ?] a really important and useful method. So it's going to do two things. One, it sets the new final position of the paragraph spring to the current position of the headline animation. And two, it starts the paragraph animation if it hasn't yet. And then finally, we'll do the same thing for the FAB. We'll set an update listener on the paragraphs and chain a spring animation to that. And that's how chaining works. The difference here from what we were doing before with flings is that those animations were subsequent one after another, and these are actually happening simultaneously. You might also notice if you're looking very closely that I also used a spring on the alphas of the views and on the scale of the FAB. So what else can you animate? And you can animate a lot of built-in properties. Certainly everything I can think of flinging or springing off the top of my head you can animate. Alphas, translation, rotation, scroll, scale, and x, y, and z, which are absolute positions, including translation. But if you want to animate something even crazier or just make a custom property that groups a couple of these, you just make an instance of float property compact. You also need to set the minimum visible change so the animation knows when to stop and doesn't keep on animating tiny, tiny bits forever. You can also start every dynamic animation at a particular start value, give them a minimum and maximum, and finally cancel your animations. Because if your user quits the activity while they're running, your app will crash. So cancel them. These APIs are available from Jellybean and above. And I'm sure you got all of that. But if you didn't, all the code for every one of these demos is on my GitHub, lisawray/physics-playground. So my takeaway here that I want is physics-based animations. They're not toys, and they're not just for games. They're way more than bouncing balls. They're a great way to bring natural motion and interaction your current UI. So I look forward to seeing what you make with them. Thank you. [APPLAUSE]
Info
Channel: Google Developers
Views: 5,976
Rating: undefined out of 5
Keywords: Google developer days, GDD, GDD europe, google developer days Europe, google developer days Europe 2017, developer days, Dan Galpin, Lisa Wray, Android O, support library, android support library, physics based animations, Google developer days Krakow, GDD krakow, google developers, web developer, google, developers, developer news, google developer conference, developer conference, web developer conference, mobile developer conference, developer products, developer platforms
Id: WmGfr3vK_g4
Channel Id: undefined
Length: 30min 40sec (1840 seconds)
Published: Tue Sep 05 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.