 In this video, we are going to create a recycler view to show our books inside our all books activity. But before that, I'm going to create a model for my book. So in my package, I can say new Java class. Let's name it book. For this book item, I'm going to have an ID first of all, let's say private int ID. This ID is going to be unique for every book. And later on, we will identify our books by this ID. After that, we need a name, private string name. Also, we need the author, private string author. I'm also going to define an integer for the number of pages. So let's say private int pages, a string maybe for the image URL. Also, I'm going to define two more fields, one is called short description and the other one is called long description. We are going to show different versions of this description in different places of our application. Okay, let's quickly create a constructor. I'm using alt plus insert. Let's select all of our fields. And also down below this constructor, let's quickly create getters and setters. I'm also going to create a two string method. I believe it will be useful. plus insert, this two string, let's select all of the fields. Okay, this is our simple model. In Java, sometimes we name these kind of classes as pojos. Pojo stands for plain old Java object in which the class has some fields and also beside that the constructor and some getters and setters method. Okay, let's move on and let's implement the recycler view dependency into our project. So if I open the layout file, let's go to the layout folder inside this activity all books that XML if we switch to design view, you can see that we have this recycler view option in here. And we can drag that in our layout. Let's switch to a split view. And let's change the widths and height to match parent. So inside this activity, we are only going to have a recycler view. Let's also give it an ID and let's initialize it in our Java file. Let's say box recycler view. Let's open all box activity that's Java class. And let's initialize our recycler view private recycler view. Let's name it box recycler view. And down in here inside the uncreated method, let's say box recycler view is equal to find you by ID are that ID dot box recycler view. After that, it's time to create the adapter for this recycler view. Let's quickly do that. So in my package, I can right click, let's say new Java class, I'm going to name this class book recycler view adapter. First of all, let's create our viewholder class. Let's say public class viewholder, I'm going to name it, let's say extend recycler view dot viewholder this class. After that, we need a constructor. We can do that by pressing alt plus insert and selecting constructor. Before going further, we need to create a layout file for every item in our recycler view. So in our layout folder, let's say new layout resource file. I'm going to name this list item book. Let's minimize this project pane and let's switch to a split view. First of all, I'm going to change this constraint layer to a card view. So this whole layout file is going to be a card view. And in here I'm going to use the material card view. I think the style is a little bit different. Also, let's change the widths and height to wrap content. Let's also give an ID to this card view. Later on, we are going to need that. Let's name it parent. Inside our card view, first of all, I'm going to create a relative layout. Let's say mesh parent and mesh parent for the widths and height. And inside this relative layout, let's have some items. For example, I'm going to define an image view. For the widths, I believe 130 would be fine. 130 dp. Also, for the height, I'm going to say 200 dp. That seems a little bit large. Let's decrease that to 150. Let's give it an ID. I'm going to name it IMG book. Let's also have a placeholder, let's say source. And let's pass our IC launcher icon. After this image view, let's quickly define a text view for the name of our book. I'm going to say wrap content and wrap content for the text. Let's say book name. Let's change the style of this text by same text style. I'm going to pass bold in here. Beside that, let's increase the size, text size, I believe 16 SP would be fine. Let's move it to below our image view. Let's say layout below our ID, IMG book. Beside that, I'm going to center it horizontally. So let's say center horizontal true. I think it's better to have a margin top, let's say margin top 5 dp or 7 dp maybe. That's almost it for our layout file in here. I'm just going to add two more attributes. First of all, let's say card corner. This one card corner radius. Let's pass 7 dp. Beside that, let's add a card elevation. Once again, I'm going to say 7 dp. In here, you can see that we are only showing the image view and also the book name. But if you remember when we have created our book model, we had more information. We are going to show those information in two different places in our application. First of all, by clicking on every book, we are going to navigate the user to another activity. And beside that, we are going to show lesser information when the user clicks on some arrow button on our card view. To be precise, later on, we are going to create an expandable card view. It means that for the first time that the user sees this activity, we are going to show only the image and the book name. But if the user wants to see some more information here, she can click on some arrow button in here and expand our card view. Later on, we will create that. Also, I forgot to add a margin in here. Let's quickly do that. Let's say margin. And I believe 5 dp would be fine. Okay, now that we have created our layout file, we can initialize our UI elements inside this viewholder class. For that, in here, I'm going to say private card view for the parent. Let's name it parent. Inside that, let's say private image view. Once again, I'm going to name it IMG book. And also let's say private text view. Let's say txt name. I believe we didn't define an ID for this text view. Let's quickly do that. So in here for this text view, let's pass an ID. Let's say txt book name. Okay, back in our adapter class. Inside the constructor of this viewholder class. After the super statement, let's initialize our UI elements. We have done this before. We can say parent is equal to item view dot find view by ID. Let's pass our ID dot parent. Similarly, for the others, after creating this inner class, we can extend the recycler view class in here. And we can pass this viewholder as the data type of our adapter. So I can say recycler view dot adapter. And I can pass my viewholder class. Make sure to import the one that comes from your package or dot make good dot my library dot book recycler view adapter. You know that in here right now, we need three methods, let's press Ctrl plus five. And let's import our methods. Before doing anything inside these methods, first of all, above in here, I'm going to define an array list. Let's say private array list of different books. Let's name this array list books is equal to neo array list. So this array list is going to be the list of all of the books that we are going to show in our activity. Besides these books, I'm also going to need a context because if you remember when we are going to use Glide in our project, Glide library needed the context to show the image. So let's say private context. Let's name it m context. After that, let's create our constructor. In here, I'm going to receive only the context for the books array list, we are going to create a set their method. Let's create that method down in here. By pressing alt plus insert once again, let's select set there. And let's create a set their method for our books are released. You know that when you set your books this way, you also need to add a method in here. And that method is notified data set changed. We are adding this method because we are going to refresh the data in our recycler view. Okay, let's move on from this part. And let's start working on this get item count method. But before that, I'm going to minimize this view holder class. This get item count method, as I said before, is just returning the size of items or the size of list in our recycler view. So in here, I can save books that size. Nothing special is going to happen inside this get item count. Inside this uncreated view holder method, we need to create an instance of our view holder, and we need to return that. Probably all the times the code inside this uncreated view holder method is going to be the same in all cases. So you can safely copy and paste what I'm writing in here. So I can say view, let's name it view is equal to layout inflator, if you remember, let's say that from we need to pass a context in here, and we can pass the context by using this view group. Let's say parent dot get context. After that, we can call the dot inflate method, in which first of all, we need to pass our layout, I can say r dot layout dot list item book. After that, we need the view group itself in order to attach our layout file, this list item book to its parent. And after that, I'm going to pass false in order to avoid redundancy. After creating this view objects, you can create your view holder class. Let's say view holder, let's name it holder is equal to new view holder. And let's pass our view object. After that, I can return my holder. Also, this method in here can be simplified. Right now, you can see that this local variable is redundant. It means that you can directly return it instead of creating an instance of that holder class. So in here, what I can say is that I can say return new view holder, and I can pass my view. Once again, in most cases, this is exactly the code that you need to put inside this create view holder method. After that, down below inside this on bind view holder method. First of all, I'm going to log something indicating that this method has been called. In order to add a log above in here, first of all, I need to add a constant. After that, inside on bind view holder method, I'm going to say log D. Let's just say called. First of all, let's set the name for our book. I'm going to say holder.txt name. That's a text. Let's say books dot get, let's pass position. Let's say dot get me. After that, we need to show our image in which for that, we need the glide library. For that, I'm going to search the internet for glide dependency. The first link, which is a GitHub link is probably our needed link. Down in here, we should see the dependencies. First of all, let's add these two dependencies in our project inside gradle or scripts, inside this build dot gradle module app. Inside these dependencies, I can paste them. Let's also check that if we have this Maven central and Google repositories in our build dot gradle project one. It seems like we need to add the Maven repositories. Let's copy it from here. Maven central. And let's paste it down in here. Okay, let's sync our project. Okay, it seems like we have added the glide dependency successfully. Let's switch back to our adapter class. And inside this on bind view holder method, I'm going to say glide dot with here, we need our context, which was named m context. After that, let's say as bitmap dot load, we need the image URL in here, which I'm going to say books dot yet, let's pass our position. Let's say dot get image URL. After that, we need our image view, let's say that into our holder dot IMG book. Okay, this way, we can show the name and image of our book. I'm also going to set an on click listener for the card view parent. For the time being, by clicking on this card view, we are going to show a toast message. But later on, we are going to create a book activity and we are going to navigate the user to that activity. So for now, let's say holder dot parent dot set on click listener. That's a new on click listener. And let's show our toast message. Let's receive the name of our book. I'm going to say books dot get, let's pass our position dot get name plus selected. Okay, I believe that's all we need for now inside this book recycler view adapter later on, we are going to change this a lot. But for now, let's initialize it inside our all box activity. And let's set it as the adapter for this books recycler view. I'm going to define the adapter above in here as a member variable, so that we can have access to this method inside different methods. I think we are going to need that. Let's say private books recycler view adapter. Let's name it adapter. Down in here before initializing our recycler view adapter, I'm going to say adapter is equal to new books recycler view adapter. And let's pass our context once again, because we are inside an activity, we can pass this. After that, I'm going to set this adapter as the adapter of my recycler view. Let's say books recycler view dot set adapter. Let's pass our adapter. Also for the layout manager, I'm going to pass a grid layout manager. Let's say books recycler view dot set layout manager new grid layout manager this one. First of all, we need the context. Let's pass this after that we need the number of columns, which I'm going to say to after setting the adapter, we need to set the data. I mean the box array list. For the time being for testing purposes, let's just create a dummy array list. And let's pass it to this adapter. Let's say array list of different books. Let's name it books is equal to new array list. After that, let's say books dot add. And let's add a book. Let's say new book. For the idea of this book, I'm going to say one for the name, let's say, one q 84. For the author, let's say, how you can mark on me. After that, let's enter the number of pages. I believe it's 1350 pages. Let's quickly copy some image URL. Let's search for one q 84. And I think this one is good. Let's paste it in here. Just make sure that your images and with that jpeg or that png. Let's go to the next line. Let's see what else do we need? We need a short description and also a long description. For the short description, I'm going to say a work of Madeline Berners. I believe it's what the time magazine said about this book. For the long description, I'm just going to pass long description because we are not going to show that yet. Okay, after adding this book, I'm going to say adapter dot set books. Let's pass our books array list. Before testing the application, let's quickly add the internet permission because we are going to load the images from internet. We need that permission in our manifest file. Above the application tag, I can say users permission, and I can pass internet permission. Okay, let's test our application. And let's see if we can see this book in our activity. Let's click on this see all books button. As you can see, we are getting a card view for our book, but we are not seeing the image. If you remember, I mentioned this problem in previous videos. The reason that we are not seeing this image is because we have changed our manifest file. We have added the permission and because we have changed our manifest, we need to uninstall the application and install it once again. We will do that in a minute. But before that, you can see that we have this ugly background in here. I'm going to get rid of that. And beside that, I'm going to add a padding for my recycler view. Right now this card view is two plus to the edges of our screen. Let's quickly fix those issues. So inside our activity all books layout file. First of all, let's delete this background color. After that, in our recycler view item, I'm going to add a margin. Similarly, you can add the padding on your constraint layout. I'm just going to add the margin in my recycler the element. Let's pass 15. I believe that's good. Okay, before testing the application, I'm going to uninstall it from the device. So if we go to our settings in here, in the apps and notification, we can see this my library application, let's uninstall it. And let's run our application once again. This time, if we click on this see all books button. After a time, we should see our image. It takes some time to load the image. But after all, we can see that. Let's also check the on click listener on our card view. So if we click on our card view, you can see that we are seeing this post message, which seems to be working fine. Okay, I think that's enough for this video. In the next video, we are going to work on that expandable card view that I was talking about. So basically, right now, we are only seeing the name and image of this book. In the next video, we are going to add a little arrow button in here, in which by clicking on that, the user can see more details about our book. Just before I finish off this video, once again, I'm going to say that if for any reason you need to check the source code, I will upload the source code at the links that you can see on the screen at macro.org. Feel free to check that if you need. And also I would love to hear your feedback on the code that I just wrote. Okay, see you in the next video. In this video, we are going to work on expandable card view. That means that we are going to show this simple card view plus an arrow button in here an arrow icon, in which if the user clicks on this arrow, we are going to expand our card view and we are going to show some more information. For example, in this case, we are going to show the name of the author of this book, plus we are going to show the description the short description of this book. In this video, we are going to see how we can implement that. But I need to say that this way of implementing an expandable card view inside our recycler view is not going to work with our grid layout manager. It works perfect with the linear layout manager. But for grid layout manager, you need some more information. We will talk about how to implement an expandable card view in grid layout manager later on in the course. So because of that first of all inside my all box activity, I'm going to change the layout manager for my recycler view to a linear layout manager. And also I'm going to increase the size of this card view. So let's switch to all box activity. This one. And down in here, you can see that we are using a grid layout manager. Let's quickly change that to linear layout manager. We need a context which I'm going to pass this. Let's close this file for now, we will be coming back to this file. And let's switch to a split view. And let's write the expandable view for this card view. So here is what we are going to do. We are going to create another relative layout down below this one that we already have. And we are going to change its visibility to gone later on in the code inside the recycler view adapter, when the user clicks on our arrow button, we are going to change the visibility of our relative layout to visible. Plus we will add some animation for adding another relative layout in here, I'm going to add one above in here as a single child of this card view. And I'm going to put this relative layout that we currently have inside that. So let's say relative layout for its widths, I'm going to say 200 dp. And for the height, I'm going to say wrap content. Also I'm going to change the size of this image view to 200 dp. If you remember, I said that because we are no longer using a grid layout manager, I'm going to change the size of this card view. So let's say 200 dp. And for the height, let's say 220, I believe is fine. Now we have a larger card view. Let's finish creating our relative layout. And let's move this one to inside the first relative layout. So I'm going to copy everything, but I think it's better to minimize this relative layout, and copy everything or cut everything to be precise and paste it in here. You can see that now our card view has this strange shape. Let's quickly fix that. So if we open this relative layout, you can see that for the height we have set match variant, I'm going to change that to wrap content. As soon as I do that, you can see in the preview that the height has been changed to wrap content. Okay, let's minimize this one. After this relative layout, I'm going to create another relative layout, which is going to be the expanded version of our card view. So let's say relative layout for the width, I'm going to say match parent for the height, let's say wrap content, I'm going to move it to below the first relative layout. So let's give an ID to our first relative layout. Let's name this one collapsed relative layout. Once again, let's minimize it. Now in here, I can say below our collapsed relative layout. Inside this relative layout, as I said, I'm going to define some text views, I'm going to show the name of the author of this book. Plus I'm going to show the short description. So first of all, let's say text view, wrap content and wrap content for its text. I'm going to say author. Let's give it an ID. Let's just say author text. I'm not going to change the style or anything. After that, let's define another text view for the width, let's say wrap content. Similarly, for the height, wrap content, for its text, I'm going to put a name, I'm going to put my name for its ID, I'm going to say the author. This is the one that we are going to change later on in the code. Let's move it below our author text. Let's say layout below text author, or it was called author text. Let's add another text view in here. Text view, wrap content and wrap content. For its text, I'm going to say short description. And let's also give it an ID. Let's say txt short description. Let's also move it to below our other name. Let's say layouts below txt author. I think it's better to add a margin. Let's say margin top. I'm also going to need two icons. Let's quickly add them in our project and we will see why I'm adding these two. So in our driver folder, we can say new image asset. Let's select action bar and tab icons. For the icons, I'm going to search for arrow. The first one I'm going to add this one this down arrow. Let's change its name to I see down arrow. And also let's change its color to a black color. Let's add another one new image asset once again, this time I'm going to search for an up arrow. This one in here I think is fine. Let's change its name to up arrow, I see up arrow. And let's add it into our project. Now in here after this description text, I'm going to add my up arrow. So if the user decides to collapse this card view, he or she would be able to do that by clicking on our up arrow. So let's say image view, wrap content and wrap content for its source, let's say, I see up arrow. This one, let's move it to below our description text txt description. And also let's move it to the end of our card view. For that, we can say a line parent and and we can pass through. Let's give it an ID. Let's say detail of arrow. Okay, that's it for my expanded view. Now that I have defined it, I'm going to change its visibility to gone. But before that, I'm going to give an ID to this relative layout because we are going to need it in our adapter. Let's say ID. This time I'm going to name it expanded relative layout. And let's change its visibility, visibility to gone. Also, let's minimize this relative layout. So now you can see that we have two relative layouts. The first one is the collapsed relative layout, which the user is going to see when he or she opens our activity. And if the user clicks on the arrow that I'm going to add in a minute, we are going to show the second relative layout. Let's quickly add that arrow button. So down in here, I'm going to say, image view, wrap content and wrap content first again, for the source, let's say, down arrow this time, I see down arrow, let's move it to below our image, let's say layout below IMG book. Also, I'm going to add the same margin that I added for this text name. So let's say margin top, and let's pass 70p, you can see that for this text view, we have this 70p as well. Okay, let's give it an ID. Let's say BTN down arrow. Let's also move it to the end of our layout. A line parent and let's say true, I think it's better to change the position of name text to the beginning of our code view. Now that we have added this icon, let's quickly do that. For this text view, I'm going to remove this center horizontal attribute. I don't think we need anything else. Let's switch to our adapter. And let's see how we can work on this down and up arrow buttons. Before everything before I go to my adapter, I'm going to open my model, my book model. And I'm going to add another field. So inside our package, we had a book class. If you remember, I'm going to add another field in here. Let's say private Boolean, let's name it is expanded. I'm not going to receive this Boolean by the constructor. Instead, inside the constructor, initially, I'm going to set it to false. So whenever we create our book object, I'm going to set this value to false. Let's say is expanded is equal to false. Let's also create a getter and setter for this is expanded as well. We are going to need the getter and setter. Let's create them. Okay, now let's switch to our adapter class. And let's see how we can implement this logic book recycler we adapter. First of all, inside this interview holder class, inside the constructor, I'm going to set an on click listener for that and down arrow button. But in order to have access to that, I need to initialize that in here. So let's say private image view, down arrow and up arrow. Let's also define the other UI elements. For example, we had a relative layout, let's say private relative layout, expanded relative layout. We had two new text views, private text view, and txt author and txt description. Let's quickly initialize them in our constructor. Now that we have initialized these items, I'm going to set an on click listener for this down arrow button. Let's say down arrow dot set on click listener, new on click listener. Inside this on click method. First of all, I'm going to get the current book that we are looking into. In previous videos, we have seen how we can get that book inside the unbind view holder method with the help of that position. But it is also possible to get it inside this view holder class. We can get it like this, we can say book, that's name it book is equal to our box area list dot get this time for the position I can pass get adapter position. So this way, we are going to get the book that we are currently creating a view holder for that. After getting this book, we are going to change the field that we just defined. I'm talking about that is expanded Boolean. So whenever the user clicks on this down arrow, we are going to change the is expanded field of our book, I'm going to say book dot set expanded, let's say the inverted value of our book dot get expanded, or I believe it was is expanded. Instead of this line of code in here, you can write an if statement, but I've simplified my code to this way. So basically, we are inverting the is expanded value of our book. There is just one last thing that we need to do in here. And that is to tell the adapter that we have changed some item in our data set. In previous videos, we have seen this notify data set this one. But in here, because I'm only changing one item, I'm going to say notify item changed. And of course, in here, once again, I need the position which I can pass this get adapter position. So this way, we are going to update our recycler view adapter. Later on in our online viewholder method, we are going to take care of the expanding and collapsing our cart view. Besides this down arrow, we also need an on click listener for this up arrow. Let's quickly write that as well. Let's say off arrow dot set on click listener, me on click listener. And in here, the logic is the same. Once again, we are going to invert the value of our books is expanded field. So basically, I can copy and paste these three lines of code. Let's paste them in here. So by clicking on our down arrow or up arrow, we are inverting this is expanded field. And that's all we need to do inside this viewholder class. Let's see what do we need to do inside the online viewholder method. So in here, first of all, I'm going to check that if the is expanded is true or not. Let's say if books dot gets, let's pass our position dot is expanded. It means that if we do need to expand our card view, then we are going to do that. And we can do that like this, we can say holder dot expanded relative layout dot set visibility. Let's change it to visible. We also need to make our down arrow icon invisible. For that, I can say holder dot down arrow dot set visibility. Sorry about that. Set visibility. Let's say gone. Let's also write the else case. In the else case, we are going to change the visibility of this expanded relative layout to gone and this down arrow to visible. So let's copy these two lines of code and let's change their values. This in here is going to work fine. But if you remember, I said that we are going to also add some sort of animation to this expanding and collapsing for that before changing the visibility of our UI elements, I'm going to call this transition manager. I'm not sure that if you have noticed, but it's coming from this Android X transition, make sure to import the right one. Let's say dot begin delay transition. For this method in here, we need to pass our route. In this case, the root is our card view. So we can say holder dot parent. If you remember, we gave an ID to our card view, which was parent. And that's all we need to do. Let's also do the same thing inside the else case. So by this point, we have changed the visibility of our relative layout, but also we need to set the data for the author's name and also for the short description. I can do that before this if case, I can say holder dot txt author dot set text to books dot get let's pass position dot get author. Similarly, for the short description, let's run the application. And let's see if we can have an expandable card view. Let's go to our all books activity. You can see that right now we are seeing the collapsed version of our card view. Also the size is bigger. We also need to move this recycler view this card view to the center of our layout, we will fix that. But right now, if we click on this down arrow in here, you can see that we are seeing the expanded version of our card view. Once again, if we click on this up arrow, we can see the collapsed version of our card view. It seems like our logic is working fine. Let's quickly center this card view. And also let's add another item into our recycler view. And let's see if the collapsing and expanding is working the same or not. So first of all, I'm going to go to the layout of my all books activity in my app folder inside the resources layout activity all books dot XML, I'm going to change its width to wrap content. And also I'm going to center it horizontally. But in here, we are using this constraint layout. So for that, I need to constrain this recycler view. That seems better. Let's quickly add one more book to our recycler view in our Java file in our all books activity dot Java file down in here, I'm going to add another book, I'm going to cut the process of adding a new book. Okay, now that I've added another book, let's quickly run the application and let's see if our expandable card view is working the same. Let's go to our all books activity. This time, you can see that we are seeing two books. If I click on the down arrow of the first one, you can see that we are seeing the short description and also the author name. But the second book is still in the collapsed version. We can do that for the second book as well. Let's quickly change the linear layout manager to grid layout manager and show the problem with grid layout manager. So in here, we need to pass a column number, which I'm going to pass to let's run the application once again. So in here, we have two books in our layout file in our recycler view. If I click on this down arrow, which you can hardly see, we can see that the layout file for both of these card views changed. So this way of implementing an expandable card view is not going to work for our grid layout manager. For implementing the expanded card view in our grid layout manager, we need to know a bit more about recycler views. For example, we need to know that in recycler view adapter, we can have multiple view holder classes. And handling two different view holders in recycler view adapter is out of the scope of this section, we will cover that later on in the course. But for now, we are just going to stay with linear layout manager. Our work with expandable card views are not done yet. Later on in the course, we will add some action to this expandable view, for example, some buttons to delete this book from a specific list in our application. But for now, I think that's enough. And also I think that's enough for this video. In the next video, we are going to create our book activity in which if we click on one of these card views, instead of sharing this toast message, we are going to navigate the user to another activity in order to show some more detail about our book. And also beside sharing more details, we are going to give the user some options, for example, to add the book to some of the lists. Okay, see you in the next video. In this video, we are going to create a book activity, and we are going to navigate the user when he or she clicks on one of our books in our recycler view. For that in my package, I can right click once again, by selecting new empty activity, I can create my activity. Let's name this one book activity. I am going to generate a layout file. So I'm going to leave this checkbox checked. Let's close this Java file, and let's start working on our layout. So our layout is right now a constraint layout. First of all, I'm going to add an image view in here. For the image of my book, for the sample data, let's select an avatar. After that, I'm going to add four buttons in here. We will talk about the purpose of these buttons. For now, let's just add them. After that, I'm going to add some text views in here for the name, author and description of my book. I'm going to give some ID to these UI elements. And beside that, I'm going to set some initial data for them. Because we have done this before, I'm going to cut the process of doing that. I've added the initial data for each one of these items plus I gave them some ID. You can see the ID, for example, for this first button, which is a btn add to currently reading list. So basically, by clicking on this button, I'm going to add this book to the currently reading list. It means that I'm currently reading it. You can guess the others. This is for adding to the visual list. This is for the books that I already read. And the last one is for adding to favorite books. Also down in here, we can see the box name, books author, books pages, and also the books description. And this image is going to be the image of our book. Okay, now let's quickly add some constraints. For this one, I'm going to constraint it to top of my screen and also to the left of my screen. Besides that, I'm going to add a vertical guideline in here. Let's right click, helpers, and vertical guideline. And let's move it to somewhere around here. And let's constraint our image view to this guideline. Let's also add a margin top, I think 50 would be fine. Let's quickly constraint our buttons. For this one, I'm going to constraint it to top, let's say 15 as the margin top or 50. Let's quickly constraint it to the edge of our screen and also this vertical guideline. I'm going to do the same thing for my buttons for the other buttons. Just for the margin top, I think I'm going to stay with 24. Let's add a horizontal guideline and let's constraint our text views to that horizontal guideline. So let's say at horizontal guideline, let's move it to down below somewhere around here. Let's also add another vertical guideline. We will see its usage in a minute at vertical guideline. I think its place is fine. And I'm going to constraint these text views to this guideline here. Let's do the same thing for the other text views. Also, I'm going to add another vertical guideline. Let's say add vertical guideline. I think they overlap. Let's move this vertical guideline to somewhere around here. And let's constrain these three text to this vertical guideline. We can see that guidelines are extremely useful when you are designing your layout files with constraint layout. For the top of this text view, I'm going to constraint it to the top of my book name. Also the same thing for the button. You can also use the baseline, but in here I've used the top and bottom constraints. Okay, I think that's all of the constraints that I need. I just want to change the width and height of this image view to somewhere around 150 dp because different books can have different widths and height. Okay, now let's quickly initialize all of these items in our Java file. Let's switch to book activity that's Java file. And let's initialize that I'm going to fast forward the process. As you can see, I've initialized all of my UI elements. Now it's time to set some values for each one of these books. For now, I'm just going to create a simple book in here. And after that, depending on the book's value, I'm going to change the value of all of these UI elements. But we shouldn't do it this way because we are going to change the values of these UI elements depending on the item that we click on our recycler view. We will see that how we can get the item that we have clicked on later on. But in here, just to test our UI, I'm going to create a book. I think I have a book in my all books activity. So I'm going to copy it from there. After creating this book, I'm going to create another method. Let's name it set data. Also, I'm going to pass my book object to this method. Let's quickly create this method. Let's say private void, set data, and let's receive a book. Before I do anything inside this method, I'm going to add a to do in here so that we don't forget to get the incoming data from the recycler view. Okay, inside the set data method, I'm going to say txt book name set text, let's say book dot get me. And similarly for the other three text views. For these pages in here, because we have set the pages as an integer in our book model, we need to cast it into a string in here. And here is how we can do that. I can say a string with capital s dot value of, let's say book dot pages or dot get pages. This way, we can cast this integer to a string. And after that, we can pass it to this set text method for the description. Let's do the same. Let's say that set text book dot get long description. Let's also show our image. I'm going to use glide. Glide dot with this is an activity. So I'm going to pass this as bitmap dot load book dot image URL, or get image URL dot into our book image. So this way, we can set the data in our UI elements. In order to test this application, I'm going to go to my recycler view adapter. And from there, I'm going to create an intent. So right now, inside this holder dot parents on click listener, we are showing a toast message. Let's remove this toast message. And let's create an intent intent is equal to new intent for the context in here. If you remember, we are receiving a context by the constructor of this class. So I can use that. I'm going to say m context for the destination. Let's say book activity dot class. After that, usually if we were inside an activity, we could have used a start activity method. But in here, you can see that we don't have that option, because this start activity method is specific to activities. If I want to use that, I can say m context dot start activity. So with the help of our context, we can have this start activity method. After that, we need to pass our intent. So right now, no matter on what book we click, we are going to navigate to book activity. And in there, we are going to show the details of this one q 84 book. I'm doing this because I'm going to test my UI. Let's run the application and let's see if everything works fine. Let's go to our all books activity. And in here, if we click on this book, for example, you can see that we are seeing the details of this book. But right now our layout has some problems. For example, we need to increase the widths of our buttons because they don't fit in one line right now. And also I'm going to increase the size of this image view. Let's quickly fix these two issues in our activity book. If I click on this book image, I'm going to change this one, this beats and height to 200 dp. Also for these buttons, let's increase the beats from 150 to I believe 170 would be fine. Let's run the application one more time. And once again, let's go to our book activity. This time it's somehow better. Also, we need to be careful about this long description in here as well. Because if this description don't fit on the screen, we probably couldn't see all of the text. For that, I'm going to add a scroll view into my layout file. We haven't seen a scroll view, but its purpose is to create a view that we can scroll. Let's quickly see how we can add that in our constraint layout. So basically, what I'm going to do is that I'm going to change these parents to a relative layout. After that, I'm going to create a scroll view inside that scroll view. I'm going to create a constraint layout. And I'm going to move all of these items into that constraint layout. Let's see what I'm talking about. So as I said, I'm going to create a scroll view for the beats and height, let's say match parent. Inside this scroll view, I'm going to create a constraint layout. Once again, for the beats and height, let's say match parent. After that, I'm going to move all of my elements to inside this constraint layout. And after everything, I'm going to change this constraint layout to a relative layout. So let's select all of these items. And after everything, as I said, let's change the parent to a relative layer. Let's enable the split view. And let's see if we have a good layout. It seems like we have done a good job. Let's run our application. Let's go to our book activity. And we can see the same result. Let's quickly add a longer description. And let's see if we can scroll our view. I've copied the text in my book activity. I'm going to set that text as the long description of this book. But before that, I'm going to create a string in here. Let's say long description is equal to this text that I'm going to paste. Now that we have this text, let's set it as the long description of our book. Let's run the application once again. And let's see if we can scroll our view. Let's go to book activity. And in here, you can see that we have a long description that does not fit on our screen. But as you can see, we can scroll this view. Okay, I think that's enough for this video. This was a short video just to create the layout file for our book activity. In the next video, we will see that how we can pass our book from our recycler view to this activity. And beside that, we will work on the logic of these buttons. See you in the next video. In this video, we are going to write the logic for these buttons, we are going to add our books to different categories by clicking on each one of these buttons. But before I do that, I need a data storage to save these books to different lists. In a normal application, in this situation, you may want to use a database. A database is a place that you persist your data. It can be a local database on your smartphone, or it can be an online database on a web server. In here, we haven't talked about any of those. We haven't talked about databases yet. We are going to talk about them later on in the course. In fact, we have a section dedicated to databases. But in here, we are going to use an alternative. We are going to use some of the capabilities of Java language. In previous videos in Java section, if you remember, I talked about a static keyword. I said that when you define a variable or an object as a static, that variable will have the same value in all of your application, regardless of where you have initialized it. In here, we are going to take advantage of that. And we are going to define our different lists of books as a static variables. This way, we have the same lists when we are working with our application in different activities. But there is a downside to this way of using a static values. Your data would not be persisted. It means that if you close your application, you lose all of your data. At the end of this section, I will introduce another alternative in which you can use to persist your data. But in here for now, let's just use a static variables. For that, I'm going to create a utility class in my package and we will see an action by I'm creating this class. So in my package, let's right click new Java class, I'm going to name it utils. In a real world application, this utils class is probably your database class. But of course, the name should be different. But in here, we are not using databases. So I named it utils. The first thing that I'm going to do inside this class is that to make this class singleton. So I'm going to implement singleton pattern in here inside this class. If you remember from the Java section, whenever we implement a singleton pattern for a class, we can have only one instance of that class in our entire application. I'm making this class singleton because I want only one instance of this class. Basically, this is the class that we are going to interact with our static array lists. And for that, I'm going to be sure that I have only one instance of this class in my entire application. Okay, let's quickly see how we can implement singleton pattern. First of all, I'm going to create a constructor for this class. It's an empty constructor. And right now we don't have anything. After that, I'm going to define a static instance of this class. Let's say private static utils, the type of our class. Let's name it instance. Besides that, I'm going to need a getter for this instance. You remember all of this from the Java section. So I'm not explaining them. Let's say getter for the instance. First thing, I'm going to change the modifier of this constructor to private. Let's do that. And inside this get instance method, I'm going to write the logic to make this class a singleton. So I'm going to say if null is not equal to my instance, then return the instance. But in the else case, in case if the instance is null, let's say instance is equal to new utils. And after that, we can return our instance, let's say return instance, because we are returning in each one of these cases, in a longer need this return instance down in here. In the Java section, we also have used the synchronized keyword. If you remember, we have used this one in here. In there, I said that this synchronized keyword will make your method to be thread safe. It means that if different threads at the same time call this method, this synchronized keyword will cause them to call this method one by one and not at the same time. But in this application, we are not going to use trading, we are going to have only one thread called the main thread. So for that, I'm not worried about trading issue in here. And I can safely delete this synchronized keyword. So by now, this utils class is a singleton class. Now we can create our static lists. So for example, in here, I can say private static. Let's say array list of different books. Let's call this fun all books. As you can guess, this fun is going to represent all of our books in our application. But where do we initialize this all books array list? We know for sure that when we create an instance of our utils class, we are going to call this constructor. So the perfect place to initialize this all books array list is inside this constructor. Let's move it to down below this all books so that we can follow the logic better. And inside this constructor, let's say if null is not equal to our all books, we don't want to re initialize our array list, we just want to initialize it one time when we create our application. Or better than that would be to say if null is equal to our all books, I'm going to say all books is equal to new array list. And after that, I'm going to create another method in order to add some initial data to this all books array list. So let's say init data, let's quickly create this method by pressing Alt plus enter, you can create your method. For now, I'm just going to add a to do in here. And later on, we will complete this method. Let's say add initial data. In case if you have forgot about these to do, these are some sort of comments that you live for yourself or for your colleagues, so that you don't forget anything later on, when you want to go in production, you can check this to do down in here. And you can see the works that you left for the future. Okay, let's move on from this part. Beside all books array list, I'm also going to define other array list as well. Let's say private static array list of different book. Let's name it already read book. Let's define three more one for currently reading books one for one to reading books or wish list books, and another one for favorite books. Similar to our all books array list, we need to initialize this array list inside our constructor as well. So down in here, once again, I can say if null is equal to my already read books. Then I'm going to initialize it. Let's say already read books is equal to new array list. But I'm not going to add any initial data because we are going to leave that option for the user later on when he or she uses the application. Let's do the same thing for the other three array lists. We now have initialized all of our lists. Now let's see how we can get the values or the items from our list. For that, I'm going to create get their methods. For example, for this all books array list, if you want, you can create a getter. Let's quickly create that down in here. By pressing alt plus insert, you can create getters for all of your lists. Let's add some initial data to our all books array list. And let's test this utilize class and let's see if everything works fine. So if you remember in all books activity, we have created this array list manually. After that, we have passed this array list to our recycler view adapter. I'm going to cut the initializing of our array list from here. And I'm going to move it to my utils class. Right now we have an error, we will fix that. So inside utils class inside this init data method. After this to do, I'm going to paste my array list. This time instead of saying books dot add, which is this array list, I'm going to say all books dot add this one in here. So this way we are adding two books to our all books array list, I can safely delete this one as well. Remember that we are calling this init data method from inside our constructor when we are creating our all books array list. So whenever we run our application and we call this utils class, this utils dot get instance method, we have some data in our all books array list. Now that we have some data in our all books activity. Instead of this books, we can say utils with this capital u dot get instance dot let's say get all books. If we run our application, if everything inside our util class works fine, we should see two books in our all books activity. Let's quickly test that. If we go to our all books activity, you can see that we are seeing two books. It seems like our utils class is working fine. We are going to add a ton of more codes inside this utils class. But more on that later on. For now, let's see how we can pass a book from our recycler view adapter to the book activity. For example, right now, if I click on this, the myth of Sisyphus, you can see that we are seeing this one q 84. It means that we didn't pass our book to this book activity. In fact, in our book activity, we are defining the book itself. And we are not getting any data from the recycler view. Let's see how we can pass a book from our recycler view to this book activity. So if you remember inside the book recycler view adapter, inside this holder dot parent dot set on click listener, inside the on click method, we have created this intent. The use of this intent is to navigate the user to the book activity. The good thing is that with this intent, you can also pass some sort of data. Let's quickly say that as well. So for example, in here, I can say intent dot put extra, you can see that we have a ton of these different methods for all sorts of variables and all sorts of data. Let's use one of them. For example, I can pass the book ID in here, we can see that in here we need two arguments, a string and after that data that we want, the string is always the key or the name of your value in here. For example, if I say book ID later on inside my book activity with this book ID, I can get the book ID. So the values inside your intents are key value pairs. For the idea of this book, I can use this box array list that we have inside this adapter, I can say books dot get, let's pass position. Let's say dot get ID. So this way we are passing the ID of our book to the book activity. Later on in our book activity, we will get our book by its ID. If you remember, I said that the ID for each book is going to be unique. It's worth mentioning that you can also pass the book itself, you can pass the whole object for that instead of passing an integer, you can pass a parcelable. Let's quickly see that you can say intents dot put extra. And down in here, if you take a look, one of the arguments in here is this parcelable, we will talk about parcelable later on in the course. But basically, it's an interface that will serialize your class at the time of transferring it from one activity to another activity. And at the time of retrieving it, it will deserialize your object. Don't worry about these two words that I'm using basically using parcelable is really easy. We will take a look at that later on in the course. But for now, we are just going to pass an integer. Besides that, you can also set multiple extras for your intent. For example, if I want to pass the book name in here, once again, I can say dot put extra. For the key, I'm going to say book name. And if I want, I can say box dot get position dot get name. Of course, we are not going to need this in here. But I just wanted to say that you can pass multiple extras with your intent. Okay, now that we are passing some data with our intent, how we can retrieve that data in our book activity. Before that, let's quickly remove this one to have a review in here. First of all, we are creating our intent. The context is this m context, which we are receiving with the constructor of this adapter, the destination of this intent is book activity dot class. We are calling this put extra method on our intent. And with that, we are passing some integer. In this case, we are passing the book ID. After that, with the help of our context, we are starting the activity, which in this case is this book activity dot class. So now we can continue our code from inside the book activity inside the uncreate method. Let's close this one. Also, I'm going to close this one, utilize class my layout file. And let's open book activity. So inside this uncreate method in here, if you remember, we are creating a book and we are setting its value to our UI elements, we can see that we also have a to do in here, get the data from the cycle review in here. So if we want to get the data, in this case, the book ID from our recycler view, we can say something like this, we can say intent. Let's call it intent is equal to this time, instead of saying new intent, I can say get intent. So if you use this get intent method, you are going to receive the incoming intent, the intent that caused this activity to be launched. But you also need to be careful about the null values of this intent, because this intent can be null at some times. So for that, I can say if null is not equal to my intent, I'm going to continue in here. After that, I'm going to receive the book ID. I'm going to say int book ID is equal to intent dot get int extra, you can see that we have a lot of this get extras method for different kind of data. For example, if you are going to get an integer, we can call this get int extra, we can see that the method in here is waiting for two things we can press down the control key and you can see the documentation. First of all, we need the name of our variable which if you remember was book ID. And the second one is a default value. So in case if for any reason this get int extra wouldn't be able to get any data from our intent, we are going to assign a default value for the name, let's pass book ID. And for the default value, I'm going to pass negative one, because I know for sure that none of my books in my list are going to have negative one as their ID. Also about this name, this key, this book ID in here, you need to be extra careful about this. The characters, the upper cases and lower cases need to be exactly the same. If you put anything wrong in here, you're not going to retrieve your data. There is a better option than hard coding your keys. Instead of passing your keys manually, you can create constants. For example, above in here, I can say public static final string. The convention is to name your constants in upper cases. For example, in here, I can say book ID key. I can also assign a value to this one. For example, I can say book ID. Now that I have defined this constant in here, I can pass it in two places. For example, the first time I can pass it as a key, I can say book ID key. And also inside my adapter class. Instead of hard coding the key in here, I can say book ID key. You can see that we need to import this by pressing alt plus insert. We can import this constant into our class. If you take a look at above in here, in the imports, we are importing this constant into this class. So this way by using different constants, you make sure that the keys are the same in two different places. Okay, let's switch back to our book activity. So by this time after this line of code, we either have a negative one value or we have the book ID, we need to create an if statement for this negative one value. Let's say if our book ID is equal to negative one, or the better logic would be to if it's not equal to negative one, let's pursue the code. So by this time inside this if statement, we have our book ID. How do we get the book by its ID? If you remember at the beginning of this video, I said that we are going to write all of the interactions with our lists inside the utils class. So for that once again, I'm going to go to my utils class. I'm pressing double shift in order to pop up this search menu if you are wondering anywhere in Android Studio, you can press shift two times and you can get this menu in which you can easily type and go to your class. For example, inside this utils class, after everything, I'm going to create a method. I'm going to say public book is going to be the return type of this method. Let's say get book by ID. We also need to get the ID. Let's say int ID. After that inside this method, I'm going to log into my all books activity. And I'm going to return the book by its ID. For that I'm going to create a for loop, a for each loop to be precise. Let's say for book B inside our all books are released. In case if B dot get ID is equal to the ID that we received, then we are going to return B. So if we have a book with this ID, we are going to return it but after the for loop, if we didn't return anything, we are going to return now by returning null in here, we are acknowledging that we may not found a book with this ID in our list. So whenever we call this get book by ID method, we also need to be careful about the null values because the result can be null. For example, inside the book activity in here, I'm going to say book. Let's name it incoming book is equal to our utils class dot get instance first of all dot, let's say get book by ID. After that, we can pass our book ID. After this line of code, we need to make sure that this incoming book is not null. So let's say if null is not equal to our incoming book, then we can call our set data method, which is this method, I can call this and I can paste it inside this if statement. You can see that before getting our book and before passing it to this set data method, we are doing three security checks. First of all, we are checking that our intent is not null. After that, we are making sure that we have received some data from our intent. After that, we are checking that if we have such a book with this ID in our list, in a normal scenario, in a good situation, none of this would be necessary. And you can simply call this get books by ID method and you can get your book. But a lot of things can happen when you call your activity and when you pass your data, your activity may be destroyed, your activity may be interrupted by some call that user receives, your activity also may be called from different places. And also for other security reasons, you always need to check for the intent for the incoming data, and for the data itself inside your data storage. Sorry, I need to change this book to incoming book in here. I mistakenly put book in there. Okay, now that we are setting our incoming book, we can safely delete this book above in here. Let's comment all of this. Let's test our application. And let's see if we can successfully navigate the user to book activity and show the appropriate book. Let's go to all books activity. One q 84 we are seeing one q 84. If we click on the myth of Sisyphus, you can see that now we are seeing the myth of Sisyphus, it seems like we are passing the data from our recycler view from inside the all books activity to the book activity successfully. Okay, I think that's enough for this video. I did want to talk about the logic for these buttons, but I think that's better to be left off for the next video. Okay, see you in the next video. In this video, finally, we are going to take care of these buttons, we are going to add the book to different lists by clicking on each one of these buttons. Besides that, we are going to disable the button if the book already exists in one of these lists. For example, if the book exists in the user's wish list, we are going to disable this one to read button. Let's go to book activity. And let's see how we can do that. So inside this book activity inside this uncreate method, I'm going to call another method. But I'm going to do that inside this if statement after I made sure that I have an incoming book. So let's name this method handle already read. I'm also going to pass the incoming book itself. Let's quickly create this method down in here. Let's say private void handle already read. Let's also receive a book inside this method. First of all, I'm going to check that if this incoming book exists in our already read books. So for that, I'm going to say array list of book, let's name it already read books is equal to utils dot get instance dot get already read books. This method. After that, I'm going to create a for each loop. Let's say for book B inside our already read books. Also before this for loop, I'm going to define a Boolean and its purpose will be clear in a minute. So let's say Boolean, let's name it exist in already read books. Let's initialize it to false down in here inside the for loop, I'm going to say that if B dot get ID is equal to our incoming book dot get ID. If that's the case, we are going to change the value of this Boolean. Let's say exist in already read books is equal to true. So after this for loop, we know that if the book exists in our already read books array list, and we can use this Boolean, we can say if existing already read books is equal to true, then we are going to disable our button because we don't want to add this book one more time in the already read books array list. So let's say btn already read or btn add to already read dot set enabled this method. And let's pass false. So this way we can disable a button. In the else case, I'm going to set an on click listener for this button. And I'm going to add it to my already read books array list. So let's say btn add to already read dot set on click listener, let's say new on click listener. And inside this on click method, we need to add it to our list. But because I'm going to keep all of my interactions to my lists inside the utilize class, I'm going to create that method inside the utilize class. So let's go to utilize class. And let's minimize all the extra unnecessary methods for now. Down in here, I'm going to say public. For the return type of this method, I'm going to say Boolean, and we will see why public Boolean add to already read. Let's also receive a book. And inside this method, let's say return already read list already read books dot add. And let's pass our book. So if you remember from the Java section, when we use this ad method on our array list, this ad method is going to return a Boolean. The Boolean is going to be the indicator that if we have added the book successfully or not, if you press down the control key, or if you are on a max system, if you press down the command key, by clicking on this ad, you can see the documentation in here, you can see that if we successfully add this element, which is the generic data type in Java, at the end of this method, we are returning true. It means that we have added the elements into our array list successfully. So in here, we are returning that Boolean later on in our book activity, we are going to check for this Boolean, and we are going to make sure that we have added this book item into our list successfully. That's all we need to do inside this ad to already read, and we can switch back to our book activity. So once again, inside this on click method of this ptn add to already read, we are going to check that if utils dot get instance dot add to already read with the incoming book. If that's true, we are going to show a toast message. Let's just say book added. But in the else case, I'm going to show a different host message. Let's just say something wrong happened, try one more time. Also, in the if case, in case if we add the book successfully, I'm going to navigate the user to another activity. To be precise, I'm going to create an activity called already read books. And in that activity, we are going to show the list of books that the user has already read. But first of all, I need to create that activity. In here, I'm just going to put a to do right now. So let's say navigate the user. Once again, let's review what we are doing inside this method. First of all, we are getting the already read books from this utils class. After that, we are checking that if our book exists inside this already read books, if it does, we are disabling our button. But if it doesn't, we are setting an on click listener for this button, in which by clicking on that button, we are adding the book to already read books are a list. If that process goes well, we are going to show a toast message. And after that, we are going to navigate the user to already read book activity. But in case if something wrong happens, we are just going to show a toast message. This else case should never happen. But I just put it for the security reason, we don't want to gamble on anything that can happen in our application. Okay, by now, we should be able to test our application and check if we can successfully add a book to our already read book area list. Let's run the application. Let's go to our book activity by clicking on one of these books. And in here you can see that this button is not disabled. And that's because this book does not exist in our already read book area list. If we click on this already read button, we can see that the book has been added to our array list successfully. I said that after this, we need to navigate the user to already read book activity. But for now, let's go back to levels. And once again, let's go to our book activity. And let's see if that button is still available, which is not. It seems like we have wrote the logic perfectly. Okay, now let's quickly create the already read book activity. And let's navigate the user there. But before that, I'm just going to warn you about something. I don't usually comment my code. And that's because I'm lazy, that's an execute. But you don't follow this behavior, you put comments wherever you feel necessary in your code. For example, before the declaration of this method, we can put a comment. And in here we can specify the purpose of this method. For example, I'm going to say enable and disable button. Besides that, we are going to add the book to already read using comments in your code might seem some minor thing. But believe me, if you come back to your code one month later, probably you don't remember any aspect of your code. And the only thing that you have that will help you to understand your code are these comments. Also beside that, you may work with a team on a project. And these comments can be extremely useful. So not only at the declaration of your methods, but wherever else you feel like you need comments, please do use comments. Okay, let's move on from this part and let's create our already read book activity. So in my project, I can right click on the package and by saying new activity, empty activity, we can create our activity. I'm going to name this one already read book activity. I also am going to generate the layout file. So let's leave this checkbox checked. The layout file for this activity is going to be really simple. Basically, we just need a recycler view. In that recycler view, we are going to show our books. So let's switch to our layout file. And let's drag a recycler view in our layout. For the width and height, I'm going to say match parent. And also let's give it an ID. I'm going to say book recycler view. Besides that, let's add some margin in our split view. I believe that would be better. Let's add a margin in here. margin, I believe 10dp would be fine. Okay, now back in our Java file, we can initialize our recycler view. For example, down in here, I'm going to say recycler view. Let's name it recycler view is equal to find view by ID are dot ID dot books recycler view. I don't think we had the s let's remove that so that we don't get an all pointer exception. After that, I'm going to create my adapter. And here is where the recycler view is coming very handy. We have created a book recycler view adapter in our project previously. And the good thing is that we can reuse our adapter as many times as we want. So once we have used that in our all books activity, we can also use it in here. For example, I can say books recycler view adapter. Let's name it adapter is equal to new books recycler view adapter. We also needed the context. Let's pass this. Let's say recycler view dot set adapter. And let's pass our adapter. Besides that, we can set a layout manager for our recycler view. I'm going to say recycler view dot set layout manager. Once again, I'm going to pass linear layout manager. Let's pass our context. For the data, I'm going to say adapter dot set books. I'm going to pass utils dot get instance dot get already read books. This method in here. Also, we are keeping this highlighting here. This highlight says that you can also use this get already read books method without instantiating your utils class. Let's do that. We can do this because this get already read books method is a static method. So for example, before getting an instance, I can say that get already read books, you can see that it's working perfectly. But there is a potential bug in here. Right now, the first place that we are calling our utils class is inside the all books activity. I'm talking about that utils dot get instance method. So before that, we don't have any instance of this utils class in our application. So before going to add all books activity, we don't have any array list called already read books. Because if you remember, we are initializing our array lists inside the constructor of this utils class. What happens if the user decides to come to this already read books activity first, and don't go to the all books activity. In that case, this get already read books method is going to return now. And that's where the potential bug can happen. Inside the adapter of our recycler view, we are calling some functions on our books array list. And we know that calling a function on a null reference can cause null pointer exceptions. What can we do to avoid this null pointer exception? We can call utils dot get instance inside the main activity. We don't need any functionalities from utils class in main activity. But we are just going to do that in order to avoid null pointer exceptions. And to initialize all of our lists. So let's go to main activity. And inside the uncreate method after initializing all of our buttons, I'm going to say utils dot get instance. This way we are calling the constructor of this utils class and we are initializing our lists. Also now that we are here, let's quickly set an unclick listener for this btn already read. I'm going to say btn already read that set on click listener me on click listener. And I'm simply going to navigate the user to this activity to already read books activity. So let's create an intent intent is equal to new intent. For the context, let's pass main activity dot this. And for the destination already read book activity dot class. After that, we can say start activity and we can pass our intent. There is one more place that we need to navigate the user to already read books activity. And that's where we have added the book into our already read books list. Let's copy this intent. And let's go to our book activity. If you remember, we had a to do somewhere down in here, in which we are saying to navigate the user. After this to do, I'm going to paste my intent. But of course, I need to change this context. Let's change it to this. Or because we are inside this interface, we need to pass book activity dot this. Now that we are navigating the user, we no longer need this to do. Let's remove that. And let's run our application once again. And let's see if everything works perfect. First of all, let's go to already read books activity. We can see that right now it's empty. It's also better to show something in case if we don't have anything in our list, we will take care of that in future videos. But for now, let's go back and let's go to our book activity. You can see that this already read books button is enabled, you may be wondering why this one is enabled because previously we have added this book into our already read books array list. Well, that's because we are not resisting our data, we are not using any database or anything, we are just simply using a static array lists. Because of that, the life of our data storage is only whenever we close our application. In future videos in this section, we will use another option to persist our data. But for now, we just lose our data whenever we close our application. Okay, let's click on this already read book button. We can see that we are successfully navigating the user to already read book activity. If we go back, we are once again inside the book activity, but still this already read button is enabled. This is because of an entirely new concept. That's because of the activity lifecycle. Whenever we add this book to our already read book list, and we navigate the user to already read book activity. And from there, when we press this back button, we are not calling the uncreate method of our activity. We are calling some other methods in which we are going to talk about them in future videos in activity and fragments section. So we are not going to talk about this problem right now. But if we press this back button once again, and if we go to our book activity, you can see that now this already read button is disabled. But the thing that we are going to talk about in here is that whenever we add a book to our already read book area list, and whenever we navigate the user to the already read book activity, by pressing this back button, we are going to navigate the user back to the main activity and not this book activity. We are going to talk about how we can fix that. For example, if I go back and add this other book to my already read book area list, let's quickly do that. Whenever we are navigated to this already read book activity, by pressing this back button, we are going to navigate the user back to main activity and not to the book activity. We will talk about that later on. Let's also go back to main activity. And from there, let's click on this already read books. Once again, you can see that we have two books in our already read books area list. There is just one minor problem in here. And that's we need to center our recycler, we will fix that. Okay, let's fix these problems one by one. First of all, let's center this recycler view. And after that, let's take care of this back button. So for this recycler view, I can go to my layout file activity already read book. And in here, I can change the beats and hide to wrap content. And after that, I can constraint my recycler view. Because we are inside the constraint layout. Or I think this button constraint wouldn't be necessary. Let's remove that. Okay, it seems like they have fixed this. Let's go to our already read book activity that Java file. And let's see how we can take care of the back button. For the back button, we have few options. The easiest fun is to override some method called on back pressed. If you press control or somewhere inside your activity. If you search for on back pressed, we can see this method in here, we are going to override this method. This method is going to be triggered whenever the user click on the back button. So inside this method, instead of the super statement, we can simply create an intent and navigate the user back to main activity. Let's see how we can do that. We can say intent intent is equal to new intent. Let's pass this as the context and main activity that class as the destination. After that, let's say start activity. And let's pass our intent as simple as that. Let's run the application. And let's see if we are going to navigate the user successfully back to main activity. Let's add one book to our already read books area list. For example, this one, we are navigating the user to already read book activity. If we press back, you can see that now we are inside the main activity. But there is one more problem in here. If you press this back button, we will be navigated back to already read books activity. And that's because of something called back stack in programming. So whenever you are going to an activity, some stack will be added to your application. Basically, the Android system is going to keep a history of where the user visits in your application. Whenever you go to a new activity, a new stack, or to be precise, a new task will be added to your back stack. You can deal with that back stack if you want. For example, you can clear that back stack or whenever you are defining a new job, for example, whenever you are firing an intent, we can say that this is an entirely new task. And you don't want to keep any history of the user's visit in your application. In order to define your intent as a new task, you can add some flags to your intent. For example, after defining your intent, we can say intent dot set flags, this method in here, and you can pass two flags, you can say intent dot, let's say clear task. You can see this flag activity clear task in here. And also I'm going to add one more flag, you can add one more by using this pipeline, let's say intent dot new task, you have this flag activity new task. So by using these two flags on your intent, you are saying that you want to clear your back stack. And also you are defining this intent as a new task. So now if we run our application, if we add a book to our already read books are a list, for example, this one. Now if I press this back button, I will be navigated to the main activity. But my back stack is now clear, it means that if I press this back button, we are going to quit the application. So this way by using these flags, you can define a new task. Okay, let's move on from this part. And let's work on the other buttons in our book activity. If you remember, we had three more buttons. So once again, I'm going to go to the on create method. After getting the incoming book, I'm going to call another method called handle want to read books. Once again, I'm going to pass my incoming book. The logic for this button and the other three buttons are going to be exactly the same. So I'm going to call two more methods in here, handle currently reading book and handle favorite books. Let's quickly create these methods down in here. I think we can also copy some of the logic from inside this method, let's copy them and we will change them if it was necessary. I'm going to copy this whole method. And I'm going to paste it inside this handle want to read books. We need to change a few things. First of all, we need to make this book final, because we are using it inside this on click listener. After that, I'm going to change the name of this already read books are a list. I'm not sure if I talked about this previously, but basically whenever you want to change the name of a variable or some object in your application that you're using in multiple places, you can press shift plus f six. And in here, you can refactor the name of your variable. For example, in here, I'm going to save one to read books. You can see that when I changed the name of this early list, it will be changed in all of its usages. So let's say one to read books. And let's press enter. I also need to change this method in here. Let's say get one to read books. I need to change the name of this Boolean. After that, I need to disable another button between add to want to read this one. And I also need to set an on click listener for this within add to want to read. So let's change that. I also need to create another method inside my utils class so that I add this book to my wish list. So let's go to utils. And down in here, let's create a similar method. You can see that the method is basically the same. We are returning a Boolean once again, and we are adding the book into our want to read books are a list. Now inside our book activity, instead of this add to already read book, I can say add to want to read. There is just one more thing that I need to take care in here. And that's navigating the user to want to read books activity and not the already read book activity. So let's quickly create that other activity. Once again, in our package, we can say new activity, empty activity. The layout file is going to be exactly the same. So I'm going to fast forward the process of adding the recycler view. Don't worry, if you need to check the source code, I will upload the source code at the end of every video. But basically, these are just copy and pasting. Okay, let's switch back to our want to read book activity. And let's initialize our recycler view. Once again, I think I can copy some of the logic from the already read book activity. Let's copy all of these. But this time, instead of this get already read books, I'm going to say get want to read books. This one. Let's also take care of the back stack. I'm going to copy this whole method from the already read book activity. You may be wondering why I'm copying pasting why I have created four different lists. Later on, we will see some minor differences between these four different lists. Okay, now that we have created this activity, let's navigate the user to want to read activity from inside our book activity. That's all we need to do inside this handle want to read books method. Let's quickly create the other two. In order to save your time, because it was just copy and pasting, I cut the part that I wrote these two methods. But let's quickly take a look at them. So first of all, this handle favorite books, you can see that the book is final, we are getting the array list. We are checking that this book exists in our favorite books. After that, if it does exist, we are going to deactivate our button. But if it doesn't, we are setting an on click listener, if adding the book into our favorites, our list is successful, we are showing a toast message, and we are navigating the user to favorite activity, which I just created. I've been sure that in a minute. But in case if something wrong happens, we are showing a toast message, just like we did for already read books. Besides that, the same thing happens inside this handle currently reading book, you can see that basically the logic is the same, we just changed the name. Also, beside that, I've added two more methods inside my utils class, this add to currently reading book, and add to favorite. Once again, you can see that we are returning a Boolean beside that I've created two new activities, this currently reading activity, which once again, we are initializing our recycler view and its adapter. And we are setting the data in our adapter by using utils dot, that method that we have in our utils class, we are also taking care of this on back pressed button. Besides that, we have created this favorite activity, which you can see the code is a lot like each other. And also for the layout points for these two activities, if you take a look at them, I only have a recycler view in each one of them. I just cut the process to save your time. But if you want to check the source code, please do that, I will upload the source code at the end of every video in this section on the links that you can see on the screen. So feel free to check that if you need, but in here, let's quickly run our application. And let's see if everything works fine. Let's go to our book activity. And let's add this book to one of our array lists. For example, let's add this one to our favorites. The book has been added, we are navigating to the favorite activity. If you press this back button, we are navigating back to the main activity. Let's see our favorites from here. But I didn't set the click listeners for these buttons, I will do that. Let's see our books once again. And let's add this one q 84 to our, I don't know currently reading books. It seems like we have added it successfully. Okay, I think that's enough for this video. In the next video, we are going to work on showing our card views. I'm talking about this book card view, differently in different activities. So for example, inside this all books activity, we can see this card view, we can expand that in different lists, for example, inside the favorite books list, we are going to add some actions, for example, to text views. So that by clicking on them, we remove the book from the list, we are going to show that for the books that are inside our list. But we are not going to show that inside the all books activity. And at the same time, we are going to use only one adapter. So that's one thing that we are going to work in the next video. Besides that, if we had time, we will work on this about in here. Basically, we are going to show some dialogue message and we will see how we can show a dialogue. Okay, see you in the next video. In this video, we are going to create a delete button in our card view, in which we'll be available in all activities beside the all books activity. Let's see how we can implement that functionality. I'm going to add my delete button inside this expanded version inside the second relative layout inside the list item book dot XML file. So if I expand this relative layout and change its visibility to visible for now, I'm going to add the delete button somewhere beside this up arrow, I'm going to place it in here. So for that down in here, after my image view, after this btn of arrow, I'm going to say text view, wrap content and wrap content for the btn height. For the text, I'm going to say delete. Let's move it to below our short description. Let's say layout below. And let's address our txt short description. After that, I'm going to move it to the left of this up arrow button. So let's say to a start off ID btn of arrow, let's quickly add a margin, let's say margin and and I believe seven DP would be fine. Let's also change its color to a red color. Let's quickly define a color in our color resources inside this color resources. Let's copy this one. And let's create a new one. I'm going to change its color to red. And for its value, let's select one of these two, I'm going to select this one. But I think this one is a pink color. So let's change the color to pink. Next, in our list item, book that XML file, in our text view, I'm going to say text color. And I'm going to change it to my pink color. Let's also give it an ID. I'm going to say btn delete. Besides that, let's change its visibility to gone. Later on in our adapter, we will change this visibility if it was necessary. Okay, we are almost done with our card view. Let's just change the visibility of this expanded view to gone once again. So in here, I'm going to change this one to gone. And we are done with our layout file. Let's go to our adapter. And let's pursue the code from there. So in our books recycled view adapter, if you remember inside on bind view holder method, we are checking that if we should expand the card view or not, I'm talking about this if statement in here if books dot get dot is expanded. So inside this if case, I'm going to check that if I'm inside the all books activity or not. If I am inside the all books activity, I'm not going to show the delete button. But in other activities, I'm going to show that. For that, I'm going to add one more variable inside this adapter glass above in here. After the context, I'm going to add a string. Let's say private a string, I'm going to name this string parent activity. I'm going to receive this string by the constructor. So I'm going to delete this constructor and create it once again. This time, let's select the context and the string at the time of initializing my recycler view adapter in different activities. I'm going to say that which activity is calling this adapter. For example, if it's the all books activity, I'm going to pass all book. If it's others, I'm going to pass the correspondent text. After receiving this string down in here inside the on bind view holder method, I'm talking about this if case in here, I'm going to check that what that text is. So I'm going to say if parent activity dot equals, let's pass some text in here. For example, let's say all books. It's better to use constants in here. But just for the sake of simplicity, I'm going to pass my text. If the parent activity that calling this adapter is the all books activity, we are going to change the visibility of our delete text to gone. So let's say holder, but I believe we haven't instantiated our delete text view in our view holder class. Let's quickly do that. So down in here, inside this view holder, I'm going to define my delete text. So let's say private text view. Let's name it BTM delete. And also after that inside the constructor, let's instantiate it. For example, down in here, I'm going to say BTM delete is equal to item view dot find view by ID or dot ID dot BTM delete. Now that we have this element in our view holder class, we can have access to it inside the on bind view holder method. So in our if statement, I'm going to say holder dot BTM delete dot set visibility, let's say gone. Let's write the other cases. For example, let's say else if if our parent activity is equal to already read books. If that's the case, we are going to delete this book from the already read our list. Instead of this if statement, you can also create a switch statement. First of all, I'm going to write the whole if statement. And after that, we will write the logic for each case. Let's say else if parent activity dot equals, let's say one to read. The other case would be else if parent activity is equal to currently reading. We have one more case, let's say else, the else case would be a favorite activity. Now let's write the logic for each one of these cases. For example, if it's the already read book activity, I'm going to set an on click listener for this BTM delete. So let's say holder dot BTM delete dot set on click listener, let's say new on click listener. And inside this on click method, I need to delete the book from my array list. Once again, I'm going to keep all my interactions to my static array lists inside the utils class. So I'm going to write another method inside that utils class. Let's quickly go to that class. And down in here after everything, let's say public Boolean. Once again, you can see that the return type of this method is a Boolean. I will talk about that in a second. Let's say remove from already read. Let's also receive a book. And after that inside the method, let's return already read books dot remove. And let's pass our book like the add method on our array list. This remove will also return a Boolean. If you want, you can check the documentation by pressing down the control key and clicking on this remove, you can see the guideline in case if we remove this item from our array list successfully, we are returning true, but otherwise we are returning false. We can use this Boolean in order to make sure that we have removed the book successfully. Let's go back to our adapter. And in here, let's say if utils dot get instance dot remove from already read book, which we need to pass our book by saying books dot get position. If that was successful, we are going to show a toast message. Let's say book removed, but instead of the book, I'm going to pass the name of the book, which I can say books dot get position dot get name. Let's say plus removed. Also, after that, we need to notify that the data set has been changed because we want to refresh our recycler view. So we can say notify data set changed. But in the else case, let's just show a toast message. Let's say something wrong happened, please start again. We have write the logic for removing a book in case if the parent activity is already read. But now that we have changed the constructor of this adapter, probably we are going to see some errors in our application. Wherever we have instantiated this adapter, we are going to see some red errors. For example, if we go to our all books activity, you can see that in here we have an error. And that's because now our constructor needs two elements, the context and also the parent activity, which is a string. For example, inside this all books activity, I can say all books. Let's see other places that we have instantiated our adapter. For example, already read books activity. Let's pass already read. Notice that these strings should be exactly the strings that you have passed inside your if cases. Okay, let's go to currently reading activity. And let's pass one in here as well. Let's quickly do the same thing for the other two activity. Okay, let's close all of these extra points. And let's test our application. And let's see if we can successfully delete the books from different activities. Remember that we have written the case only for this already read. And the others shouldn't work. Before I test my application, I'm going to add one more line in here because it seems like I have forgot something. So in case if the parent activity is already read activity, first of all, we need to change the visibility of our between delete, I can say holder dot between delete, let's say dot set visibility, and let's pass visible. Let's run our application. Let's go to our all books activity. In here, if we click on this down arrow, we shouldn't see this delete text. Let's try that. As you can see, we cannot see any delete that seems to be good. Let's go to our activity. And let's try adding this book to our already read list. It seems like it has been added successfully. If we click on this drop down, we can see that this time we can see the delete button. Let's try clicking on that. It seems like we are getting a crash. Let's open our lock at and let's see what the crashes. It seems like I've lost the error. Let's run the application once again. And let's try everything one more time. See all books, book activity, add to already read list. And let's try deleting it once again. It seems like the error is happening online 78 of our recycler the adapter. Yes, the problem is that, first of all, we are removing this book from our list. And after that, we are trying to get the book from our list. For that, we are getting an index out of bound exception, because this book no longer exist in our books area list. What I can do is that I can save the name of book before this button before this on click listener, or alternatively in here, I'm just going to say book removed. Let's delete this. And in here, let's say book removed. Let's try running the application one more time. And let's see if you still see the exception. All books activity, book activity, add to already read list. This time, let's try deleting this book. It seems like we have removed the book successfully. Also, we have refreshed our recycler view. This empty screen is not a good user experience, we probably should show some text message in case if we don't have any book in our list, we will fix that later on in future videos. But for now, let's go back. I also don't like this behavior that we are instantly removing the book. For example, in here, if we try to add a book, the user might press this delete on one table, for example, by accident, before deleting the book, we also need to get some confirmation from the user. I think that creates a better user experience. So in here, after clicking on this delete button, I'm going to show a dialogue message to the user. And I'm going to ask that if he or she is sure of deleting this book, let's see how we can create a dialogue. So in here, before removing this book, inside the on click listener, I'm going to delete this whole if statement. And here is how you can create the simplest alert dialogue, you can say alert dialogue, this one that comes from Android x dot app compact, let's say that builder, let's name this builder is equal to new other dialogue dot builder, this builder needs a context in which I can pass my m context. After that, I can set some options for this builder. For example, I can set a text, let's say builder dot set message, this option. And in here, we need to provide some message. For example, let's say, are you sure you want to delete this book? After that, I can also set some buttons for my other dialogue. For example, I can say builder dot set positive button, you can see that we have negative button and positive button. For example, for the positive button, let's say yes, we also need an on click listener, let's say new on click listener, this dialogue interface dot on click listener. And what would happen if the user press on this yes. And here is the place that we need to remove the book from our array list. I can say if utils dot get instance dot remove from already read, let's also pass our book books dot get with an index of position. If that was successful, let's try a toast message. Let's say book removed. After this toast message, we also need to notify that the data set has been changed. Let's also set a negative button for our dialogue. For example, I can say builder dot set negative button. Let's say no. Once again, we need an on click listener dialogue interface dot on click listener. Inside this on click method, I'm not going to do anything because I want to dismiss the dialogue in case if the user pressed this no. So we don't need to do anything, we just need to override this on click method. Let's finish setting a negative button. After creating your builder after setting the message, the positive and negative button, you can create and show your builder. For example, you can say builder dot create dot show. Let's test the application and let's say if everything works fine. Let's go to our all books activity. Let's add a book to our already read list. And let's try removing this book. So if I press on this delete, we can see that we are seeing this alert dialogue. Are you sure you want to delete one q 84? Let's say no. As you can see, even though we didn't write any code inside this on click method, we have dismissed the dialogue successfully. Let's press the delete once again. And let's say yes this time, as you can see, the book has been removed successfully. That alert dialogue creates a much more better user experience. Okay, now that we have write the logic for already read books list. And let's quickly write for the others. I think I can copy and paste a lot of these codes. Before copy and pasting, we need to go to our utils class, and add some methods. For example, for removing from different lists, let's say public Boolean, remove from one to read. Let's also receive a book. You can see that the logic is exactly the same. I'm going to cut the process of writing the logic for the other two lists, you can see that it's exactly the same. Okay, now let's go back to our adapter class, and let's copy the logic for this already read case. I'm going to paste it for the other three cases. As you can see, the code is exactly the same, we just changed the name of this method, remove from favorites, remove from currently reading, and remove from one to read. Besides that, I'm going to create an on click listener for my different buttons in main activity. Because I'm going to navigate the user to each one of the activities by clicking on the buttons. Okay, let's test our application. Let's go to our all box activity. Let's add this one to currently reading list. We are navigating to the currently reading list. Let's try removing this, let's say delete. Once again, you can see that we are seeing the dialogue, let's say no. This time let's say yes. It seems like the book has been removed successfully. If we go back and if we check our currently reading books, you can see that the list is still empty. Let's quickly try for others. One to read added successfully, delete. Sorry, I clicked on the card view and not on the delete button. Let's go back and let's try deleting it. Yes, it has been deleted successfully. See all books. Let's add it to our favorites. Let's try deleting it. Let's say yes. It seems like we have an error when we try to delete the book from our favorite lists. If we open our lock cat, you can see that something wrong is happening inside our utils class at line 116. And yes, this is the error. In here, instead of removing the book from my favorites list, I have recalled this method. Sorry about that. Let's say favorites. Remove. Let's try it once again. Let's add a book to our favorites list. And let's try removing it. Let's say yes. It seems like it has been deleted successfully. Okay, I think that's enough for this video. In the next video, we are going to see how we can show a website in Android applications. Okay, see you in the next video. In this video, we are going to work on this about button by clicking on this button, we are going to show some dialogue in which inside that dialogue, we are going to show some detail about the developer of this application and also the application itself. Besides that, we are going to give the offer to check our website by clicking on a button, the user will be navigated to our website. Let's quickly see how we can implement that. For showing the dialogue, like the previous video, we can use the alert dialogue, we are going to use that in here. But I also need to say that you have other options as well. For example, you can create your own customized dialogue. We will talk about customized dialogue later on in the course when we talk about fragments. But in here, we are just going to show a simple alert dialogue. Okay, let's go to main activity. And let's implement that functionality that I was just talking about. So down in here, inside the uncreate method, I can say btn about that set on click listener. Let's say new on click listener, we need to create our alert dialogue that builder object in here. Once again, I'm using the Android X artifacts. So import the right one. Let's say other dialogue that builder, let's name it builder is equal to new alert dialogue that builder, you know that we need to pass a context in here because we are inside the main activity inside this interface, we can pass main activity dot this. After that, we can set a title for our other dialogue builder, we can say builder dot set title, I believe is the name of the method. Let's pass the name of our application, I can say get strings. Let's say r dot string dot app name. After that, I can say builder dot set message. And let's provide a message. That's going to be our text. And after that, we are going to set two buttons for our dialogue. So let's say builder dot set negative button. For the negative button, I'm going to say dismiss. And after that, we need an on click listener. Sorry, I have a type in here. Let's say neo on click listener, dialogue interface dot on click listener. Once again, inside this on click method, we are not going to do anything because we are going to dismiss the dialogue, we just need to implement this on click method. After that, let's set a positive button for our dialogue. Let's say builder dot set positive button. Let's say visit. Neo on click listener. And by clicking on this visit text, we are going to navigate the user to our website. For now, let's just add it to do in here, we will do that later on. After creating the dialogue, we can show it, we can say builder dot create dot show. Also, before I run my application, I'm going to say that you have all sorts of functionalities with this builder. For example, if you take a look at the available methods, we can see that you have all sorts of options. For example, you can set an icon for your dialogue. Beside that, you can set that if your dialogue is cancelable or not by saying set cancelable, let's say that cancelable this one, you can pass a Boolean. If the dialogue is not cancelable, the user cannot dismiss the dialogue unless he or she clicks on one of our buttons. I'm not going to talk more about these functionalities in here because when we talk about customized dialogue later on in the course, you can see that we have a lot more functionalities. Okay, let's run the application and let's see if we can see this dialogue. Let's click on this about button. Right now, I can only see this visit button. And that's because I've made a mistake in here. Both of my own click listeners are for this set negative button. I need to change this one to set positive button. Sorry about that. Let's run the application one more time. Once again, let's click on this about button. This time you can see both of the options. Also, if you don't get my point about being cancelable, cancelable means that if you click on anywhere outside of the dialogue, for example, in here, your dialogue will be cancelled. If you set your dialogue to not to be cancelable, you cannot cancel it by clicking on anywhere on the screen. You just need to click on the dismiss button. Okay, let's also try this dismiss in here. We can dismiss our dialogue successfully. And by clicking on this visit button, because right now we don't have any code. Once again, our dialogue should be dismissed. Okay, let's write the code to navigate the user to our website. In order to navigate the user to my website, I'm going to create another activity in my package in Java folder in my package, let's say new activity, empty activity. Let's name this activity website activity. In the layout file of this activity, I'm going to put only one element. And that element is going to be a web view. Let's search for web view in here, you can see that we have this web view option. Let's drag that. And let's change its width and height to match parent. Let's also give it an ID. I'm going to simply call it web view. That's all we need in here. Let's switch back to our Java file. And in here, let's initialize our web view. I'm going to define my web view as a member variable as a private member variable inside this activity. And you will see why I'm doing this. Let's say private web view. Let's name it web view down in here inside the uncreate method. Let's initialize that. Let's say web view is equal to find you by ID, or dot ID dot web view. After that, we can pass a URL to this web view. For example, if we want to show Google, we can say web view dot load, load URL, and we can pass our URL. Let's pass the URL of Google.com. And from the positive button of our dialogue, let's navigate to this website activity. In here, I can say intent intent is equal to new intent. For the context, let's pass main activity that this for the destination website activity that class, and we don't need any flagging here. Let's just say start activity. And let's pass our intent. Let's run the application. And let's see if we can load Google successfully. Let's click on this visit. As you can see, we are navigating to another activity, but we are not seeing Google.com. And that's because in the URL, we need to say HTTPS because Google has SSL certification. So let's quickly modify our URL in our website activity. Instead of HTTP, I'm going to say HTTPS. Let's run the application one more time. Let's click on this about, let's try visiting. As you can see, another application has been opened. In this case, we are opening Chrome because Chrome is the default browser in this emulator. This is good, but you can do better. You can open the website in your own application and don't send the user to another browser. In order to do that, you need to set a web view client on your web view. Let's quickly see how we can do that. So in here, I can say web view dot set web view client, this one, and we need to pass a new web view client, new web view client. This time, if we run our application, we should open the Google.com in our application and not in another browser about visit. You can see that this time we are inside our own application, you can see the name of application above in here. Let's try searching something in here. For example, let's try searching for Android. If we try to go back one page right now, if you press on this back button, we are going to go back to the main activity. This is not a good user experience, you may want to navigate the user one page back and not destroy the whole activity. If you want to do that, you can override the unback pressed method in here by pressing control all and searching for unback pressed. We have seen this method in previous videos. Let's override that and we need to do some modifications in here. And here is the reason why I've defined this web view as a member variable, because I want to have access to this method inside both on backpress method and also on create method. So what I can do in here is that I can say if we view dot can go back this method, you can see that the return type is a Boolean. If our web view can go back, let's say, web view dot go back. But in the else case, we are going to do the super statement. So I'm going to cut this one. And I'm going to put it inside this else case. This in here means that whenever we are pressing the back button, if our web view can go back one page, then go back. But if not, do whatever you are doing with your back button, for example, destroy the activity and go to your main activity. Let's try this. Let's visit Google once again. And let's search for something. For example, may code. This time, if we go back, you can see that we are going back one page and we are not destroying the whole activity. There is also one more thing that you can enable on your web view. You can enable JavaScript if you want on your web view as well. Most modern websites use JavaScript and you can enable it in here if you want. You can say web view dot get settings this one dot set JavaScript enable this method, you can pass through or false in here. For example, let's pass through. But you can see that as soon as I pass through, I'm getting a warning. The warning says that enabling JavaScript is a security issue. And it can cause vulnerabilities to your application. So enable it carefully. Okay, now that we have enabled JavaScript, let's try running our application one more time. And let's see if we can see any difference. We shouldn't see any difference about visit. We can see Google in here and you can search for whatever you want. When you are using web view in your application, you have all sorts of functionalities. In fact, a lot of applications are based on web view. They are basically some website and they are showing some web view in their application. So if you want to dig into that area, make sure to learn web view well, you have all sorts of options when you are working with web view. But in this course, we are going to use a web view this much and we are not going to go further. In here, I'm going to make my website activity reusable because I may want to show different websites in my application. For that, I'm going to get an intent in here and I'm going to receive the URL with that intent. So that I can show multiple websites. So before defining our web view before instantiating it, let's get the intent. Let's say intent is equal to get intent we have seen this before. After that, let's make sure that our intent is not null. So let's say if null is not equal to our intent, let's receive the URL, let's say a string URL is equal to intent dot get a string extra this method. And let's pass a key for example, let's say URL, let's move this logic to inside our if statement. Then I'm going to pass this URL to this load URL method. So instead of this hard coded text, I'm going to pass URL. Next, in different part of my application, when I create an intent and navigate the user to this website activity, I'm going to also provide a URL. For example, in here inside this on click method of our dialogue before starting the activity, I'm going to say intent dot set extra or put extra was the name of the method. Let's say URL for the key. And let's pass a URL. Let's remove this to do from here. As a suggestion in your application in your book activity, you may want to provide a link for more information about your book. Let's quickly go to activity book dot XML. For example, somewhere in this layout, you may provide a link for your book. For that, you also need to change the model of your book and provide a URL for that and navigate the user to some website if you want to give the user some more functionalities. But we are not going to do that in here together because that's really simple. And I believe you can do it by yourself. Okay, I think that's enough for this video. It was a relatively short video. In the next video, we are going to see how we can define some animations. For example, right now, when we navigate between different activities, we only have a basic pop up animation. In the next video, we are going to see how we can create a better animation for navigating between different activities. See you in the next video. In this video, we are going to talk about animations in Android. And also beside that, we will talk about how to enable the up button. To be honest with you, we are not going to focus on animations that much yet in the course. And after this video, you will know my reason. Okay, let's see how we can implement a simple animation in our application for navigating between different activities. In order to create a simple animation file in our project inside the app folder inside the resources folder, we can create a new resources directory by clicking on this new Android resource directory. From this resource type, we can select anim the first option in our list. Let's keep the name anim and let's create our resource directory. Now if you take a look at your resources, you can see this anim folder by right clicking on that you can create a new animation resource file. I'm going to name this file slide in. Let's create our file. You can see that the root element right now is this set basically set means a set of different animations. For example, you may have a horizontal animation beside that you may want to have a rotation animation, you can include them all inside this set. But in here we are only going to implement one animation. And because of that, I'm going to change this root element. I'm going to change it to translate. Whenever you want to have a simple horizontal or vertical animation, you can use this translate in this application, we are going to slide our activity to the next activity. So in here, we need a horizontal animation. Let's see some of the attributes on this translate element. The first one that I'm going to talk about in here is called from x delta, this one, you can see that similar to that we have this from why delta, you can guess the meaning of each one of these when we use the first one from x delta, it means that we are going to define the horizontal place of our animation, where do we want to start our animation in a horizontal axis. So let's say from x delta, in here you need to define the first horizontal place of your application. For example, you can pass zero pixel. This is just a normal pixel. And it's going to be a started from the beginning of your screen. Besides zero, you can pass zero percent, which will start the animation from the beginning of your element from the beginning of the bits of your element. So this percent in here means relative to the bits of your element. If you pass percent P, you are going to start your animation from the zero pixel relative to the parent of your element, not to the bits of the element. So for example, if we have a button that we are going to apply this animation on that this zero percent P in here means that we are going to start our animation from the beginning of its parent layout, you can enter any number that you want in here from zero to 100. Beside that you can also enter negative numbers. For example, in here, I'm going to say negative 100. The next attribute that we are going to take a look at in here is called to x delta. Once again, you can see that we have two attributes to x delta and to y delta, you probably can guess their meaning to x delta means the destination in the x axis and to y delta is the destination in the y axis. In here, we are just going to slide our activity. So we are going to use this to x delta, you can put whatever number that you want in here, but I'm going to say zero percent P. Beside these two, you can also define a duration for your animation as well. For example, in here, we can say duration, you can see that it's not working, you can type it manually, you can say Android column duration, let's say is equal to and we need to pass our duration in milliseconds inside these double quotations. For example, I want to set the duration of my animation to 1000 milliseconds. So to have a quick review in here, our animation is going to start from the negative 100 pixel relative to the parent layout. And we are going to end in the zero percent relative to the parent inside the x axis. And the whole animation is going to take one second. Let's quickly create another animation as well. Once again, by right clicking on our animation folder, let's say new animation resource file, let's name this one slide out. I think we can change the root element from here as well. Let's change this one to translate. And let's create our XML file. For this translate element, I'm going to define the same attributes, but I'm going to change their values. For example, I'm going to say from x delta, this time I'm going to pass zero percent P. Let's say two x delta. This time let's pass negative 100% dp or 100% p sorry about that. And let's also define a duration Android column duration. Once again, let's say 1000 milliseconds. Okay, now we have two different XML files for our animations. How do we implement them in our activities? Here is how you can do that. For example, let's go to our all books activity. Inside the uncreate method of this activity before everything we can say override pending transition. You can see that this is an inner method inside every activity. This method requires two animation files. The first one is the interanimation and the second one is the exit animation. Let's provide them for the first one, I'm going to say r dot anim dot let's say slide in for the second one, I'm going to say r dot anim dot slide out. Let's run our application and let's see what our animation looks like. If we try to go to all books activity, you should see the animation. It's not that pretty, but it is what we created. But in here, if I try to go back, for example, by pressing this back button, you can see that we are still seeing the default animation. If we want to apply our own animation, we can do something like this. In our activity, we can override a method by pressing control plus or alternatively by typing the name of the method, we can override that method. The name of this method is finished. So this method is going to be called whenever we are going to finish our activity. Let's call that after the super statement. Once again, we can use this override pending transition. Let's say override pending transition. This time, I'm going to switch these two animations. For example, for the first one, I'm going to pass a slide out. And for the second one, I'm going to pass a slide in. So let's say r dot anim dot slide out. And for the second one, r dot anim dot slide in, let's run the application once again. And let's go to our all books activity. This time, if we try this back button, you can see that we have some sort of animation. It's not perfect, but it is what we have created. Honestly, I'm not a designer. I'm not good at animating my applications. But probably you can do better than me. Just play around with these numbers inside your XML files. And you will find animations that you are looking for. But right now, if we try to go to another activity, for example, this already read books activity, you can see that we are still seeing the default animation. If you want to apply your animation on this activity as well. Once again, inside this activity, you can overwrite the pending transition. Or alternatively, if you want to apply the animation on your entire application, you can change the style. Let's quickly see how we can change our style. So inside our values folder inside the styles dot XML, in here, I'm going to create another animation. Sorry, I'm going to create another style. Let's say style, I'm going to name my style custom animation. And for its parents, I'm going to say at Android column style forward slash animation dot activity. So this is going to be our parent inside this style file, I'm going to define some items. For example, for the first one, I'm going to name it activity open interanimation, this one. And for its value, I'm going to pass my own animation, I'm going to pass this slide in, I can say at any slide in, I need to create three more items. The next one is going to be activity open exit animation, this one, this time for its value, I'm going to say at any slide out, let's also create the exit animations item activity close interanimation, this one, let's pass a slide out once again at any slide out another item, activity close exit animation. This time, let's pass our slide in. Now that I have created this style, I can pass it as an item inside this app theme style. So in here inside this app theme style, I can say item for its name, I'm going to say Android column window animation style this one. And for its value, I'm going to address this style, I'm going to say at style forward slash custom animation. Now that we have changed our app theme style, we can delete that override pending transition method from inside our all books activity. So let's delete this one, and also beside that, let's delete this whole finish method. Let's run our application one more time. And let's try going to different activities. For example, this currently reading books, you can see that we are seeing some sort of animations. Let's go to this see your favorites, animation. My emulator is low on a speed. So for that, you can see some frames. Let's go to our all books. Once again, we can see the animation to our book activity. It seems like our animation have been applied successfully. There are much more concepts and elements when creating different animations, you can probably design a simple game with Android Studio by just using these animations. But I'm not going to talk about them in here. The reason that I'm not going to talk about them in here is that because the Android team are releasing a much better solution for animations. That solution is called motion layout. And right now it's in beta phases, I believe it will be released in few months, probably in the spring of this year, in the Google IO conference, or later on this year in Android developers conference, either way, when it's released on a stable channel, I will create one or more videos about that I've seen and I've heard a lot of good things about that. Let me quickly show you some links. If you come to this webpage at Android developers official website, you can see some of the features of motion layout together with the motion editor, and you have all sorts of functionalities and all sorts of easiness when you are designing your animations. Honestly, I think that they are bringing after effects inside Android Studio. So for that, I'm not going to talk about animations in here. Instead, I'm going to wait for the motion layout. Motion layout is going to come with constraint layout 2.0. And that constraint layout is still in beta phases, we just need to wait few more months. Okay, let's move on from animations. The next thing that I'm going to do inside my application is that I'm going to enable an app button in my activities. For example, inside this all books activity. But before I do that, I'm going to delete my animation because I don't like it. Let's just comment this line. And let's close all of these extra files. So in order to activate your app button inside the uncreate method of your activity, you can say get action bar, or to be precise, get support action bar dot set display home up enabled. This option in here, if you pass through, you will activate your app button. Let's run the application and let's see what does that look like. If we go to our all books activity in here, you can see this back arrow, which is our app button, right now, it's not going to do anything because we haven't defined the functionality. But if we want to navigate the user back to the main activity, we can do something like this, we can override the on option item selected method like this, I'm talking about this method, you can see that we are getting a menu item, and we can use that item in here, we can create a switch statement. Let's say switch on item dot get item ID, and let's create our cases. Let's say in case it's android dot r dot ID dot home, it means that we are going to click on our app button. This is the ID of that button, we are going to navigate the user back to the main activity. In here, I have two options, I can create an intent and navigate the user back to the main activity, or I can call the on back pressed method. Let's call that. So this in here means that do whatever you are doing when the user clicks on the back button, basically the up button and the back button in here are going to have the same functionality. But of course, you can do whatever you want, you can navigate the user to another activity. Let's also add a break in here. And let's create a default case. In the default case, I'm not going to do anything, I'm just going to break out of the switch statement. Let's run our application and let's see if it's going to work. So if we go to our all books activity, if we click on this up button, you can see that we are navigating back to the main activity. I'm not going to enable it in other activities, I just wanted to show you how you can implement this up button. Okay, the next minor thing that I'm going to do in here is that to change the name of my application this title in here in different activities. For example, I'm going to change it inside this all books activity to all books. In order to do that, you can go to your manifest file. And in here for different activities, you can define different labels. But I'm going to create my labels inside the string resources. So inside my values folder inside strings that XML, I'm going to define few more strings. The first one is going to be named activity all books. And its value is going to be all books. Let's define few more. After defining these strings, you can go back to your manifest file. And inside every activity tag, you can set a label attribute. For example, for this favorite activity, we can say label, let's search for favorite activity. Let's do the same thing for the other activities. Let's run our application. And let's see if we have changed the labels successfully. In the main activity, we are still seeing this my library, which is the name of our application. Let's go to our all books activity. You can see that the title has been changed. If we go to our book activity, you can see the book details. Let's go to already read activity. Once again, you can see the title has been changed. It seems like we have changed the labels in all of our activities. Okay, I think that's enough for this video. In the next video, we are going to work on our utl's class. Right now, we are using a static array list for our data, which is not resisted over the lifecycle of our application. In the next video, we are going to see my simple solution for persisting data, even if we restart our device, it is probably the last video of this section of the course. So make sure to don't miss that. Okay, see you in the next video. In this video, we are going to solve our problems with our data not being persisted. Right now, the problem is that we are using a static variables for our data. For example, when we add one book to one of these lists, that book will be added. But when we close our application, this array list will be cleared. In this video, we are going to solve that we are going to persist our data after the application is closed and also for that matter, after the device is rebooted. Usually in a real world application, you may want to use databases for situations like this. They have been designed exactly for this problem. They have been designed to persist our data. But we don't know anything about databases yet. Later on in the course, we will talk about databases, specifically, we will talk about SQLite database, and also its wrapper room database. But we also have another option that we are going to use in here. That option is called shared preferences. The purpose of shared preferences is that to persist the data that is not structured. They are being widely used for the preferences of the user in your application. For example, if the user decides to use the dark theme with your application, you can save that preference in your shared preferences. But that's not all of the purpose of the shared preferences. As I said, you can save all of the unstructured data in shared preferences. In here in our application, our data is structured, we have a model called book. Besides that, we have all of these early lists, but we are going to manipulate our data and we are going to save them inside the shared preferences. By manipulate, I mean we are going to convert our Java classes and early lists to strings. And after that, we are going to save them inside the shared preferences. In another word, we are going to serialize our objects. And later on, when we get our data from the shared preferences, we are going to convert those strings to these array lists and books. That process is called deserializing. Okay, enough talking, let's see how we can use shared preferences. So if you remember from the previous videos, I have done all of my interactions with my array lists inside this utils class. And I've done that because of this exact reason, I'm going to delete all of my array lists, and I'm going to use shared preferences. So most of our changes are going to be inside this utils class. First of all, I'm going to define my shared preferences as a member variable inside this utils class. For example, down in here, I'm going to say private shared preferences, you can see that this is an interface that comes from Android dot content package. Let's name it shared preferences. After that, I'm going to initialize it inside my constructor inside this utils. Before everything, let's say shared preferences is equal to get shared preferences, but we cannot use this method because for that we need a context. For that reason, I'm going to receive a context via the constructor of this class. But notice that and because I'm going to receive a context in here, I need to change a lot of codes in my application. Wherever we have used this constructor, or for that matter, this instance and its method get instance method, we also need to pass a context. We will do that later on. So let's receive a context. Let's say context. And down in here, let's say shared preferences is equal to context dot get shared preferences. You can see that in here we need a name. This string is going to be the key for our shared preferences. Let's pass a name. For example, let's say alternate DB. DB stands for database. After that, after the key, you also need to pass a mode. For example, the mode that I'm going to pass in here is this mode private. We have other modes as well. But if you want your shared preferences to be specific to your application only, you can use this mode private or to be precise context dot mode private. Now you have an instance of your shared preferences, you can use it however you want, you can put some data into it or you can get the existing data from your shared preferences. But right now, because I've changed this constructor, we should probably see some error inside the get instance method. Because if you remember in here, we are calling our constructor. For that inside this get instance method, I'm going to also receive a context. And I'm going to pass it to this constructor that will fix our error for now. Next, I'm going to change this init data method. In here right now, we are saving our books inside this all books area list, which is a static array list. But let's see how we can use shared preferences. So in here, first of all, I'm going to define a new array list. Let's say array list of books. Let's call it books. Is equal to new array list. And after that, I'm going to add my books to this new array list and not to the static array list. So let's say books dot add. And similarly for the second book. Now let's see how we can add these books are released into our shared preferences. So down in here, I can say editor, this interface shared preferences dot editor, let's name it editor is equal to our shared preferences instance dot edit, you can see that this edit method returns an editor instance. After that, with the help of this editor, we can say editor dot for example, put a string. You can see that our options in here are very limited. We can only store primitive data types plus the string. But how do we store our Java classes? For example, this book class and similar to that our array list inside these shared preferences. I said that we are going to convert our books array list into a string. Let's see how we can do that. The best option is to convert your Java classes and array lists into a JSON file. If you don't know anything about JSON, don't worry, we are going to talk about that later on in the course specifically, we will talk about it in the networking section. Basically, JSON is a way of passing data between different applications, regardless of the language. In here, we are not going to talk further about JSON. We are not going to work with JSON files. We are going to handle the job to a third party library. So basically, we are going to serialize and deserialize our objects with the help of another library. Let's quickly implement that library into our project. The name of this library is JSON. If you search for JSON, you can see that the first link from GitHub is the link of this library. As you can see above in here, it has been developed by Google. Down in here somewhere, we should see the dependencies. We are using Gradle, not Maven, so we can copy the dependencies from here. Let's add it into our project. Inside the build.gradle module app, let's add it somewhere and let's sync our project. After adding it in our utility class, first of all, let's create an instance of this JSON object. We can say JSON. We can see that it's coming from com.google.json package. Let's name it JSON is equal to new JSON. After that, if you want to convert an object to JSON, you can say something like this. You can say JSON.JSON. We have multiple versions of this JSON method. You can see that each one of these versions receive different arguments. For example, we can simply pass our books. So this way we can have a string. Let's simply name it text is equal to JSON.2JSON. So this way we can serialize our books object. With the help of this JSON, we have converted our array list into a JSON file. Now let's see how we can add this text into our shared preferences. I'm going to delete this one. I'm going to say editor.put a string. First of all, we need the key. I'm going to use constants for different keys. And I'm going to define them above in here as member variables. Let's say private static final string. Let's name it all books key. Let's initialize it to all books. After that down in here, inside this put a string method, we can pass that key. Let's say all books key. And after that, we need our value, which I'm going to say JSON.2JSON. And let's pass our books object. As simple as that, with the help of this editor, we can put this array list into our shared preferences. But there is one more step and we need to apply the changes on this editor. For that, we have two options, we can say editor dot apply this method, or the alternative that we are going to use in here is dot commit. The difference between the apply and commit is shown in here inside this highlight. So whenever you use apply, the changes inside your shared preferences will be applied in a background thread. And you will not block the main thread. I suggest that in most cases, you use apply because you don't want to block the user from interacting with your application. But in here, our data is really small, and we are not going to block our user interface for long. And beside that, we need the result of this applying immediately. For that, I'm going to use this commit. Later on, we will see that how we can use callbacks in order to communicate between two different threads. And then we can use apply but in here because we need the results instantly, and we haven't talked about callbacks. I'm just going to simply use this commit method. Okay, that's all that we need to know in order to put some string into our shared preferences. Now that we have successfully initialized our data, let's see how we can call this init data method. So inside the constructor, if you remember in here, we are calling this init data. But before that, we are using this all books are a list in order to make sure that we haven't defined our books previously. As I said, I'm going to delete all of these are a list. So I shouldn't use this all books are a list. For that, I'm going to check my shared preferences and see if I have any initial data in the shared preferences or not. If I don't have any initial data, I'm going to call this init data method. But if I don't, I'm going to skip to the rest of the code. Okay, let's see how we can get our data from our shared preferences. The right place to do that is inside the get all books method. Let's quick insert for that, you can see that we have this method in here. And we are simply returning all books are a list. Instead of that, I'm going to get the data from the shared preferences. Let's say array list of different book. Let's name it books is equal to in here. First of all, I'm going to get the text from the shared preferences. And after that, with the help of gson library, I'm going to convert it to this books array list. So before defining this array list, first of all, I need to create an instance of the gson. So let's say gson gson is equal to new gson. After that, let's say array list of different books is equal to gson.from json. This time, we can see that similar to to json, we have this from json as well. In here, first of all, we need the text itself, which we are going to get from shared preferences. But as you can see, I'm not getting my shared preferences. And that's because when I've defined my shared preferences, I didn't define it as a static variable. And because of that, because we are trying to have access to a non static field from inside the static method, we are getting this warning. Let me type it completely to see the error. If you hover over this shared preferences, you can see that non static field cannot be referenced from a static context. For that, I'm going to delete this static keyword from the declaration of this method. We have used it so far in order to have access to this all books array list, but we no longer need it. So we can safely delete it. Now that we have access to our shared preferences, I can say shared preferences that get a string. Inside this get a string method. First of all, we need a key. The key is going to be our constant all books key, this one. And after that, we need a default value, which I'm going to say null in this case. So if we didn't get anything from the shared preferences, we are going to return null as this string. After that, the next item that we need for this from Jason method is a type token. The type token in here defines that to what object we are going to convert our JSON. In this case, we are going to convert our JSON to an array list of books. So we need to create the appropriate type. So in here, I can say type, you can see that it's an interface. Let's name it type is equal to near type token, this one, as the data type of this type token inside the diamonds, I'm going to say array list of different books. After that, we have a strange syntax in here. After the parentheses, I'm going to put a pair of curly braces. After that, a dot. And after that, this get type method, which you can see that will return a type. So let's use that. This is fairly a strange syntax, and we haven't seen it so far. You don't need to understand everything in here, we are just defining a new type token. You can copy and paste this one if you need. Basically, inside this type token diamonds, we are defining our object kind. And after that, we are using this dot get type method in order to have a type. After creating our type, in here inside this from JSON method, we can pass that. Now we are getting our books from the shared preferences, and we are converting it to an array list. After that, we can safely return books instead of all books. So now that we have changed this get all books method, we can call it from inside our constructor. Inside this utils, instead of using this all books, I'm going to say if null is equal to get all books, this method, if you remember, we had a lot of null potentials inside the get all books method. Let me quickly show you one more time. So for example, if we fail to retrieve this string from our shared preferences, we are going to get null. After that, if our type doesn't work, we are going to get null, which will be produced by this JSON library. So there are a lot of potentially null values. So make sure to take care of them whenever you call your method. So inside this constructor, I'm going to say if null is equal to get all books, I'm going to call this init data method. Let's remove this line of code because it's no longer necessary. And if you want to have a review inside this init data method, we are initializing our data. We are creating this books area list, and we are saving it inside the shared preferences. So the logic that we have wrote so far means that if it's the first time that the user is launching our application, if we don't have any books saved inside our shared preferences, then call this init data method and save some books. But if it's not the first time that the user is launching our application, just ignore this if statement. After initializing the initial data, I'm also going to initialize these other area lists as well. Because even if at the time of installing our application, these area lists should be empty, but we are using them inside different activities. And based on them, we are calling some methods. If these area lists are null, we are going to cause some exceptions. For that, I'm going to initialize all of these with some empty area lists. You can see that basically inside these if statements, we are doing the same thing for our static area lists. This time, we are going to do it for our shared preferences. So I'm going to do the same thing that I've done for my initial data. Instead of this already read books, I'm going to use get already read books. If you remember, we had such a method down in here, let's quickly find that we have this get already read books method. And we are simply returning our array list. This time, let's see if we have such a data in our shared preferences. Once again, I'm going to say gson. Let's say gson is equal to new gson. After that, let's define our type. Once again, we are using this interface, which is coming from the Java packages. So let's say type. Once again, let's name it type is equal to I think I can copy some of the code from inside this get all books method. Let's copy everything. We just need to change the key in here. Also, we need to remove this static keyboard because we no longer need that. Of course, removing this static keyboard is going to cause some problem in our application. For example, inside the already read book activity in here without initializing our utils, we are trying to call this method, which was fine when we have defined our method static. But it's not going to work right now, we will fix this later on. Okay, let's move on from this part. And let's go to our utils class. Inside this get already read books method, when we are trying to get a string from the shared preferences, we need to put another key in here. Let's quickly define some keys above in here. After defining these constants, we can pass them in different methods. For example, for this get already read books method, I can pass already read books and constant. Now that we have changed this get already read books method inside our constructor inside this utils, when we are going to initialize our already read books, we need to check that if it's null or not, let's say get already read books, this method, if it is null, we are going to initialize our shared references. Because I'm going to use my editor in multiple places, I'm going to define that outside of these if statements, for example, in here, let's say editor to be precise shared preferences that editor, let's name it editor is equal to shared preferences that edit. Then after that, inside this if case, we are going to edit our shared preferences. I can say editor that put a string for the key I'm going to use my key from above in here, this one, let's say already read books. And for the values, I'm going to pass an empty area list. I'm also going to use gson library. So let's define our gson above in here, let's say gson is equal to a new gson. After that, inside this put a string method, let's say gson dot to JSON. And as for the object, I'm going to say new area list of kind book. So this way, we are initializing our already read books as an empty area list inside our shared preferences. We just need to commit these changes, we can say editor dot commit. Let's do the same thing for the other area lists as well. For example, for this one to read books, we need to fix the get one to read books method. If you remember, we had such a method down in here. Let's copy everything from inside this get already read books method. I'm going to copy everything. And in here, let's paste them, we just need to delete this static keyboard. And also beside that use another key. Then after that, inside the constructor, we need to check that if this method is going to return null or not, let's say if null is equal to get one to read books, then we are going to initialize our want to read books area list. Let's copy these two line of code from here. And let's paste them in the second if case. We just need to change this constant. Similarly for the currently reading book and favorite books. Let's copy the logic from here. And paste them inside this get currently reading book method. Let's also delete this static keyboard. And let's change the constant. Let's do the same thing for this get favorite books method. Delete the static keyboard and change the constant. Let's minimize both of these methods. And let's go back to our constructor. Let's say if null is equal to get currently reading books, this one, let's copy this two line of code. And let's change the constant. Besides that, in here, let's say if null is equal to get favorite books. Once again, let's paste these two line of codes. And also let's change the constant. Okay, now we have deal with our constructor successfully, we have initialized all of our array lists. Let's see what else do we have inside this utils class. We have fixed all of these methods until down in here after this get favorite books. We also have this get books by ID method. Let's quickly see what we have in here. So basically, once again, we are using the all books array list in order to get some book by its ID. Instead of that, I'm going to get the books from my shared preferences. For that, I'm going to say array list of books. Let's name it books is equal to get all books. I'm going to use my method. After that, I'm going to check that if this books array list is null or not. Let's say if null is not equal to books, then let's put our for loop inside that if case. And also let's iterate through our books array list. That's all the change we need to do inside this get book by ID method. Now we are getting the book from our shared preferences instead of array list. After that, we have these add to methods and these remove from methods. Let's quickly fix this as well. Inside this method, we are returning the result of this dot add method, which we have called on our array list. This time, I'm going to connect to my shared preferences. So I'm going to say array list of different book. Let's name it books is equal to let's say get already read books. If you remember above in here, we have fixed that method. I'm talking about this method in here. And now instead of using our array list, we are getting the data from the shared references. Then inside this to already read method, we are going to use that. After that, we need to make sure that this books array list is not known. Let's say if no is not equal to books. After that, let's say if our books array list dot add, let's say book, if the result of that is true, then we are going to save this books array list into our shared preferences. As a reminder, this add method will add the book into our array list. And after that we'll return through if something wrong happens, it will return false. So after this check in here inside this if statement, we have successfully added the book into our list. Now we need to convert this books array list into a JSON file. And after that, add it to our shared references. For that, I'm going to instantiate a gson in here. Let's say gson is equal to new gson. After that, I'm going to instantiate my editor. Let's name it editor is equal to shared references dot edit. And after that, I'm going to first of all, remove the current already read books. And immediately after that, I'm going to put this new books array list. So let's say editor dot remove, you can see that beside put a string and get a string we have this remove as well. If you want to clear your shared preferences, you can use this clear method which will remove all of the data inside your shared preferences. With the key that you have provided above in here when you have created your shared preferences. I'm talking about this key in here this alternate DB, it will clear all of the data inside that shared preferences. But in here we are not going to clear all of the data we are just going to clear our already read books list. And we are going to update it with this new list. So let's use that remove method which requires a key. Once again, for the key, I can pass my constant already read books. After that, let's say editor dot put a string for the key once again, let's say already read books. And for the value, let's say json dot to json. And let's pass our books are a list. After everything, we just need to call dot commit method. If we reach to this point, we also need to return true, because as you can see, the return type of this method is a Boolean. If we reach to this point, it means that we have successfully updated our shared preferences. So we can safely return true. But in case if anything wrong happens in this process, we are going to return false, I'm going to do that after everything. Let's say return false. That's all we need to do in order to add a new book to our already read book list in our shared preferences. Let's copy this logic for the other methods. For example, for this add to want to read list, let's delete this return statement in here. And let's paste our logic. We just need to change this method. Let's say get one to read books. And after that, we need to change these constants as well. Once again, one to read books. Okay, let's do the same thing for the other methods. For this currently reading, let's change the name of our method to get currently reading books. And after that, let's change our constant. Let's say currently reading books. Let's minimize this method. And let's do the same thing for our last method for this add to favorite method. Let's say get favorite books. And for the constant, let's say favorite books. Okay, I think that's enough for this video. This video is getting a little bit long. But we also have these remove methods in which we are going to fix them in the next video. Besides that, we have a lot of problems in different part of our application, because first of all, we have changed the constructor of this utils class. And also we have removed the static keyboard from the declaration of some of these methods. We will fix those problems in the next video as well. Okay, see you in the next video. In the previous video, we have rewritten this utils class up until this remove methods. In this video, we are going to change these remove methods in order to get our data from the shared preferences, not the static area lists. Besides that, I said that right now we have a lot of problems in our application due to changes in this utils class, you can see some red warnings above in here, we are going to fix them in this video as well. Okay, let's change this remove from already read book method. First of all, let's delete this return statement. After that, let's get the already read book. Let's say array list of different book. Let's name it books is equal to get already read books. After that, I'm going to check that if this array list is null or not, let's say if books or if null is not equal to books. If that's the case, we are going to remove the book from this list. In here, you may think that you may write some logic similar to these ad methods. For example, inside this ad method, after checking that if our array list is null or not, we are using this ad method in order to add our new book. In here, you may want to do the same thing. For example, you may want to say if books that remove the book that we are receiving, you may think that this is going to work but it's not I have tried that actually. And the reason for that is because this book that you're passing to this method is different from the book that is inside your array list. The values are the same. For example, the name ID description and everything is the same for both of these books, but the reference is not for that you cannot remove your book display. Instead, I'm going to create a for each loop, let's say for book, let's name it be inside our books array list. After that, inside the for loop, let's say if B dot get ID is equal to this incoming books ID, book dot get ID. If that's the case, then we are going to remove this book. So this way, we are not checking the reference of these two objects. Instead, we are checking their equality by their ID. So if that's the case, we are going to say books that remove, let's say be, it's very important to pass be in here and not this incoming book. Or if you want to have the Boolean, you can say, if books that remove, let's pass B once again, if that's the case, we are going to update our shared references. Let's do that in here. First of all, we need an instance of our G song, let's say is equal to new G song. After that, I can say editor, let's name it editor is equal to shared preferences.edit. After that, I can say editor dot remove. First of all, we are going to remove this already read book from our shared preferences. For that, I need the key. Let's pass already read books. After that, I'm going to put the new books are a list, let's say editor dot put string for the key, I'm going to say already read books. And for the value, I'm going to say G song dot to Jason, our books are a list. After that, let's say editor dot commit in order to commit our changes. Also, the return type of this method is a Boolean. So we need to pass through in here after this editor dot commit. If we reach to this point in our code, it means that we have successfully removed the book from our shared preferences. So we can safely return true. But if anything wrong happens during this process, we need to return false, I'm going to do that after everything. We need to do the same thing for the other three remove methods. So let's copy all of these. And let's paste them inside this remove from one to read. We just need to change the name of our method in here to get one to read books. And also these constants. Okay, I think that's all the changes that we need to do inside this YouTube class. Let's quickly check everything. We have changed these remove methods, we have changed these add methods, we also have changed this get by ID method, we change the get their methods for our lists, we also change this init data method. And after that, we have changed this constructor, we no longer use these early list. So I'm going to comment them. Okay, now let's fix our problems in our application. I'm going to check my classes one by one. So in the project folder, inside the package folder, let's check our classes one by one, all books activity. First of all, we have this error in here, we are using this get instance. If you remember this get instance now requires a context, which I'm going to pass this, you can see that we don't have any much error inside this class. Let's go to the next one, already read book activity, because we have removed the static keyword from the declaration of this get already read books method. I'm going to fix that by calling the get instance method. Let's say you to start get instance, in which requires a context in which I can pass this. Okay, that's all the fix that we need to do inside this already read book activity. Let's go to our book class, because this is the model and we haven't used anything from inside the utils class, we don't need to change this one. Inside the book activity, we have multiple errors, you can click on these errors from this left pane in here in order to navigate to the errors. For example, in here, we need to pass a context. Let's pass this. Let's check the second one. Once again, in here, we need to pass context. The third error in here, we need to pass a context. But because we are inside this on click listener, we need to pass book activity dot this instead of this, let's see others. Inside this handle currently reading. Once again, let's pass this. Inside the on click listener of this ptn add to currently reading, we need to say book activity dot this. In here, we need to pass this. Also inside this on click listener of this ptn add to want to read, let's say book activity dot this. That's probably all of the changes that we need to do in our application. We just need to pass some context to our get instance method. Let's say this. And let's check the last one. Once again, we are inside the on click listener. So let's say book activity dot this. I think we have fixed all of the errors inside this class. Let's check the others inside the recycler view adapter from the beginning. We are inside the on click listener of our positive button of our other dialogue. If you remember inside this adapter, we have received a context by the constructor. So I can say m context. Let's check others. Once again, let's pass m context in here as well. m context. The last one that's here, let's say m context. Okay, it seems like we have fixed everything inside this adapter. Let's switch to currently reading activity. Once again in here, because we have removed the static keyboard. First of all, we need to say get instance, and we need to pass our context, favorite activity. Let's say you choose dot get instance. And let's pass this inside the main activity. I believe we have instantiated our utils. Let's pass our context. We have fixed the utils class, we shouldn't see any error in here. Let's go to want to read activity. Once again, we need to say utils dot get instance, and we need to pass this. I believe that was the last error in our application. Let's also check the website activity. We don't need to change anything inside this class. Okay, now that we have rewrite the logic for our application, let's test it and let's see if everything works fine. Our application is launching. That's a good sign. Let's go to our old books activity. In here, we can see our books. Once again, that's a good sign. Let's see if we can see the details of this book by clicking on this button. We are seeing them. Let's also go to our book activity. In here, we are seeing all of the details of our book. Let's try adding this book to one of our lists. For example, this one to read. It seems like we have added the book successfully. Let's see if we can see the details in here. We can see them beside that we can see this delete button. But here comes the difference between using static variables versus shared preferences. Right now, if we close our application and run it once again, we should see this book still in our wish list. Let's close the application and let's run it once again. And let's see if we can see this book in our wish list. Let's run it once again. Let's go to our wish list. And as you can see, we have our book in our wish list. Now we have persisted our data with the help of shared preferences. It seems to be great. Let's also try deleting this book from our wish list. I believe in here we should see a little bug. Let's try deleting this book. First of all, let's say no. Next time, let's say yes, it seems like the book has been removed successfully, but we are seeing the book inside our wish list. I believe the problem is that our recycler view is not refreshing. If we go back to the main activity and we open our wish list once again, you can see that the list is empty. But for some reason, after deleting the book, the recycler view does not refresh. I believe the reason for that is because the process of deleting that book from our recycler view takes too much time. And we have a trading issue in here. If you take a look at our recycler view adapter, this one books recycler view adapter, you can see that after removing the book from our lists, immediately after that, we are calling this notified data set changed. We have seen the toast message we have seen this book removed text, but it seems like this method in here is not being called until this point until calling this method we have removed the book successfully from our list. But the process of updating the process of making another connection to the shared references inside, for example, get favorites method takes too much time. And before that, we have called this method. So we have called this method before we get the new favorite books, we can fix this we can create a callback interface and create a communication between this part of our application between this on click method. And for example, favorite books activity, we can implement that callback interface inside the favorite books activities so that whenever we remove some book inside this on click method, we update the list of our books. But I'm not going to do that in here because we haven't talked about callback interfaces yet. If you want as a challenge for later videos, you can come back to this video and fix this problem. When we have talked about callback interfaces, I believe we will face this problem a lot during the course. And we definitely will take a look at callback interfaces and their usages in situations like this. So for that reason, I'm not going to talk about the solution for that issue in this video. Let's quickly check the other aspects of our application. For example, let's add some books to other lists. Let's try this book, let's say already read, we have added the book, let's delete it. Let's say yes, book has been removed. If we go back to main activity, and check our already read box activity, you can see that the list is empty. Okay, I think that's enough for this video. And for that matter, for this section of the course, you have successfully created your first functional application. As a reminder of what we have done in this section, I'm going to say that we have practiced a lot of our skill set. Besides that, we have learned how to show different dialogues, we have seen how to create a web view and show our website. Besides that, we have seen how to create expandable card views. We have seen how to use static variables. Besides that, we have learned how to use shared preferences. We learned how to enable this up button, we learned how to create animations for our activities. We also have learned how to change the title of different activities. I believe overall, this was a good section. And I hope you learned something. Hello, everyone. May Sam's here. This video is about to reach to its end. But before that, I would like to say that it is amazing that you have watched thus far of the course. Make sure to have a little party. Watching the entire course means that you are serious about Android app development. Because of that, once again, I'm going to remind you that there is an extended version of this course that you can take. There are more than 60 hours of videos in that course, and you will learn everything that you need for a successful career in Android app development. By enrolling in the course, you will have lifetime access to all of the existing videos and all of the new videos that I'll add in the course. You will have access to the source code that I write in the videos, and you can ask your questions directly from me and expect an answer within hours. Above all, you will have 30 day money back guarantee in case if for any reason you changed your mind. Click on the link in the description of this video or go to maycode.org for more information about the course. Remember that you can use free code camp as the coupon code to get 20% discount. I hope you learned something in this course, take care and continue coding.