Recyclerview to the rescue
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 46 | |
Author | ||
License | CC Attribution 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/47165 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
droidcon Berlin 201535 / 46
5
7
10
13
16
18
20
21
23
26
31
34
35
36
41
42
45
00:00
Android (robot)Mobile appLecture/Conference
00:19
Mobile appLibrary (computing)Android (robot)GoogolLimit (category theory)Electronic mailing listRevision controlMeeting/Interview
01:21
MereologyEmailElectronic mailing listContent (media)XML
01:47
Demo (music)EmailMereologyVideoconferencingContent (media)BitOcean currentXML
02:26
Demo (music)RepetitionConvex hullLinear mapChi-squared distributionEmulatorInterior (topology)Demo (music)Source codeNormal (geometry)Graph coloringMereologyGreatest elementOrientation (vector space)Web pageRow (database)BitElectronic mailing listDisk read-and-write headDivisorLink (knot theory)Group actionDataflowStandard deviationInverter (logic gate)Slide ruleLine (geometry)Visualization (computer graphics)Computer animation
05:58
Chi-squared distributionLinear mapVacuumGUI widgetDefault (computer science)Demo (music)FreewareWeb pageQuicksortMultiplication signRight angleProcess (computing)Structural loadLine (geometry)Lecture/ConferenceMeeting/InterviewProgram flowchart
07:37
Electronic mailing listLocal GroupMultiplicationLibrary (computing)Library (computing)Electronic mailing listDisk read-and-write headGroup actionComputer animation
08:16
Vertical directionElectronic program guideData managementSoftware developerMemory managementFile viewerMultiplication signVertex (graph theory)LogicElectronic mailing listTouchscreenAndroid (robot)Computer animation
10:07
CountingType theorySkeleton (computer programming)Keyboard shortcutPosition operatorDifferent (Kate Ryan album)Instance (computer science)Lecture/ConferenceSource codeJSON
11:04
EmailElectronic mailing listType theoryDemo (music)Position operatorLecture/ConferenceComputer animation
11:34
Execution unitPoint (geometry)Position operatorBoom (sailing)Message passingSource codeJSONXMLUML
12:07
Android (robot)Constructor (object-oriented programming)Execution unitCountingMultiplication signType theoryCache (computing)Different (Kate Ryan album)Computer animationSource codeJSONXMLUML
12:38
Android (robot)Constructor (object-oriented programming)Electronic mailing listGoodness of fitComputer animation
13:13
Android (robot)Constructor (object-oriented programming)Medical imagingVariable (mathematics)Category of beingUniform resource locatorConstructor (object-oriented programming)Social classField (computer science)Computer animation
14:19
Descriptive statisticsParameter (computer programming)Constructor (object-oriented programming)JSONXML
15:15
Run time (program lifecycle phase)Software frameworkData managementMereologyImplementationHypermediaElectronic mailing listSource codeMultiplication sign1 (number)LinearizationDemo (music)Computer animation
16:13
Electronic mailing listRun time (program lifecycle phase)WaveElectronic mailing listClassical physicsLecture/Conference
16:43
Android (robot)BitElectronic mailing listRun time (program lifecycle phase)Configuration spaceJSONXML
17:06
Electronic mailing listTwin primeUser interfaceBitElectronic mailing listData managementCodeComputer animation
17:29
Data managementElectronic mailing listPoint (geometry)LinearizationVariable (mathematics)BitIntegerNumberRight angleSource codeJSONXML
18:25
Row (database)Electronic mailing listComputer animation
18:44
Data managementCodeComputer animation
19:18
Position operatorEndliche ModelltheorieData managementCountingDecision theoryData conversionPattern languageData modelInformationElectronic visual displayParameter (computer programming)Instance (computer science)ImplementationXML
20:35
Electronic mailing listContent (media)Data managementContent (media)Goodness of fitDependent and independent variablesElectronic mailing listMobile appComputer animation
21:04
Endliche ModelltheorieTouchscreenElectronic mailing listMathematicsContent (media)State observerSet (mathematics)Range (statistics)Context awarenessCASE <Informatik>JSONUML
22:05
Electronic mailing listContent (media)Default (computer science)Position operatorDefault (computer science)CASE <Informatik>Range (statistics)PlastikkarteMathematicsSet (mathematics)State observerComputer animation
22:54
UML
23:17
FreewareDemo (music)Convex hullRight angleSoftware repositoryXMLProgram flowchart
23:43
FreewareDemo (music)Similarity (geometry)Pattern languageVertical directionMultiplication signProjective planeBoundary value problemConstructor (object-oriented programming)Pattern languageFrame problemComputer animation
24:47
Slide ruleLecture/Conference
Transcript: English(auto-generated)
00:05
All right, hello, first I'll introduce myself. My name is Brett, as you just said. I work at RDO, and I've been there for about four years, and I've been working on the Android app for about three of those years.
00:22
Now that's out of the way, let's talk about RecyclerView. I think the first thing I should do is sell you on it. So why should you use it? Because you probably already have an app that's written, it's probably using ListView or GridView or something like that. But I almost guarantee you probably run into problems with it, or run up against some serious limitations
00:41
as your app evolves and you want to make a more complicated UI. Especially GridView starts falling short really quickly. So that's why RecyclerView is coming to your rescue. They announced it last year's Google IO, 2014 Google IO, they announced the RecyclerView.
01:01
And I don't think a lot of people have really started adopting it yet, although it has been getting incremental updates in each support library revision, and I really think it's the future, and that's where most of the Android engineering work is gonna go into RecyclerView, and probably not so much into the Legacy ListViews. But let me show you an example here
01:21
of something that maybe you've tried to do in the past, or your designers asked you to do in the past, and it's really hard to do with a GridView. So you have a grid here with a header that's part of the content, not just a header that's above all the content, or a footer that's below all the content, like the way that ListView headers and footers work.
01:41
It's in the middle here. This grid has three columns, but you want this item to span all of them and be full bleed, and then maybe you want to have some items that are a little bit bigger, because maybe they're more important or whatever, and so this is gonna span two columns, and then everything needs to flow around it. The current GridView doesn't do this at all, really.
02:03
You can implement a header GridView if you want, but it really does headers surrounding, so headers and footers that surround the content, it's hard to get it to be part of the content. But with RecyclerView, it's very easy to do something like this, and I will show you in just a bit,
02:21
but I think a video or a live demo is gonna be more exciting than just looking at a static picture. So I'm gonna bring up the Genymotion emulator, give those guys a shout out. They have a booth downstairs, and I've been using Genymotion for like a year,
02:41
and it's pretty awesome. So here's the demo. We start out with just a standard list. It's pretty normal. It's got some headings. So this is a RecyclerView, and it does pretty much what the normal ListView does.
03:00
I've added a little bit of an animation to the bottom. That's not part of RecyclerView, but it kind of makes the scrolling a little bit nicer, and it's a little kind of more materially. The source code for this demo is on GitHub. The link is at the bottom of every slide, so you can see how I did that animation. I'm not really gonna go into that during this demo. Okay, so this is kind of a standard.
03:20
Okay, it's got a list. It's got some headings in between the groups here, right here. So then, let's go. That's not too exciting. We'll go over here to the grid. So, and this is, it's important to note that some of the view pages are in there, and each, I have one fragment with one layout,
03:43
and then it's just configured a little bit differently for each tab. The fragment is, the layout just has one RecyclerView in it. And so I just basically tell this RecyclerView, hey, be a grid. And I'll get into more of that later, too. But so it's doing, and this is just like kind of a standard grid,
04:00
and you can scroll through it, and it doesn't have anything special in it, but it gets a little more exciting when we go here, where we have, now we're implementing this nice, this heading. So maybe you have, maybe you wanna show groups, and you wanna delineate between, maybe this is like top charts or something like that, and then the next one is like maybe new releases
04:22
or something like that. And you wanna be able to have this kind of visual, and it's kind of hard to see this color here, but there is a divider there. So that's cool. But then let's get a little crazier, and then let's see here. Spans are, these bigger items are just randomly added. That's what I have right now. But so here's one where it's just,
04:42
you're getting this nice, everything's lined up correctly. See, the gutters are nice and aligned here. The height is aligned here, and things flow around the bigger item. And that's actually, I've tried to do this in the past with grid view, and it's possible, but a lot of work.
05:01
Not so much work with recycler view. Okay, and then we go one more little bit of craziness. This looks kind of the same, but if you look at this first row here, there's a little bit of, it's kind of bleeding off, which implies that you can scroll this. So this is gonna be, this first row here is actually a recycler view inside of recycler view.
05:24
And then I have these items that are spanning. So as we go through here, here's these lists come through like this. And I do this just to show that it can really handle pretty much any situation you throw at it. And the way this is implemented, again, you can see this in the,
05:41
if you look at the source code for the demo, but this is just an item that I've told the outer recycler view, hey, this thing spans all of the columns. And then this item itself happens to have a recycler view in it, and I've set it to be in a horizontal orientation. So then now you have, and that's one thing that you never got with the standard widgets,
06:03
was a really good horizontally scrolling view, right? You have horizontal scroll view, which all it does is take one child and kind of moves it around. But it doesn't work with an adapter, so it's really hard to have page data in there. But with this, it works just like an adapter backed view. So you could page load it, you could infinitely scroll,
06:20
you can do all sorts of stuff. So that's as crazy as I got with this. Then one last thing, let's go back to the beginning. I'm just gonna show you all the things that the demo does at the beginning. Okay, so I have a little plus button here, and a lot of times you wanna let users add or remove items. And it's not that hard to actually add or remove item,
06:41
but usually it's hard to get it to look like the item is adding as opposed to just appearing. But recycler view lets you do stuff like this, that one, maybe this one. And it's the same thing with the grid. It does a really nice job of letting you add
07:01
these new items here, scrolls them off, delete them. And this is all pretty much for free. There's default animations, as long as you're calling the right things, it'll animate that stuff for you. And it works with any one of these, even the really complicated one here. Although I only have it, I could have had it adding things that span, but right now it's just doing the one.
07:21
In the line of my time. Okay, so that's basically my demo reel of why you should be using it. Hopefully I've convinced you by now that it's something that you might wanna start looking at using. Let me switch back here. We'll get into how I did some of that stuff.
07:43
And this is just reiterating what you just saw. You can do simple lists, you can do simple grids, you can do grids with group headings, you can do a grid with headings and multi-column items, you can do all that with nested horizontal lists. And it's pretty nice. So, again, why should you use it?
08:01
It's pretty awesome. It's very flexible. It's in the support library, so you don't really have an excuse, a compatibility excuse to not use it. And ListView and GridView are terrible, and they make you sad. Or they make me sad at least. All right, so let's get into the anatomy. I think it seems, at first glance it seems,
08:24
well, maybe this is a little different, but it's pretty much the same as what you're used to using. There's the view, there has an adapter, it serves basically the same purpose as a ListView adapter does. The new things are here, the layout manager and the view holder are basically the two new things
08:41
that you might need to get familiar with. So I'll just dive into each one of these. So the RecyclerView knows how to recycle views, and that's it. And by that I mean that it only knows, it works with the layout manager to know when a view is either going off screen
09:01
or coming on screen. And it knows whether it needs to put that particular view or view holder in a scrap heap or take it out of the scrap heap or ask for a new one to be created, things like that. So what they've done is they've extracted all of the layout logic from the view itself, which is what the big problem with ListView and GridView were,
09:21
is that they had to recycle the views and know where the views need to be laid out. They fixed that now. So the layout manager is where the real magic happens. But basically the RecyclerView is what you put in your layout. And it's not a list or grid, it's not horizontal or vertical, it's everything. It just depends on what layout manager you give it.
09:45
So the adapter is conceptually the same thing that you're probably already used to. It provides and binds view holders to be displayed. And so view holders, some of you are probably familiar, it's like a best practice that they've been,
10:01
that they've had in the Android documentation or developer guides for a long time. And I'll give you an example of those. But they're really just kind of wrappers around your view. So here's, so you can see this. This is just like a kind of pseudo CODI skeleton of a RecyclerView adapter. And if you look, it's pretty much what you would expect
10:22
from a regular adapter. You have to implement an item, get item count. And the difference is here is rather than just a get view you have onCreateViewHolder and onBindViewHolder. Get view, you have to check the past and convert view. If it's null, okay, let's make a new view. And they've separated that out, so it's kind of nice now.
10:44
You know here, always make a new instance. You know here, this will never be null. Do your binding and everybody's happy. And then one more thing that's cool about, you don't have to implement, but what makes it much more powerful is this view type they're giving you.
11:00
This isn't, when they say create view holder, they don't give you a position to create it for. They give you a view type. So get item view type is similar to the one that's in the regular adapter, but it's more powerful, I think, because it lets you make like what I have in the demo
11:22
where some items are different layout than the others. And the best way to use it is return a layout resource ID for that position. So when you're onCreateViewHolder is called, what you return here, it's passed in here,
11:42
and then you can just inflate it, pass it to your view holder, boom. So there's no looking up, oh, what view do I need here? You've already answered that question, the view at that position. You've already answered it. It's telling you at this point, I need this view created for me.
12:03
So, and it's also, I have notes for that too. Oh, I'm in the view holder. So also note that there's get item view type, but there's no get item view type count. You don't have to know ahead of time or any time. You don't have to tell the RecyclerView
12:22
how many different views you're gonna have. It doesn't care. Internally, it's creating like a partitioned caches for each different view holder, so based on what you return here, from here and then there. Okay, so view holder,
12:43
this is getting towards the last piece. So the view holder should sound familiar. Like I said, it was an established best practice, but now they're actually enforcing it, which is a good thing, because it'll make your lists that much more efficient when you're scrolling.
13:05
So it acts as an access wrapper around your item views. So the view holder itself is just like, it really doesn't do much. You give it, when you're asked to create a view holder, you inflate your view, you give it to the constructor of the view holder, and then in your constructor,
13:20
you should do all your find view by ID calls, and assign them to member variables of the view holder. So for example, if your view holder has an image and like a text field, your view holder class might have a member variable that's, excuse me, a member variable that's called,
13:40
it's a text view called like primary text, and then an image view called, you know, image or whatever. So then in your constructor, when you're creating the view, you have to look them up, and then you would add accessors to your view holder, subclass that are like set primary text, set image URL, and then what your view holder's gonna do
14:01
is check to see if that view happens to be not null, and then set whatever property on it that you wanna do, which makes the view holder very flexible, because you could use it with different layouts, if it doesn't find the image, and you're null checking that, it just doesn't find it, you don't set it. So you can still use a view holder, but it just lets you kind of selectively use layouts. So here's kind of a simple example of a view holder.
14:24
So you extend the RecyclerView view holder, the only real requirement there is that it has a constructor that takes a view as a parameter. So what you do here is you find your text view, and then you'd make an accessor here to set the text, because generally you don't even really ever need access
14:41
to the actual text view itself, you probably just wanna set the text. And then you can make things like, oh, hide it, show it, stuff like that. But it also makes a nice description of what this view holder is supposed to do, because instead of just, I mean, I like to do it this way, but instead of just exposing this, you expose specific things that you want to do
15:00
with that view, set primary text, hide primary, something like that, and then since you're null checking everything here, it's just a nice clean way to use it with different layouts. If that view happens to be missing, this thing will still work. We'll just bypass that view. So now, layout manager, which is kind of the meatiest part,
15:21
it's definitely the most complicated if you look up the source for it. There's a lot going on in there. It's very similar if you look at list view, the list view implementation, all the crazy stuff it's doing to try to figure out, or grid view's even crazier, but to figure out where these things need to go, that's been pulled out into layout manager.
15:42
And there's different implementations of it. The good thing is that they've added standard ones, and they're all pretty, like they cover pretty much anything you can throw at it. They have a linear layout manager that's for list. They have a grid layout manager that's for a grid. They even have a staggered grid, which I didn't show in the demo, I ran out of time when I was making it,
16:00
but so you can do like cool Pinterest and Etsy style staggered grids, and that layout manager knows how to do it. So if your grid items are of varying height, it knows how to pack them correctly. But so it also, they can easily be switched. There's no like setting up in the layout,
16:20
oh, this recycler view's gonna be a grid, and that's it. This recycler view's gonna be, you don't do that. So you can switch it at runtime, so you don't have to do a view switcher, which is like, this is kind of the classic way of, and oh, well this view, sometimes it's a grid, sometimes I wanna show the data as a list. You do a view switcher, you put the two in there, you switch between the two children,
16:41
it's okay. But not as great as just putting a recycler view in there and that's it. So it makes, it's just a little bit simpler rather than having to be like, because if you have that view switcher, then it can only be that list or only be that grid. This could be a horizontal grid or a horizontal list
17:01
or whatever, you know, you're not defining it here, you're defining it at runtime. So it lets your user potentially configure the user interface a little bit more. Okay, so we'll get into kind of putting it all together, making a simple list and a simple grid. These are like the three things you have to do.
17:21
Put a recycler view in a layout, you set the adapter on it, you set the layout manager on it and you're done. So I have some code snippet here. It's kind of hard to read, I bet for people in the back, but basically what I'm doing here is like, this is a onCreate view of a fragment. Just inflate your view, find the recycler view.
17:41
Say you have a member variable or something that's like, hey, this, we're showing it as a list right now. So this is like, here's the magic. Just set layout manager and do linear layout manager, you're done, or grid layout manager, and then you tell it how many columns you want. And this is cool too. It's similar to setting num columns on the grid view.
18:02
This value could be like, I like to put it in an integers XML. So for landscape maybe of four columns and then for portrait you have two or three, something like that. And then here, assuming you have data at this point, you set the adapter and then you're done. Well, if you also had to have created
18:22
those view holders before that there was adapters gonna give to the recycler view. Okay, so now we know how to make a simple list, a simple grid. We wanna be able to do the cool things where you have things kind of span rows or columns and all that stuff. So I'll show you how to do that.
18:40
It's pretty simple. So there's a thing, I think I screwed up this name, but it's in the code, it's right. It's not in recycler view, it's in grid layout manager. So there's a thing called span size lookup and it works with a grid layout manager to figure out how many columns and items should span.
19:03
And the span means like a span of one means I live in one column and so on. So one, that means I don't span anything any more than that means you need to accommodate me however many spans I want. So here's like an example I have in my adapter,
19:23
I just made an implementation of the span size lookup. I put it in the adapter because it's gonna be asking you for this position, what's the span size? And so since the adapter knows about the data that it's putting into the view,
19:41
seems like a good place to put it. And then here it's just like, okay, check your layout manager instance. If it's a grid layout manager, then set the span size lookup, get it out of your adapter, just set that and then you're done. I just wanna put out here that it says view models.
20:00
I use the MVVM pattern. I think there was a talk about it yesterday. I highly recommend it because here it kind of extracts the information from your data model into like a view model, so it's just for display. I put span count in there, I put a layout parameter on there and it makes it really easy for your adapter just to be like, for this view model at this position,
20:21
it doesn't have to make any decisions. Those decisions are made way before this even happens because the thing that's actually handling getting the data converts them into view models, but that's a separate conversation. So back to this. So now basically what I just showed you lets you do this.
20:42
That's it, span size lookup, set it on. If you're using a grid layout manager, you set it on there and you can do things like this. And then the last piece is modifying the list contents and getting those nice animations because it's just nice to be like in a nice,
21:00
good responsive app, you're gonna show like you're adding something, it looks like it's getting added, it looks like it's getting removed instead of just appearing and disappearing. Traditionally, you have to do a lot of heavy lifting to do that. ListView doesn't really handle items that are animating very well. Fortunately for us, RecyclerView's gonna come to our rescue again. So here's the old way,
21:22
potentially without an animation. You have maybe a remove item on your adapter, you remove the model from the dataset, you notify dataset changed, the list updates. The problem with this is your dataset observer, in this case, your ListView, all it knows is that the dataset changed, it doesn't know what changed about it.
21:41
There's no context, it's just, you're like, hey, something changed. But you don't know, was it removed? Was it added? Did something get swapped? Did you just update the contents of one item or a range of items? It doesn't know. So the only thing the observer can do is just say, well, I better just redisplay all the things that are currently on screen.
22:01
Which, I mean, it works, but it's not super great. Now we have all these new, really nice, new API for actually telling the observer, in this case RecyclerView's the dataset observer, you can tell it exactly what happened. Oh, hey, an item changed, you give it a position.
22:22
An item was removed at this position. An item was added at this position. There's also more, there's like, you can say a range of items have changed, you can say, I think there's one for telling them that things have changed positions or been swapped. So now that the RecyclerView has a way of knowing exactly how the dataset changed,
22:41
it can do something smart like animate the change because it knows exactly what happened. So that's why you get these default animations and you don't have to do anything to turn them on, they're already there. So this is all you have to do from that previous example of the old way, this is the future where you just say, you know that someone removed an item, now you can tell the RecyclerView
23:01
that this item was removed or this item was added. This is all I had to do in that to get those nice adding and removing animations, the grid one where it kind of puts them in place. This is all you have to do and it just does those animations for you. I'm gonna go back to my cool animated GIF just to reiterate, all you have to do
23:21
is use the right notify methods and you get those nice animations, just like here. I think I took these off the GitHub repo. But there you go. That's probably one of the coolest things is you really don't have to do anything to get that.
23:44
Yeah, it's coming to an end, I didn't go my full time, but I'll just recap that RecyclerView is the future, you should be using it or you should at least be thinking about using it, use it in a new project maybe. Think about converting your existing projects
24:00
because the API is very similar, your adapters don't really have to change very much. You're gonna have to use ViewHolder but that's not a hard thing to implement either. And then you're gonna get a kind of this way cooler, a more powerful view. That's about it. Yeah, I mean, I've covered the modification. ViewHolder pattern is enforced,
24:20
which is great because now you're not, if you're doing all your find view by ID calls in the constructor, then every time you're binding the view, you're not calling find view by ID anymore. And you only have 16 milliseconds between frames, why waste them calling find view by ID again? You're just kind of come right up to that boundary
24:40
where you're gonna drop a frame and then you don't wanna do that. Yeah, so that's it. I didn't make a last slide, so let's end the show.