1 00:00:05,650 --> 00:00:06,483 Alright, so this adapter's 2 00:00:06,483 --> 00:00:09,220 going to use a cursor as the source of 3 00:00:09,220 --> 00:00:10,930 the data to be displayed. 4 00:00:10,930 --> 00:00:13,470 So we need a field to hold the cursor. 5 00:00:13,470 --> 00:00:15,830 So I'm gonna add that to the class constructor. 6 00:00:15,830 --> 00:00:17,180 What we have to do is specify 7 00:00:17,180 --> 00:00:19,390 the nullable type cursor question mark 8 00:00:19,390 --> 00:00:21,380 because the cursor, our cursor, 9 00:00:21,380 --> 00:00:24,640 will be null until we've downloaded the data. 10 00:00:24,640 --> 00:00:26,810 So let's have a go at doing that. 11 00:00:26,810 --> 00:00:30,660 So we're gonna add in parentheses after the class name, 12 00:00:30,660 --> 00:00:31,493 private 13 00:00:34,250 --> 00:00:35,720 var 14 00:00:35,720 --> 00:00:36,553 cursor: 15 00:00:37,850 --> 00:00:40,290 and Cursor? as I mentioned. 16 00:00:40,290 --> 00:00:42,550 Let's now edit that cursor to the constructor. 17 00:00:42,550 --> 00:00:45,090 Alright, so there's three methods we have to implement 18 00:00:45,090 --> 00:00:48,420 to satisfy the RecyclerViewAdapter contract. 19 00:00:48,420 --> 00:00:51,240 Now I've mentioned before that an interface is a contract 20 00:00:51,240 --> 00:00:53,230 and if you implement an interface 21 00:00:53,230 --> 00:00:55,248 then you have to provide an implementation 22 00:00:55,248 --> 00:00:58,310 of all the methods that the interface defines. 23 00:00:58,310 --> 00:01:02,100 The same is true when you extend an abstract class, 24 00:01:02,100 --> 00:01:05,069 your class has to provide an implementation 25 00:01:05,069 --> 00:01:08,590 of all the methods defined in the abstract-based class 26 00:01:08,590 --> 00:01:09,670 that you're extending. 27 00:01:09,670 --> 00:01:10,503 So, what I'll do here, 28 00:01:10,503 --> 00:01:12,050 is I'll get Android Studio to generate 29 00:01:12,050 --> 00:01:13,760 the methods we need to implement. 30 00:01:13,760 --> 00:01:16,040 Just using Control + I and that's obviously 31 00:01:16,040 --> 00:01:18,120 with a cursor already inside the class bodies. 32 00:01:18,120 --> 00:01:19,720 You can see I've got. 33 00:01:19,720 --> 00:01:21,170 Now select all three. 34 00:01:21,170 --> 00:01:23,520 Just press Enter there to create them. 35 00:01:23,520 --> 00:01:26,570 Now in terms of these methods, 36 00:01:26,570 --> 00:01:29,110 I prefer to have the onBindViewHolder function 37 00:01:29,110 --> 00:01:32,800 appear immediately after the onCreateViewHolder. 38 00:01:32,800 --> 00:01:35,640 So, if your codes generated in a different order as mine is, 39 00:01:35,640 --> 00:01:37,250 just cut and paste to rearrange it. 40 00:01:37,250 --> 00:01:38,500 I'm going to do that now. 41 00:01:40,710 --> 00:01:43,023 Personal preference of where it should be. 42 00:01:44,030 --> 00:01:45,080 It's not an issue though, 43 00:01:45,080 --> 00:01:46,880 as far as the compile is concerned, 44 00:01:46,880 --> 00:01:48,190 but it makes it easier, 45 00:01:48,190 --> 00:01:51,012 if you want to compare your code to mine, ultimately. 46 00:01:51,012 --> 00:01:52,760 Also, I take this opportunity 47 00:01:52,760 --> 00:01:56,790 to change the parameter names for these first two functions. 48 00:01:56,790 --> 00:01:58,447 Android Studio sometimes just gives them the names, 49 00:01:58,447 --> 00:02:00,660 p0, p1, etc., 50 00:02:00,660 --> 00:02:01,493 which is done here, 51 00:02:01,493 --> 00:02:03,520 when that's not really very informative. 52 00:02:03,520 --> 00:02:05,620 Alright, starting off with on line 25. 53 00:02:05,620 --> 00:02:07,643 We'll change p0, that should be parent, 54 00:02:08,680 --> 00:02:10,240 for first argument. 55 00:02:10,240 --> 00:02:12,623 And the second one is the viewType. 56 00:02:15,234 --> 00:02:18,970 Alright, and then for the second method on line 29, 57 00:02:18,970 --> 00:02:22,250 we're going to go with holder, instead of p0 58 00:02:22,250 --> 00:02:23,480 for the argument name. 59 00:02:23,480 --> 00:02:25,880 And, for the second one, it's gonna be position. 60 00:02:27,127 --> 00:02:28,650 I think that's a bit more informative 61 00:02:28,650 --> 00:02:31,150 and makes more sense now reading. 62 00:02:31,150 --> 00:02:33,140 And with same as three methods before, 63 00:02:33,140 --> 00:02:36,440 onCreativeViewHolder is called by the RecyclerView 64 00:02:36,440 --> 00:02:38,570 when it needs a new view to display. 65 00:02:38,570 --> 00:02:40,330 The flicker browser app displayed 66 00:02:40,330 --> 00:02:42,782 the same details in each line in the RecyclerView 67 00:02:42,782 --> 00:02:44,970 and this app does the same. 68 00:02:44,970 --> 00:02:47,120 But the RecyclerView can be used to display 69 00:02:47,120 --> 00:02:48,790 different things of each row. 70 00:02:48,790 --> 00:02:50,220 You give it a valid view 71 00:02:50,220 --> 00:02:52,520 and it will display it at the correct position. 72 00:02:52,520 --> 00:02:55,140 And, that's why there's a viewType parameter, 73 00:02:55,140 --> 00:02:57,810 so your function can respond to the type that's requested 74 00:02:57,810 --> 00:03:00,840 and return different views, accordingly. 75 00:03:00,840 --> 00:03:03,010 Best example of that, think about ChatApp. 76 00:03:03,010 --> 00:03:05,110 The views for the incoming message 77 00:03:05,110 --> 00:03:07,370 may have the text to appear to the left, 78 00:03:07,370 --> 00:03:09,800 while the messages being sent from the device 79 00:03:09,800 --> 00:03:10,960 have them on the right. 80 00:03:10,960 --> 00:03:12,170 Now that's a bit simplified 81 00:03:12,170 --> 00:03:13,450 and you'd probably implement that 82 00:03:13,450 --> 00:03:16,900 by starting the widgets before sending the view back, 83 00:03:16,900 --> 00:03:20,420 but how about if an incoming message contained a file? 84 00:03:20,420 --> 00:03:22,500 You may have in return a different view 85 00:03:22,500 --> 00:03:25,530 that included an image view widget to display the picture. 86 00:03:25,530 --> 00:03:28,002 If the file type wasn't a recognised type of image, 87 00:03:28,002 --> 00:03:31,450 you can add a button to download the file instead. 88 00:03:31,450 --> 00:03:34,450 So, this involves implementing getArt and viewType, 89 00:03:34,450 --> 00:03:35,450 so that you can switch 90 00:03:35,450 --> 00:03:37,670 the type of view at any given position. 91 00:03:37,670 --> 00:03:39,870 But, we display in the same kind of data 92 00:03:39,870 --> 00:03:41,520 throughout the RecyclerView list, 93 00:03:41,520 --> 00:03:45,020 so we can safely ignore that viewType argument. 94 00:03:45,020 --> 00:03:46,110 And we're not gonna be displaying 95 00:03:46,110 --> 00:03:47,870 different types of views in our list, 96 00:03:47,870 --> 00:03:49,340 but if you want to do that, 97 00:03:49,340 --> 00:03:51,670 then you know now how to search for something like 98 00:03:51,670 --> 00:03:54,977 RecyclerView, getArt, and viewType. 99 00:03:54,977 --> 00:03:57,070 Alright, so our onCreateViewHolder 100 00:03:57,070 --> 00:03:59,030 function will just inflate a view 101 00:03:59,030 --> 00:04:01,910 from the task_list_items layout 102 00:04:01,910 --> 00:04:04,810 that we created earlier and then return that view. 103 00:04:04,810 --> 00:04:06,090 So, let's write some code for that. 104 00:04:06,090 --> 00:04:07,440 We're gonna delete the TODO 105 00:04:10,084 --> 00:04:11,700 and we'll start with 106 00:04:11,700 --> 00:04:13,790 a Log.d, 107 00:04:13,790 --> 00:04:17,880 in parentheses, TAG and double quote, 108 00:04:17,880 --> 00:04:18,829 onCreateViewHolder, 109 00:04:20,055 --> 00:04:21,720 because that's the functionary, 110 00:04:21,720 --> 00:04:22,930 and we'll put new view requested, 111 00:04:22,930 --> 00:04:24,430 so we can see that in our log. 112 00:04:27,970 --> 00:04:30,920 Alright, so the code next line is val view =, 113 00:04:30,920 --> 00:04:32,240 it's gonna be LayoutInflater 114 00:04:35,577 --> 00:04:37,510 It's gonna be .from, 115 00:04:37,510 --> 00:04:41,133 in parentheses; parent.context, 116 00:04:42,250 --> 00:04:45,140 closing parenthesis, .inflate, 117 00:04:45,140 --> 00:04:46,743 and parenthesis again, 118 00:04:46,743 --> 00:04:51,743 R.layout.task_list_items, 119 00:04:51,850 --> 00:04:53,830 and then ,parent, false 120 00:04:53,830 --> 00:04:56,510 and then we got a closing raw parenthesis on the end there, 121 00:04:56,510 --> 00:04:57,910 which we can see down there. 122 00:04:58,811 --> 00:05:01,280 Alright, then the last line we're going to return 123 00:05:01,280 --> 00:05:02,950 a new TaskViewHolder object. 124 00:05:02,950 --> 00:05:04,123 The TaskViewHolder, 125 00:05:05,314 --> 00:05:07,630 in parenthesis will be view that we created 126 00:05:07,630 --> 00:05:09,040 on the previous line. 127 00:05:09,040 --> 00:05:11,550 So, that's onCreateViewHolder 128 00:05:11,550 --> 00:05:12,930 and again that's just inflating a view 129 00:05:12,930 --> 00:05:15,810 from the task_list_items layout, 130 00:05:15,810 --> 00:05:17,670 that we created earlier, 131 00:05:17,670 --> 00:05:18,760 and after inflating the view, 132 00:05:18,760 --> 00:05:20,130 it returns the view. 133 00:05:20,130 --> 00:05:23,320 Alright so next is our onBindViewHolder function 134 00:05:23,320 --> 00:05:25,980 and that's called when the RecyclerView wants new data 135 00:05:25,980 --> 00:05:28,030 to be displayed and is providing 136 00:05:28,030 --> 00:05:30,180 an existing view to be re-eused. 137 00:05:30,180 --> 00:05:31,750 So this is where we put our data 138 00:05:31,750 --> 00:05:33,830 into the individual widgets. 139 00:05:33,830 --> 00:05:34,920 In case it's not obvious, 140 00:05:34,920 --> 00:05:38,230 a call to onCreateViewHolder will be followed 141 00:05:38,230 --> 00:05:39,660 by a call to onBindViewHolder. 142 00:05:39,660 --> 00:05:43,230 The RecyclerView first requests a new view, 143 00:05:43,230 --> 00:05:46,440 then sends the view back so that we can put data into it. 144 00:05:46,440 --> 00:05:47,710 So let's implement that. 145 00:05:47,710 --> 00:05:49,303 So, I'm going to delete the TODO. 146 00:05:51,423 --> 00:05:52,390 And we'll start with a log. 147 00:05:52,390 --> 00:05:55,160 So I have log.d, parentheses, 148 00:05:55,160 --> 00:05:57,123 TAG, "onBindViewHolder 149 00:06:01,637 --> 00:06:05,580 :starts" logging message. 150 00:06:05,580 --> 00:06:06,730 You're going to avoid some problems 151 00:06:06,730 --> 00:06:07,740 with the smart cast again. 152 00:06:07,740 --> 00:06:10,360 So, val cursor = cursor 153 00:06:11,802 --> 00:06:13,180 now just to make it clear, 154 00:06:13,180 --> 00:06:15,300 we're going to put that in a comment 155 00:06:15,300 --> 00:06:17,647 for some regular code in the future. 156 00:06:19,630 --> 00:06:21,810 Of course we talked about that previously. 157 00:06:21,810 --> 00:06:23,150 Alright, first in length then we want 158 00:06:23,150 --> 00:06:24,750 to check to see whether the cursor is null, 159 00:06:24,750 --> 00:06:27,530 or it has a count of zero. 160 00:06:27,530 --> 00:06:32,410 Now record if, parenthesis, cursor = null, 161 00:06:32,410 --> 00:06:35,020 or cursor., 162 00:06:35,020 --> 00:06:36,670 or cursor.count. 163 00:06:36,670 --> 00:06:38,970 I'm trying to use the word period instead of dot. 164 00:06:38,970 --> 00:06:42,230 For dots very normal for me to use in Australia, 165 00:06:42,230 --> 00:06:44,030 but it's not something that's used over-seas, 166 00:06:44,030 --> 00:06:45,740 so I'm trying to use the word period 167 00:06:45,740 --> 00:06:46,880 on a consistent basis, 168 00:06:46,880 --> 00:06:48,260 so bear with me there, 169 00:06:48,260 --> 00:06:50,427 so that everyone knows what I'm talking about. 170 00:06:50,427 --> 00:06:51,290 = 0 171 00:06:52,670 --> 00:06:55,130 Then we're just going to log a message. 172 00:06:55,130 --> 00:06:55,963 Basically what we're doing, 173 00:06:55,963 --> 00:06:57,530 is we're providing some instructions, 174 00:06:57,530 --> 00:06:59,530 if this is the first entry. 175 00:06:59,530 --> 00:07:03,083 So Log.d parentheses TAG, 176 00:07:04,160 --> 00:07:05,330 then our message will be 177 00:07:05,330 --> 00:07:06,180 onBindViewHolder: 178 00:07:09,909 --> 00:07:11,210 providing instructions, 179 00:07:11,210 --> 00:07:13,890 so again we know what's going on in the log. 180 00:07:13,890 --> 00:07:17,060 Then we're gonna set the T line name field properly 181 00:07:19,040 --> 00:07:19,873 to instructions. 182 00:07:19,873 --> 00:07:21,253 So holder.tli_name. 183 00:07:23,985 --> 00:07:26,760 setText parentheses, 184 00:07:26,760 --> 00:07:28,310 and it's gonna be Instructions, 185 00:07:29,920 --> 00:07:30,823 in double quotes. 186 00:07:31,720 --> 00:07:34,740 Android Studio should've added the synthetic import of 187 00:07:34,740 --> 00:07:38,977 kotlinx.android.synthetic.main.task_list_items.* 188 00:07:41,996 --> 00:07:44,120 And the one I'm talking about is the one there on line ten. 189 00:07:44,120 --> 00:07:45,640 So it's done that for us automatically. 190 00:07:45,640 --> 00:07:46,473 What we've done there, 191 00:07:46,473 --> 00:07:49,240 is enabled the use of synthetic imports 192 00:07:49,240 --> 00:07:51,680 in our ViewHolder class by implementing 193 00:07:51,680 --> 00:07:54,080 the LayoutContainer interface that we did last video, 194 00:07:54,080 --> 00:07:55,670 and I think that's pretty cool. 195 00:07:55,670 --> 00:07:56,640 Alright, with that said, 196 00:07:56,640 --> 00:07:58,100 let's now finish the function, 197 00:07:58,100 --> 00:07:59,790 so go back down to where we were. 198 00:07:59,790 --> 00:08:02,190 Now onBindViewHolder. 199 00:08:02,190 --> 00:08:04,720 We're testing for no records there. 200 00:08:04,720 --> 00:08:05,553 What we need to do, 201 00:08:05,553 --> 00:08:06,390 we'll set instructions, 202 00:08:06,390 --> 00:08:08,770 we need to update the other fields as well. 203 00:08:08,770 --> 00:08:11,123 So it's gonna be holder.tli_description 204 00:08:15,230 --> 00:08:17,817 and we set that to an empty string. 205 00:08:17,817 --> 00:08:21,020 .setText parenthesis, two double quotes, 206 00:08:21,020 --> 00:08:24,790 you wanna hide the edit and delete properly, 207 00:08:24,790 --> 00:08:25,957 so holder.tli 208 00:08:27,046 --> 00:08:29,105 _edit 209 00:08:29,105 --> 00:08:30,963 .visibility = 210 00:08:32,130 --> 00:08:34,393 and we'll set that to View.GONE. 211 00:08:35,419 --> 00:08:36,738 We'll do the same with delete. 212 00:08:36,738 --> 00:08:40,534 So holder.tli_delete 213 00:08:40,534 --> 00:08:43,100 .visibilty = 214 00:08:43,100 --> 00:08:45,313 View.GONE. 215 00:08:46,600 --> 00:08:48,310 Alright, so if the cursor was null, 216 00:08:48,310 --> 00:08:49,540 there's no records. 217 00:08:49,540 --> 00:08:51,040 We now need to add an else clause, 218 00:08:51,040 --> 00:08:53,970 which is obviously gonna be taken up, 219 00:08:53,970 --> 00:08:55,010 if that's not the case, 220 00:08:55,010 --> 00:08:56,067 in other words, we have got some dollars. 221 00:08:56,067 --> 00:08:59,380 Now the else will be wiping the code block. 222 00:08:59,380 --> 00:09:00,590 First we wanna try and see 223 00:09:00,590 --> 00:09:02,610 whether we can move to another position, 224 00:09:02,610 --> 00:09:06,310 so we do that by typing if, parenthesis, not, 225 00:09:06,310 --> 00:09:07,843 cursor.moveToPosition, 226 00:09:09,960 --> 00:09:12,630 in parenthesis, position, 227 00:09:12,630 --> 00:09:14,318 closing your right parentheses. 228 00:09:14,318 --> 00:09:15,820 I'm not gonna code block, 229 00:09:15,820 --> 00:09:17,360 and if we can't move to that position, 230 00:09:17,360 --> 00:09:19,120 we're gonna throw an illegal state exception. 231 00:09:19,120 --> 00:09:21,673 So throw IllegalStateException 232 00:09:22,964 --> 00:09:24,163 and in parentheses, 233 00:09:25,590 --> 00:09:26,800 we'll put a message to that effect, 234 00:09:26,800 --> 00:09:29,910 Couldn't move cursor to position 235 00:09:30,947 --> 00:09:31,780 $position. 236 00:09:33,490 --> 00:09:35,580 Obviously we had an error trying to do that. 237 00:09:35,580 --> 00:09:37,570 Alright, that's handled that scenario. 238 00:09:37,570 --> 00:09:39,600 Now assuming that we got past that 239 00:09:39,600 --> 00:09:41,400 and haven't thrown an error, 240 00:09:41,400 --> 00:09:42,840 We're gonna create a task object from 241 00:09:42,840 --> 00:09:44,460 the data that's currently in the cursor, 242 00:09:44,460 --> 00:09:47,180 so we'll put a comment to that effect. 243 00:09:47,180 --> 00:09:48,470 Create a Task object 244 00:09:50,510 --> 00:09:52,360 from the data in the cursor. 245 00:09:55,607 --> 00:10:00,607 Now we'll start by typing val task = Task parentheses. 246 00:10:02,030 --> 00:10:04,037 Now you're gonna type cursor.getString, 247 00:10:06,545 --> 00:10:07,550 now we've got parentheses there, 248 00:10:07,550 --> 00:10:09,630 then I'll type cursor.getColumnIndex 249 00:10:11,580 --> 00:10:13,410 and parenthesis again 250 00:10:13,410 --> 00:10:16,973 and then TasksContract.Columns. 251 00:10:18,424 --> 00:10:19,970 TASK_NAME, 252 00:10:19,970 --> 00:10:22,470 first field, comma, 253 00:10:22,470 --> 00:10:25,090 and then the next one will be cursor.getString. 254 00:10:25,090 --> 00:10:26,860 Let's save a bit of time here 255 00:10:26,860 --> 00:10:30,413 and let's just take a copy of these next two. 256 00:10:32,130 --> 00:10:34,530 So, on line 53 it's 257 00:10:34,530 --> 00:10:35,820 cursor.getString, 258 00:10:35,820 --> 00:10:38,630 then cursor.getColumnIndex, 259 00:10:38,630 --> 00:10:40,440 and this time it's gonna be basically 260 00:10:40,440 --> 00:10:43,550 task description instead of task name, 261 00:10:43,550 --> 00:10:46,900 and the last one is going to be task sort order. 262 00:10:46,900 --> 00:10:49,350 So task sort order. 263 00:10:49,350 --> 00:10:51,430 The last one isn't gonna have a comma, 264 00:10:51,430 --> 00:10:52,611 'cause we're closing off the line, 265 00:10:52,611 --> 00:10:55,140 so we're gonna have a third raw parentheses, 266 00:10:55,140 --> 00:10:56,377 and of course the third one is 267 00:10:56,377 --> 00:10:58,830 the string sort order is in Int. 268 00:10:58,830 --> 00:10:59,813 So .getInt. 269 00:11:01,944 --> 00:11:04,053 Alright, so that fixes up that error. 270 00:11:05,100 --> 00:11:06,830 Alright so, now that we've done that, 271 00:11:06,830 --> 00:11:09,460 We'll put another comment down here 272 00:11:09,460 --> 00:11:10,880 just to remind us about the ID, 273 00:11:10,880 --> 00:11:15,880 so, remember that the ID isn't set in the constructor. 274 00:11:18,290 --> 00:11:19,170 We need to set that manually. 275 00:11:19,170 --> 00:11:23,233 Task.id = cursor. 276 00:11:23,233 --> 00:11:25,759 And we want to do getLong, 277 00:11:25,759 --> 00:11:27,934 parentheses, and it's going to be 278 00:11:27,934 --> 00:11:31,902 cursor.getColumnIndex, 279 00:11:31,902 --> 00:11:33,016 in parantheses again, 280 00:11:33,016 --> 00:11:37,933 it's going to be TasksContract.Columns.ID, 281 00:11:39,370 --> 00:11:41,306 and closing in raw parentheses. 282 00:11:41,306 --> 00:11:43,600 The last thing we need to do is, 283 00:11:43,600 --> 00:11:46,990 use the holder object to update our field. 284 00:11:46,990 --> 00:11:48,750 So, holder.tli_name.text. 285 00:11:53,310 --> 00:11:54,900 Like I said, our fields, 286 00:11:54,900 --> 00:11:57,140 but of course it's our text views we're updating here. 287 00:11:57,140 --> 00:12:00,083 Set that = task.name. 288 00:12:01,370 --> 00:12:03,507 That's the first one, then we got three more to do. 289 00:12:03,507 --> 00:12:07,710 Tli_description we'll set that = 290 00:12:07,710 --> 00:12:10,030 task.description. 291 00:12:10,030 --> 00:12:11,910 Then for our edit and delete, 292 00:12:11,910 --> 00:12:13,373 holder.tli_edit, 293 00:12:16,895 --> 00:12:20,895 .visisbilty, we'll set that = View.VISIBLE. 294 00:12:23,028 --> 00:12:24,346 Now we'll do the same for delete. 295 00:12:24,346 --> 00:12:27,929 Holder.tli_delete.visibilty 296 00:12:29,657 --> 00:12:32,370 = View.VISIBLE. 297 00:12:32,370 --> 00:12:35,930 I think I've got an extra raw parentheses there, 298 00:12:35,930 --> 00:12:37,570 which I will delete. 299 00:12:37,570 --> 00:12:39,040 And I missed something in there, 300 00:12:39,040 --> 00:12:40,830 it should have been .text, 301 00:12:40,830 --> 00:12:43,980 so tli_description.text 302 00:12:44,964 --> 00:12:48,000 = task_description, that fixes that. 303 00:12:48,000 --> 00:12:49,920 Alright now, the description text, 304 00:12:49,920 --> 00:12:51,140 this is for the instructions, 305 00:12:51,140 --> 00:12:53,110 which we've got currently on line 42, 306 00:12:53,110 --> 00:12:54,070 is quite long. 307 00:12:54,070 --> 00:12:56,580 It provides basic instructions to the user 308 00:12:56,580 --> 00:12:57,680 when the app first loads up. 309 00:12:57,680 --> 00:13:01,150 Obviously we've got the name defined as instructions, 310 00:13:01,150 --> 00:13:03,715 but the text is an empty string at the moment. 311 00:13:03,715 --> 00:13:04,770 Now I'm sure you don't want 312 00:13:04,770 --> 00:13:06,310 to see me typing in a load of text, 313 00:13:06,310 --> 00:13:07,143 so what I'm going to do, 314 00:13:07,143 --> 00:13:09,610 is paste in the holder. description line 315 00:13:09,610 --> 00:13:11,010 with the text we want. 316 00:13:11,010 --> 00:13:12,490 You can pause the video to catch up, 317 00:13:12,490 --> 00:13:13,323 and what I'll also do, 318 00:13:13,323 --> 00:13:16,847 is I'll put it in the resources section as a text file, 319 00:13:16,847 --> 00:13:18,710 you can grab it from there and copy and paste 320 00:13:18,710 --> 00:13:19,820 if you'd prefer to do that. 321 00:13:19,820 --> 00:13:20,653 So let's do that. 322 00:13:20,653 --> 00:13:22,950 I'm gonna change line 42 323 00:13:24,880 --> 00:13:27,070 and paste in the description. 324 00:13:27,070 --> 00:13:28,200 Okay. 325 00:13:28,200 --> 00:13:30,030 Once again, this is all very similar 326 00:13:30,030 --> 00:13:32,010 to what we did in the flicker browser app. 327 00:13:32,010 --> 00:13:34,450 Instead of retrieving the data from a list, 328 00:13:34,450 --> 00:13:36,420 we get data from a cursor and use it 329 00:13:36,420 --> 00:13:38,600 to create a new task object. 330 00:13:38,600 --> 00:13:40,060 If the cursor is null, 331 00:13:40,060 --> 00:13:42,300 and we can see some of the code there, 332 00:13:42,300 --> 00:13:43,530 or it contains no rows, 333 00:13:43,530 --> 00:13:46,025 then we put some instructions in the description text view, 334 00:13:46,025 --> 00:13:47,590 and the heading in the name. 335 00:13:47,590 --> 00:13:52,510 We've seen \n used before to insert a long break in text. 336 00:13:52,510 --> 00:13:54,670 We just formulate a text there for description 337 00:13:54,670 --> 00:13:57,130 so that it looks better when it's displayed. 338 00:13:57,130 --> 00:13:59,850 We also set the buttons to be invisible; 339 00:13:59,850 --> 00:14:01,750 lines 47 and 48. 340 00:14:01,750 --> 00:14:04,050 There's a view.invisible view value defined, 341 00:14:04,050 --> 00:14:06,360 but I've used View.GONE instead. 342 00:14:06,360 --> 00:14:08,220 It's very similar to invisible, 343 00:14:08,220 --> 00:14:11,292 but the widget also takes up no space in the layout. 344 00:14:11,292 --> 00:14:13,700 The other layout is a description text view widget 345 00:14:13,700 --> 00:14:15,980 to fill the entire width of the display. 346 00:14:15,980 --> 00:14:16,930 Once the code's running, 347 00:14:16,930 --> 00:14:19,710 try changing those two settings to view.invisible 348 00:14:19,710 --> 00:14:21,500 to see the difference that it makes. 349 00:14:21,500 --> 00:14:23,210 As long as we have a valid cursor 350 00:14:23,210 --> 00:14:26,710 that contains at least one row for code in the else block, 351 00:14:26,710 --> 00:14:28,310 starting on line 50, 352 00:14:28,310 --> 00:14:30,440 moves to a correct position in the cursor. 353 00:14:30,440 --> 00:14:32,290 And obviously, that's assuming that we don't get 354 00:14:32,290 --> 00:14:34,360 an error trying to move to that position. 355 00:14:34,360 --> 00:14:36,880 After that, we're retrieving the values from the cursor 356 00:14:36,880 --> 00:14:39,640 and using them to set the text in the TextView widgets. 357 00:14:39,640 --> 00:14:42,220 We can also make the buttons visible again 358 00:14:42,220 --> 00:14:47,120 down there towards the bottom on lines 64 and 65. 359 00:14:47,120 --> 00:14:49,410 We're gonna add onClick list this to the buttons. 360 00:14:49,410 --> 00:14:50,740 So what I'll do there for those two, 361 00:14:50,740 --> 00:14:53,563 is we'll make a note to that effect, as a TODO. 362 00:14:54,560 --> 00:14:56,500 So I'm gonna put a TODO there 363 00:14:56,500 --> 00:14:59,613 to remind us to add an onClick. 364 00:15:01,988 --> 00:15:03,310 It's always a good idea to that, 365 00:15:03,310 --> 00:15:05,120 'cause of course you can see those TODOs 366 00:15:05,120 --> 00:15:07,200 if you want to at a later stage. 367 00:15:07,200 --> 00:15:09,090 Pretty handy, you can see that Android Studio 368 00:15:09,090 --> 00:15:10,750 is highlighting them in the blue. 369 00:15:10,750 --> 00:15:11,660 If you want to see your TODOs, 370 00:15:11,660 --> 00:15:12,650 I think I've shown you this before, 371 00:15:12,650 --> 00:15:15,713 click on TODO and you get a list of all the TODOs. 372 00:15:17,476 --> 00:15:19,400 And there's one there from us that we've used previously, 373 00:15:19,400 --> 00:15:20,590 and also this one here, 374 00:15:20,590 --> 00:15:23,120 CursorRecyclerViewAdapter that we're working on now. 375 00:15:23,120 --> 00:15:25,230 Very handy to have that capability. 376 00:15:25,230 --> 00:15:27,440 Alright, I'll close that now. 377 00:15:27,440 --> 00:15:29,160 Basically, a useful way to keep track of code 378 00:15:29,160 --> 00:15:30,660 that you want to come back to, 379 00:15:30,660 --> 00:15:32,560 and it can help to make sure that you don't forget. 380 00:15:32,560 --> 00:15:33,700 We're also getting a warning now, 381 00:15:33,700 --> 00:15:35,210 on the right hand margin. 382 00:15:35,210 --> 00:15:36,910 It's three, in fact, but the first one, 383 00:15:36,910 --> 00:15:39,840 we come back here and look at the first one. 384 00:15:39,840 --> 00:15:41,450 So ignore this first one about removing 385 00:15:41,450 --> 00:15:42,300 the empty class body, 386 00:15:42,300 --> 00:15:43,610 because I talked about that, 387 00:15:43,610 --> 00:15:44,540 but this one here 388 00:15:44,540 --> 00:15:48,290 is telling us that currently CursorRecyclerViewAdapter, 389 00:15:48,290 --> 00:15:50,860 the class itself isn't being used at the moment. 390 00:15:50,860 --> 00:15:53,080 More to the point, is these other ones down here, 391 00:15:53,080 --> 00:15:54,570 we need to deal with these, 392 00:15:54,570 --> 00:15:57,000 which is a warning about hard-coded text, 393 00:15:57,000 --> 00:15:58,320 and obviously that's because we're using 394 00:15:58,320 --> 00:16:02,500 a string literal in the setText function call. 395 00:16:02,500 --> 00:16:03,880 We can get Android Studio to help 396 00:16:03,880 --> 00:16:05,690 in creating a string resources for us, 397 00:16:05,690 --> 00:16:08,134 which is slightly easier than typing the XML into 398 00:16:08,134 --> 00:16:10,450 the string's XML file, 399 00:16:10,450 --> 00:16:12,660 which is of course Res/values file. 400 00:16:12,660 --> 00:16:14,300 I'll do that in the next video, 401 00:16:14,300 --> 00:16:15,660 because it's a bit fiddlier 402 00:16:15,660 --> 00:16:16,850 than you might expect. 403 00:16:16,850 --> 00:16:18,203 See you in the next video.