Build a Yelp Clone on Android - Retrofit Networking Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back most interesting apps will get data from the internet and display that data in the app ui so that's exactly what i wanted to build with you in this walkthrough we're going to build an app which retrieves data from the yelp api and displays information about the restaurants and cafes in a ui that's similar to yelp if you're not familiar with yelp it's a really great service which provides rating and review information about different businesses around you everything from cafes to an electrician so in this example we are getting data out of the yelp api in order to look at where are popular places to get avocado toast in new york so you can see that the the ui that's presented is similar to what the actual yelp mobile app looks like where we have image for the restaurant a name a rating address and a distance from the location that we've specified which is new york the app that we're building is deliberately very simple it's only a single screen so nothing happens if you actually tap on any of these and that's because i really want to focus on the networking aspect and follow best practices using retrofit so that you can really learn how to build apps like this and the reason this is important is because so many apps are actually just variations of this very simple app to illustrate this here's a guide from codepath about mobile screen archetypes and the idea here is that even though there are a bunch of different mobile apps out there they really all boil down to six core screen archetypes and in particular the one that is probably the most important is something called a stream which is exactly what we're building in this walkthrough and the stream is focused on the primary content or data that a user consumes within the application so if you think of almost all the most popular apps facebook twitter snapchat really where users spend the bulk of their time is the feed where you can see a bunch of different discrete data for example on twitter and if you want more information you can tap in on one of these elements but the idea of opening up the app making a network request to get data and displaying that data that list of data in the main screen is very common in a bunch of apps which is why i want to go through it in this example we're going to get started in the next video by talking about the yelp api and how to get data out of it if you have any questions drop a comment and we can do some debugging together don't forget to like and subscribe and i will see you in the next video [Music] the goal for this video is to understand the yelp api and the data we get back i'll also show you how to create an api key which we'll need in order to make requests to yelp once we have this we'll start coding in the next video let me start with an api api stands for application programming interface and it defines how software apps communicate with each other so in this case yelp is providing an api to us and we're considered the client of the api in order to access data the mobile app that we're building is considered a client and we're making a request to the yelp server we're asking i want to search for restaurants in new york that serve avocado toast the yelp server will respond over the internet with a list of restaurants that match our search criteria and we can do whatever we want with that data in our case all we're doing is we're rendering it in a list the fundamental two apis are data apis are contracts that define how we get create modify or delete data and the way that we send data back and forth is through something called json json stands for javascript object notation but it doesn't actually have anything to do with the language of javascript in particular json is a standard way to transmit data it's easy for machines and humans to read and write which is a benefit because easy for humans to read and write means that we can look at it in the browser or in a text editor and be able to understand what it means the second thing to understand about json is that it consists of two fundamental structures objects and arrays an object is an unordered set of key value pairs and it's denoted by curly braces each key is a string followed by a colon and the value can be a string number true or false or another object or array an array is an ordered collection of values and again the values could be anything an array is denoted by square brackets and this will make more sense once we actually look at example data from the yelp api in a little bit but going back to this slide which shows the diagram architecture diagram the reason why json is important is because apis like pretty much anything with software there can't be any ambiguity so it's really important to understand how to read the structure of json and format the data you're dealing with so that the data you send to the server or receive from the server can be parsed and displayed properly now that we have an understanding of apis and json let's take a look at the yelp api which will power our application so go to yelp.com developers sign in if you haven't signed in just because you'll need that in order to create an app for the yelp api we'll get to that later but yelp fusion is a name of the api or product that we're going to use to get data out of yelp so tap on that link and then go down and tap on documentation so we can learn more about how to use yelp fusion the apis generally consist of a large number of endpoints each of which has the ability to do some operation on the data so traditionally with apis you can do things like get create modify or delete sometimes that's abbreviated as crud create read update or delete do the four common operations for the purposes of our app the only thing that we want to do or will be able to do is read data each of these has a corresponding http verb and for that it's called get we're going to be doing get requests on the yelp api in order to get data out in particular what we're going to do is use the search endpoint from this category business's endpoint and do get requests so here you can see that's the verb and the way apis typically work is that there's a base url in this case the base url is https colon slash api.yelp.com v3 so presumably v3 is the version of the api there's usually a versioning scheme behind every api after the base url you append the endpoint the endpoint here is businesses slash search so this is the request we're going to make we're going to make a get request on this url along with the url you also need to pass in certain parameters for this endpoint we're going to pass in something called a term which is of type string and it says this is optional but this is a search term for example food or restaurants in our example we're going to be passing an avocado toast here and one more parameter that we're going to provide is location again the type of this is a string because we're not going to be passing in a latitude and longitude location will be required and we're going to be passing in new york and then you can read more about other parameters that you could pass in for example if you want a particular category of business or restaurant you could do that if you want to limit the number of businesses that you get back open now is a filter and so on so there's a lot of power in this api we're going to have something which only utilizes the first two parameters but there's a lot more here that you can see if we scroll down we can actually see a sample response body so once you make a successful request to the api it will send back json data which we just talked about and it's formatted like this so you can see that what we're getting back is a json object and the way we're able to identify that is because it has curly braces here and json object consists of key value pairs so the first key value pair has a key of total and the value is 8228 and the second key value pair has a key of businesses and the value is a json list and the json list consists of a bunch of different json objects so here for example is one object this is the end of the object and then the json list consists of more of these this json object is a representation of one business or one restaurant on yelp and it has these various attributes such as rating price phone number and we're going to parse out and use a lot of these when building our app the summary of what we're getting back is a json object with three key values total businesses and region and each of them has corresponding data the only one that we'll really be interested in is the data that we get back from the business is key and you can again read more about how this data is structured and the type of that data whether it's a string or an object or a decimal in the documentation what i'd encourage you to do is spend a few extra minutes right now to read through a bit more of the documentation you can see some of the other functionality that the yelp fusion api provides for example being able to look up a business by phone number or getting the details of a particular business so similar to reading json data like the example that we went through here reading json is a skill and reading api docs itself is a skill and that's something you should develop over time and one more thing worth mentioning is the requirements that yelp has when anyone uses their api which is that attribution to yelp should be very obvious and also yelp has branding requirements for example the star rating for every business should come from yelp like those assets to show the rating should come from yelp so strictly speaking our dummy app the yelp clone won't follow those guidelines but these are things that are again all documented in the api finally most apis including the yelp api has some way to monitor the number of requests coming from a particular developer the way they do that is through something called an api key and different apis have different ways of doing this but the yelp fusion api is pretty simple actually in this regard because all you need to do is create an app in order to obtain a private api key which we'll do next and every ap api call you make to the yelp api has to include the api key some apis you'll see will use something called oauth which is a bit more complicated it's effectively a handshake between the client and server but for yelp it's pretty straightforward we're going to follow the steps here let's create an app and this is going to require us to fill out certain information and then once we create the app we'll be able to get our api key through the magic of video i filled out the fields here and you can now tap on create new app in order to get your api key so now i've created my new app keep note of this api key because we're going to be using this in our client code now that we have an understanding of api's json and in particular how the yelp api work in the next video we're going to use this information in order to make a request and get a response from the api [Music] the goal for this video is to successfully make a request to the help api and get data back what i have here is an empty android studio project i haven't changed anything you can see that when i run the project i get hello world the very first thing i'm going to do is android apps have a permission model and so in order to use the internet which of course we do need the internet because we're talking to a web service we need to add in a user's permission line in the android manifest the next thing we need to do is add in the libraries that will allow us to talk to the api android has some low-level primitives for making network requests but this pattern of making an api call is so common that there are dedicated libraries to do that so the one that we're using is called retrofit retrofit is a really popular android library that allows your app to talk to an api such as the one provided by yelp there's a lot of terminology i'm going to throw at you but don't worry too much if you don't know all the details the takeaway is that retrofit makes it much easier to do network calls by removing a lot of the low-level details so you can see here from the guide it's a type safe http client for android and java what i actually find more understandable than the square documentation is the code path documentation so you just google for codepath retrofit you should come to this article so the very first thing that's required is you need to add some dependencies into your project so just copy these three lines and open up the build.gradle file which is located in the app module paste it in and then tap on sync now and what's happening when you tap on sync now that is downloading all of the code relevant for these libraries so you can actually start referencing this in your project and just to demystify this a little bit the json is an example of a converter a converter is what takes the response from the api and converts it into a java or kotlin data class and so we're going to be using json there are a couple other options here but we're using json and then here are the actual libraries for retrofit scrolling down a bit there are some notes here about what to do on the upgrade path we're not upgrading anything so let's skip all this and then the section here about creating java classes for resources so java is very verbose much more verbose than kotlin and so there's actually a shortcut that allows you if you're creating a java class from json to kind of shortcut the process but we're going to skip this because in kotlin it's actually much much easier which i'll show you so come down to this section creating a retrofit instance this is the first thing that we'll want to do the way this works is we'll use the builder coming from the retrofit library add in a base url add a converter factory which in our example is going to be json and then call dot build in order to actually get the instance of retrofit the first thing we want is a base url so in our example the base url is going to be https api.yelp.com v3 so going into android studio go to main activity and at the very top i'm going to define a constant called bcrl and actually at this point even though i haven't actually written any interesting code i'd like to run the app because i want to make sure that the app is still able to compile after having added these libraries let's make sure yeah we still see hello world so that's a good sign that we haven't gotten off track yet retrofit dot builder and then add in the base url add in the converter going back to the guide the next step is that we want to define the endpoints for our api the way we'll do this is simply by defining an interface what that means is we're going to define a class which doesn't have any implementations for the methods we're simply defining the method signature so we're talking about the method name parameters and a return type and then retrofit will be in charge of actually filling in the details for this interface that's the benefit of retrofit so i'm going to go back to internet studio let's create a new interface i'm going to call it yelp service the return value of the method that we're going to define is always parameterized by call and then the type of what we're getting back in addition every method has to be annotated with the http verb so in our example the only thing that the yelp api is allowing us to do is read data which is a get request we need to also fill in the endpoint here so let's go back to the documentation and then the endpoint is businesses slash search so i'm going to say get business search and then function search restaurants and if you recall there are two parameters that we will pass into this endpoint first will be term which is a string and the second is the location and so the way this works with retrofit is we're going to describe these as query parameters and so i'll copy this term and we'll say query term search term you can call the name here whatever you want and then one more query will be location and the return type was always going to be surrounded by call and i don't want to worry actually about what the details of the call are so for now i'm just going to say any so now that we have the yelp service defined we can start referencing it in main activity so say retrofit.create and pass in the class instance it's a yelp service coloncolonclass.js and at this will return to us the yelp service and now we're able to call this method search restaurants on the yelp service we'll pass in a search term so the search term will search for avocado toast and the location will be new york at this point the natural question is to ask how can we get access to the data which is being returned from the yelp api because underneath the hood this search restaurant's call is using the internet to talk to the app server and getting data back this is where there's an important distinction between synchronous and asynchronous programming in synchronous programming which is what most of us are comfortable and familiar with when you make a method call you get back the result of that method call immediately for example like in this line or if this search restaurants call was synchronous we'd expect to get back some sort of value like restaurants immediately and then we could do whatever we want with that restaurant however if you look at the return type here we're actually getting back something of type call search restaurants is asynchronous which means that the method call here might take an arbitrarily long amount of time to finish either succeed or fail whatever code is after this line we want to continue executing that as soon as we fired off the network request when the network request finishes we want to get called back and get alerted of that and for example update the ui so network requests are one example in android of many examples for example database requests where you can't expect the operation to be immediate and when the operation is not immediate you can't hold up the main thread of the ui thread because that's really important for user interaction and for the app to continue processing user input so the way we can do that here is by on the call object we can enqueue it and then we need to pass in a callback so we'll say object and pass in a callback and the callback is parametrized by a type which is what we have given as the parameter here so we're going to say any here i'm going to let android studio help us with this there's two methods we need to override on failure and on response so my pattern i just typically prefer to have the on response above the on failure let's add in a log statement okay at this point let's try running the app and we don't expect any ui changes because we haven't actually modified the xml ui file yet but what we expect is we should have gotten either a success or a failure so it's filter for main activity and what i'm seeing is a 400 response code and if you google for what that means you can see that 400 means a bad request the server cannot or will not process the request to do something that is perceived to be a client error meaning that something on our end as a mobile app developer we did something wrong and if you'll remember yelp api has a requirement for an api key this is for tracking and authentication purposes so that's our issue we need to pass in an api key save this as a another variable and if you go to the documentation about authentication you can see how to authenticate api calls with the api key all we need to do is set the authorization http header value as bearer followed by the api key i'll add this in as the first parameter to our search restaurants interface this is going to be annotated with header the value is going to be exactly authorization and i'll call this auth header and this will be of type string and so now the responsibility of whoever calls this method is to pass in the auth header so let's go back here and the first parameter needs to be the bearer followed by api key so i'm going to pass this in and the api key should refer to the constant that we've defined hopefully now we will get into the on response and actually get proper data back from the yelp api in order to better inspect where we're stopping and what the data is at that point i'm going to put break points inside the method bodies and instead of running the app like normal i'm going to go up to this bug icon and debug app what this will do is start the app like normal but as soon as we hit one of these breakpoints as the app boots up execution will pause we're able to inspect each of the parameters here so now if i go into response the code that we get back is 200 which is great that means that we got okay response and if you look inside body we are able to see a json object which has businesses total and region which is exactly what we expect given the documentation students always have some issues here if you encountered a operation not permitted in on failure i found that that can usually be easily remedied just by uninstalling the app on your emulator or on your phone and then reinstalling it also double check to make sure the spelling of all the parameters is correct so make sure that you have bare correct with one space in between bearer and api key make sure you've copied the api key correctly and the base url is correct and also of course if you have any misspellings here that might also cause a failure so once you have that working the next step is parse the results and actually turn them into kotlin data classes [Music] now that we're able to talk to the yelp api and get proper data back the goal for this video is to actually leverage the power of retrofit and json and turn the response into data classes that we can use in our application so right now we're kind of throwing away a lot of the value of gson which is a converter because the data that we're getting back from the lb api we're calling it as any which is basically a generic object in kotlin instead we'd like to take the data which is always going to follow the same format as described in the api and turn that into actual yelp restaurants which we'll then use to display inside of a list or a recycler view in order to make this conversion process happen what we need to do is exactly mirror the structure of the json that we get back from our api call so i'm going to scroll down and let's take a look at what is the response body like we talked about has three keys total businesses and region and within that there are other objects so for each object that we care about we need to define an analogous model in kotlin a data class corresponding to that same structure so the top level is going to be this structure which contains these three keys so that's the first thing i'm going to do i'm going to define all of these data classes in a another file that i'm going to call yelp data classes the first data class we'll define is something called yelp search result which represents the top level json object in the response containing three keys retrofit and json will look at the data coming back from the api and then try to transform it according to the keys that are defined here so we need to call out the name of the key so it'll be total for example for the first one has a resulting value of an integer so we'll say val total and this is an int and then we want to do something similar for the other key so the one that we really care about is called businesses and this is going to be a list of businesses so we'll call it restaurants and yelp restaurant is going to be another data class that we define the idea of yelp prostrate is to mirror this json object which represents one business or restaurant on yelp so just to start out let's parse out the name field the serialized name is actually name and this is going to be of type string and one thing to note here is that there's no need to parse out every field from the json so you'll remember that there is one more key in the yelp search result object which is called region but we don't actually care about that because we're not displaying it in the ui so i am not parsing it out here even total we don't really care about that so we could about that out the only thing that we are really using for display purposes is this key called businesses which we're calling restaurants now that we've defined yelp search result let's actually use it inside of yelp service so the callback will return a yelp search result object so now in main activity we need to update the callback to use yelp search result and that means each of these also has to get updated and let's try it now so if we debug the app again let's go inside of the on response method and see if we're actually constructing these objects properly so we expect to see a list of these yelp restaurant objects that we've defined and each of them should have a name field so we open up response body and now we do see restaurants and you can see that there's a yelp restaurant and it has one field filled out called name which is perfect that's exactly what we expect that means that json is doing its job correctly of converting the data that we get back into a yelp search result and inside the yelp search result we are maintaining a list of yelp restaurant so now we're going to do a similar process for each of the other attributes inside of the restaurant that we care about for example review count image url and so on now what i've done here is i've gone ahead with the straightforward attributes of the yelp restaurant so name rating price number of views distance in meters and image url these are all simple attributes that are on the top level object of the yelp restaurant one thing to note is that there's no need to actually specify a serialized name if the name of the parameter in the object exactly matches the name of the variable in kotlin so that's the case for name rating and price if you go back to the sample data rating price and name exactly match the reason i had to specify serialized name here is because i'm calling review count something else i'm calling it num reviews in camelcase whereas the attribute name in json is review underscore count and similarly i'm renaming these other fields distance and image url which is why we need to specify these there are two more attributes that i would like to be able to parse out of the yelp restaurant in order to show the completed ui first is a category for the restaurant and second is a location so these are a bit more involved and you can see why by looking at the json data the first is the category so what you'll notice is that the category is a key in this json object which has a value of a json array and this json array consists of different json objects each json object represents one category and so this is what we need to now mirror in our data classes so we need to have one more data class called category yelp category and this contains two fields alias and title but really the only thing we care about is a title because that's what we're going to use for display purposes and the attribute name is going to exactly match the variable name so i don't even need to say serialize name i'll just say val title and this is a string so now we can use this yelp category in the parsing of yelp restaurant so i'll say serialized name and it's called categories those categories and this is going to be a list of yelp category and again actually i don't even need to specify serialize name because this exactly matches with the variable name and finally the last thing we want is we want to display the first line of the address of each business so in this example it would be 375 valencia so again we have to create a yelp location object and we don't need to parse out everything the only thing we need is the address i'll say data class you know location and then the only thing we care about here is address it's going to be a type string and here i can say location and this is going to be of type yelp location and one more thing while we're here that i'm going to add is i'm going to add one method on the yelp restaurant data class which will convert the distance in meters that we have as part of the data class and convert it into a distance that we can actually use for the ui so i'm going to add a function called display distance and this is going to return to us a string and the way this will work is i'm going to save the number of miles in one meter as a variable and use that to multiply with the double that we get back here the number that we get back from distance meters and that'll be how we compute the number of miles which we'll use for display purposes great so now we're formatting it and we are getting some distance and miles and we want to return that as a string properly formatted okay let's try it i'm going to debug the app and hopefully we should get into the on response again and now we should have fully formed yelp restaurant objects opening up response body and here you can see for example image url properly filled out the name and all other data looks pretty good the one common mistake here is you want to make sure that the type that you assign matches up exactly with the type that's actually being returned from the json so make sure you have int double and string specified appropriately the next step is to actually take the data that we have parsed out now from the yelp api and finally we want to display it inside of a recyclerview that the user can scroll through [Music] at this point we've gotten back data from the yelp api successfully and moreover we've actually converted it into exactly the format that we want in order to display it inside of a scrollable list on our main activity our job now is to take the response that we get back and notify the recyclerview that we have data now and it should re-render itself the first thing i'm going to do is to find a variable for the list of restaurants and then we need an adapter for the recyclerview which we're going to define later and this is the adapter is going to take in two parameters one which is the context and then second which is the list of restaurants and before we define the adapter i'm going to go into the activitymain.xml go into the design tab get rid of the hello world text but drag out a recycler view and this will prompt you to add in the recyclerview library so tap on ok and what we want to do here is fill out the properties of this recyclerview sometimes i've noticed that the attributes tab doesn't come up until i quit android studio and open it up again so i just did that and now i'm able to provide an id and layout width and height to this recycler view i'm going to call this rv restaurant and i'm going to make the width and height match parent and now let's go back into main activity we need to now define this restaurant adapter class so i'll let android studio help us with that create class extract to a separate file and the first parameter is going to be context prepend it with val and then this is going to be of type context and then similarly val restaurants and this is going to be a list not mutable list but just a list of yelp restaurant and this is going to extend or be a subclass of the base recyclerview adapter and the adapter is parametrized by a view holder i'm going to define an inner class which is the view holder and now that we have the signature of the adapter we can now implement the methods that are required there are three methods i'll implement all of them and my preference is to have the view holder at the very bottom and this these methods that we're overriding should be at the top so get item count is the easiest just to fill that out first this is going to be the size of the restaurants i'll say restaurants that list dot size and i have a separate playlist of just talking motorcycle review which is i'm kind of speeding through this because it's mostly a repeat of what we've already done i'll leave a link for that in the description the next is on create view holder so here we want to actually inflate a new layout and drop that inside of a view holder so i'll say return view holder and then you want to get the layout inflator from the context and inflate a new layout and i'll define this layout shortly but we'll call it layout dot item restaurant and this is going to represent one cell or one row in our recycler view and we pass in parent and false so let's go ahead and define that now create layout resource file the base root element will be a constraint layout tap on okay just to get started let's drag out a text view let's give this an id of tv name because this will represent the name of the restaurant and i'll also zoom in so we'll get some sample text to better visualize what this might look like charlie street let's constrain this to be zero from the top and left okay so in restaurants adapter let's go back and in the on bind view holder the first thing we want to do is grab the restaurant at this particular position this is pretty easy because we already have the restaurants list and i'm going to index into it with position i'm going to be a restaurant and then what i like to do here is especially if you're setting a lot of data on the view which we will right now we only have the name but eventually we're going to have a bunch of other info such as the rating image address and so on then i like to push all of that logic inside of the view holder class so i'll say holder which is an instance of the view holder dot bind and i'll pass in the restaurant let's add this as a function here and so here's where we can actually specify the different views or widgets on the item restaurant so i'll say tv name and i'm going to set the text to be the name of the restaurant and this is coming from the data class json has set the name of the restaurant so now let's go back into main activity and let's use the adapter so i'm going to define the recyclerview from the from the layout then i'll set the adapter to be adapter and then the other thing we need for every recycler view is a layout manager we'll just use the traditional linear layout manager and pass into context and finally once we get the data back from the help api we need to add that data into the restaurants list and then notify the adapter that the data has changed so the very first thing we'll do is just check the body of the response and make sure that it's valid so if the body is null then something has gone wrong and we should indicate that if the body is not null then we can assume at this point that we have a properly formatted yelp search result and within that we have all of the restaurant data so we can just add that all into our restaurants list so i'll say add all and pass in body dot restaurants and then finally we need to notify the adapter that the data set has changed and one more thing we can do before we try it out is going back into item restaurant right now you'll notice that the constraint layout has a width and height of match parent the height of match parent would mean that we take up the whole screen height and we don't want that instead we would like wrap content and you can see how it shrunk up just to contain the elements inside now we can try it and we expect to see just the list of restaurant names and nothing else in the app now and then you can see the 20 restaurants that we got back and just their names what i want to do now is drag out all of the widgets that we will need text view rating bar image view to make up the final display of the row here's what we're aiming for in terms of the ui of one row of the recycler view we have one image view a rating bar and one two three four five six different text views and so what i'm going to do first is drag out all these views and then we'll organize them after that so first let's drag out an image view and i'll have avatars as a sample data the id can just be image view i'm going to hard code the within height to be 100 dp and then i'm going to drag out the tv named now we need a rating bar so first i want to change the style of the rating bar to be small so it's not as unwieldy and then i'll call the id as a rating bar and num stars will be five for some sample data we'll have a sample rating of 4.5 and the step size will be 0.5 that's what the yelp system the api gives us back ratings in increments of 0.5 then we'll have one text view to the right of the writing bar which describes how many reviews there were so we'll call this tv num reviews and then i'll give it some sample text of 321 reviews then we'll have one more text view underneath which is for the address we'll call this tv address and the sample text can be 41 kenmare and one more text view underneath that which will be the category and finally two more text views one up in the top right is for the distance finally one more which is for the price this is the number of dollar signs okay one thing i want to do is add a margin around the whole parent layout the constraint layout so we can have some spacing in between different elements so i'll search for margin and let's just add 8 dp all around okay so now let's work on positioning these views so first the image view can be 0 0 at the top left and then we want to position the name to be to the left of the image view and also zero from the top along with the sky as well so this should be zero from the top and the right the tv name should be placed to the right of the image view with some gap maybe eight and each of these the rating bar the address and category should be positioned vertically below the element above it i'm going to drag this out and make it four and then that's it and then the address should also be 4 dp below that so remember our job here is to constrain each view horizontally and vertically and these red exclamation marks give us a hint of which views we haven't yet constrained in both of those directions so for each of these we've now constrained them vertically because they're below the element above them but we haven't constrained them horizontally so in order to do that i'm going to just align the left edges of each of these views to the name of the restaurant which is charlie street in this instance all right and now you can see the red exclamation marks next to each of these three views has gone away for the number of reviews i'm going to align the baseline of it with the rating bar those should kind of be in the same same level the bottom edges will be aligned and also in order to constrain it horizontally i'm going to move it to the left of the number of ratings and then finally we have these two so the distance is already constrained because we've pushed it to the very top right the price we're going to have it be relative to the distance and we want to align the edges between these two elements right so now you can see all the red exclamation marks are gone and the other thing we'll do just to make it match a bit closer to our preview here is the name of the restaurant should of course be bigger and on bold and then you can see that there's some graying out happening for all the text views except for the address so i'm going to do that so each of these should be a gray color darker gray and then this one the title should be bold and also larger yeah so that looks pretty close to what we have here in the next video we'll put it all together by referencing these views from the restaurant's adapter and populating data that we get from the api so now we've dragged out all the relevant views text view rating bar and image view onto our item restaurant.xml which represents one row in our recyclerview if you run the app now you can see that we are seeing the spacing is there but we're not actually populating any of the data properly the grading bar we've hard coded in 4.5 which is why you're seeing that and none of the other data is there so the job for this video is to fill out this data from the adapter class so if we go into restaurants adapter the place where we're doing all the population of the data is going to happen in the bind method of the view holder so we have the view and we also have the restaurant data in the bind method that's all we need the way i'll approach this is going in order top to bottom and filling out all the data in our view so right below the name of the restaurant we have the rating bar there's an attribute on the grading bar called rating and we will just set that this is a double but rating actually expects a float that's what this is complaining about so i'm just going to call dot the two float method next to the rating bar is the number of reviews we gave that an id of tv num reviews and then we'll set the text attribute of that to be restaurant dot number views and we actually want this to be in a string so we'll format this below the rating bar and reviews is the address so the address if you remember from our data class it lives inside of the yelp location so we first need to get the location and then inside of that there is a field called address below that is the category and this is something similar well first we want to get the list of categories and we can just take the first one and we'll grab the title of that and then in the next column we have two things one which is the distance and the second is the price so first we'll do the distance we called it the id of the text view is tb distance and we want to set the text so this is where the helper method on the data class comes in handy which is the display distance this is going to convert it nicely into the format that we care about restaurant dot display distance and finally we have the price this is a number of dollar signs so it's already a string let's try it we haven't filled out the image view yet we'll come to that but let's just make sure that this is all being populated properly alright and you can see it is so the only thing left to do is fill out the image view in order to do that android doesn't have an easy built-in system for displaying remote images and so we're going to use a library called glide if you go to your browser and just google for codepath android glide you should come to this article and this is usually how i am able to quickly get up and running with glide we need these two dependencies so let's add these into the build.gradle file which is located in the app module after you paste it in tap on sync now and what that'll do is actually pull in these libraries so you can reference them in your project going back to the adapter we can now start to reference glide say glide dot with and we need to pass in a context which we are getting from the constructor of the restaurant's adapter and we're loading the image url that is restaurant. image url i'm going to load this into the imageview of the itemview let's try it yeah so that almost worked the only thing that's a bit odd is that the image is not taking up the full dimensions of the 100 by 100 image view that we've set what we'd like is we want to change the scale type in addition we'd also ideally like to have routed corners on the imagery that just makes it look a little nicer so the way you can do both of those transformations is by again using glide so i'll say apply and we're going to add in some request options with transforms and then here is where you can specify the transforms you want so there are two that we care about center crop and you'll need to import this and then second you also want rounded corners and this transformation takes in a parameter which is the corner radius so i'm going to specify 20. so if you run this now you can see that looks way better so all our images are square rounded images and they take up the full dimensions of the image view a great job if you've gotten this far as a review what we've done is we've added in the library retrofit into our application and retrofit is an easy way to interact with apis and web services so in our example we're making a yelp clone so we're talking with the yelp api in order to make that work we pass in a base url and we tell retrofit to create all the details of talking to this api by passing in an interface this interface has one method for each endpoint of the api that we're interested in we only have one endpoint which is searching for businesses according to a search term and location which are the two query parameters in addition we need to pass in a header which is the api key that's used for authentication the result of this api call is a yelp search result which is a data class that we've defined and that contains all the restaurant data and one important point important concept here is asynchronous programming because the api call may fail may succeed or it could take some amount of time and so we need to make the call and then get notified back on the main thread when the response has either succeeded or failed and when it succeeded we can parse out all the restaurants which is being done for us by json and then notifying the adapter of this new data and then all of the logic to display one restaurant in the recycler view is happening in the adapter so we're sending all the data here so as usual there's a ton of really cool extensions that you could do once you've built out this space application for example you could allow the user to add filters to the query to the endpoint that we have currently for example you could only want restaurants that are open now or only restaurants have a certain category and second you could update the ui to look more like yelp as we talked about yelp has branding requirements so for example the rating bar you can't use the stock android rating bar you have to use the assets that come from yelp and those are all included in the documentation if you got stuck anywhere as you were building out this project or if you have any conceptual questions about what exactly we covered feel free to drop a comment i'd love to help i hope you had a lot of fun building out this project and you feel empowered to now use any of the countless number of apis out there don't forget to like and subscribe and i'll see you in the next one bye
Info
Channel: Rahul Pandey
Views: 1,719
Rating: undefined out of 5
Keywords: android, androidstudio, development, programming, kotlin, codepath, code, tutorial, rahulpandey, rahul, pandey, teach, yelp, retrofit, gson, networking, api, json
Id: F2V-VOHvx0E
Channel Id: undefined
Length: 52min 0sec (3120 seconds)
Published: Sun Oct 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.