Handling Filter Selection11:58 with Jamie Huson
Simplify your filter selection using RxJava.
Let's take a look at our model for filtering the list. 0:00 Right now we have a complex listener set up and 0:04 it uses this to do list filter object. 0:07 So let's try to think about this a little bit simpler. 0:11 So right now, we have our spinner and we have this selection and we have 0:14 the AdapterView.onItemSelectedListener that comes with Android. 0:21 And it's got these two callbacks onItemSelected and onNothingSelected. 0:25 And one thing that's interesting about these callbacks, 0:29 these listeners for the spinner, is that these items are gonna be 0:36 called back when even the first initial value is set on them and that's not 0:40 something we really want and so we only care about changes to the data set. 0:45 We don't care about the initial data setup here. 0:50 So these filter is gonna have some initial value like the all value. 0:52 And we don't wanna be notified when that happens that's just gonna be the first 0:58 thing displays but we can simplify it's a little bit using 1:01 RxBindings that we had included in our dependencies. 1:06 So here's the first thing we're gonna do we can use RxAdapter view. 1:10 And this will transform our OnItemSelectedListener 1:16 into an observable we can use. 1:20 So let's call itemSelections and pass in our spinner. 1:22 And this gives us now a observable. 1:27 And the first thing we want to do is, 1:32 we're actually gonna use an operator called skip. 1:34 And it just takes an account so what we really wanna do here is skip that 1:37 first item that gets emitted cuz remember we only care about when changes happen. 1:43 We don't care about the initial value that's set. 1:48 So let's skip that first value there. 1:50 And now what we wanna do is we wanna update the adapter 1:54 with the items that are filtered based on the selected item in the spinner. 1:57 So we're getting the items emitted from the spinner as they come. 2:01 So we wanna combine both the items emitted by the to do list, that subscription. 2:04 And the filter together. 2:10 Because when the filter changes or 2:11 when the items in the list change, the adapter needs to know and needs to update. 2:13 So what's interesting here is the adapter doesn't need to know about filters. 2:19 It really just needs to know about the items to display. 2:24 Right. Which items should be in the list. 2:28 It doesn't care what filter mode specifically is happening. 2:30 It doesn't need to know that. 2:35 So what we're gonna do is we're gonna use an operator. 2:36 It's called a combined latest and this is really gonna help us in this case. 2:40 So here's what we're gonna do, 2:44 we're gonna wrap all of this in an operator and 2:48 combine latest takes in two observables. 2:54 The first one is our adapter view, which is our spinner for the filter. 3:00 The second is going to be our list, 3:07 as the observable and so what's gonna happen is we're gonna 3:11 combine the latest value from both of these observables. 3:16 So we're gonna combine the latest filter and the latest data from the spinner and 3:20 we do this using a function. 3:24 And this function takes in integer that's what item was selected in our spinner, 3:33 our to do list and then we need to specify what it's actually going to then emit out. 3:38 And what really we need to emit out here is just the actual to do's were 3:44 displaying. 3:48 So that's gonna be a list of to do's. 3:49 It's not gonna be the to do list object, because that's all the data set. 3:51 We really just want the subset of data that we should be displaying 3:56 right now based on what the filter is currently selected at. 3:59 So we're just gonna return back a list of to do's and 4:02 now we can implement the call for that. 4:05 So here, we're gonna get the integer, that's our filter, that's the selection 4:08 from the spinner, so we can switch on that and we have a few 4:13 different cases and those are defined over here in our TodoListFilter class. 4:20 But what I wanna do is I'm actually going to move those and I might create a new. 4:26 Interface over here. 4:37 And it doesn't need to be an interface but I'm just gonna make an interface. 4:39 I'm just gonna call it filter positions. 4:42 And in here, that's where I'm gonna move these three values. 4:51 We just broke some of the code in here, but don't worry. 5:03 We're gonna come back to this right in a second. 5:05 So hang in there. 5:07 But we're gonna use filter positions now and there's a few different ones. 5:09 Incomplete, now we're gonna return back the data here. 5:14 And how are we gonna return specs. 5:18 So before we had our to do list filter object and this was filtering data and 5:19 creating these new lists based on what items should be in it or not, and 5:23 it was creating the new to do list items. 5:28 We don't really need that anymore we're just wanting a list of individual to dos. 5:30 So, what we're gonna do is we're just gonna move this functionality into to do 5:34 list itself we're gonna ask the to do list, hey, what are the incomplete items, 5:39 what are your completed items or, what are all your items? 5:43 So, let's add those methods to our to do list itself. 5:46 So in our to do list the easy one to do is. 5:53 Get all. 6:02 So in get all we can just return our to do list because remember 6:04 to do list class, really just holds a list of to do's anyway. 6:09 So we actually the underlying data is really just a list of to do's so 6:14 we get all is easy want here. 6:18 We can also send you. 6:20 Again, the list of to do's getting incomplete will be the next one. 6:23 So just the items that are not completed. 6:28 So for this we can just create a temporary array list. 6:32 Call it incomplete. 6:37 And for each item in our list. 6:43 Or you can check if it's not completed we wanna go ahead and add it. 6:52 And then finally we're gonna return back that list and 7:01 get complete, looks almost the exact same. 7:07 It's just that the logic here for checking is the opposite. 7:11 So all we need to do here is just check if it is completed and 7:17 probably wanna name this better because this is now a list of complete to do's. 7:21 So with that in place we can go back here to where we were applying this 7:30 function that transforms our spinner selection, which is our filter. 7:35 And the latest data emitted by our list into one single subscription. 7:42 So here what we're gonna do is just say if it's incomplete, 7:48 we wanna get the incomplete data. 7:54 If it's complete, get complete. 8:01 Otherwise, return back all. 8:06 So this combined latest operator is now allowing us to capture whatever 8:14 there is been selection changes whenever the list changes. 8:19 Modify it with another operator function that transforms it 8:24 into just the list of to do's and that's what we care about displaying. 8:28 So what we wanna do here is now we wanna subscribe to this 8:32 combined latest Observable. 8:37 So let's go ahead and subscribe. 8:39 And what's gonna subscribe to this is our adapter. 8:43 So our adapter wants to be notified whenever the spinner, 8:48 the filter changes, or the list changes the dataset. 8:53 So what you'll notice here is that this is incompatible because 8:57 here we're returning back list of to do's and the adaptor not looking for that. 9:01 The adapter is actually looking for our do list here. 9:06 And its action one, which is its observer method. 9:12 So what we need to do is just change this. 9:17 So here, instead of displaying to do list, we just want to display a list of to do's. 9:19 And up here we want to change our to do list to be a list of to do's. 9:35 And. 9:43 Make sure we use the right call back here with the right type. 9:47 And now it looks good now. 9:58 So here we're keeping our data as a list of todos. 10:01 We can still call size and get individual items from this list. 10:04 And now, back in our main activity. 10:10 Our adapter can be a subscriber to this combined latest observable. 10:14 So, we cleaned up how this interaction works because simplified it and 10:19 condensed it into a nice logical piece of code. 10:24 And we can further cleared up by getting rid of all the things that we don't 10:28 need anymore. 10:30 So we don't even need this to do list filter class anymore. 10:31 This isn't doing anything for us. 10:34 But also, let's go ahead and delete it. 10:35 Okay. 10:46 And our to do listener from before. 10:46 We're not using this anymore. 10:48 Let's go ahead and delete that, as well. 10:49 And what we'll see is that there were some references to our 10:56 list as observable subscriber. 11:01 Here this is our old subscriptions we don't even need this anymore we've 11:03 combined these together using combined latest operator. 11:07 And we also have really simplified this 11:14 to the point of not needing the TodoListFilter all together. 11:17 So we're just gonna delete this code here for our filter. 11:21 And any references to it as well. 11:32 In fact we don't need this anymore cuz we move this into. 11:35 Our item selection observable here that we are using in our combine latest. 11:42 Okay so we've simplified a lot of things here. 11:48 And we're gonna keep moving forward until our app is mostly completely 11:51 converted to RX Java. 11:55
You need to sign up for Treehouse in order to download course files.Sign up