Displaying Data From Code
Learn and practice how to implement the recycler view adapter to render a list of blog article in this lesson.
We'll cover the following...
Loading data from the Internet
During the previous lessons, we created a BlogHttpClient
that loads a list of blog articles. Let’s modify our code to support the new JSON format.
Old JSON format:
{"data": [{"title": "G'day from Sydney","date": "August 2, 2019","views": 2687,"rating": 4.4,"image": "https://bitbucket.org/dmytrodanylyk/travel-blog-resources/raw/3436e16367c8ec2312a0644bebd2694d484eb047/images/sydney_image.jpg","author": {"name": "Grayson Wells","avatar": "https://bitbucket.org/dmytrodanylyk/travel-blog-resources/raw/3436e16367c8ec2312a0644bebd2694d484eb047/avatars/avatar1.jpg"},"description": "G'day mate! Welcome to Sydney, where you come for the ..."}}
The main changes in the new JSON format are:
- We have an
id
attribute - The
image
andavatar
now contain a relative path
{"data": [{"id": 1,"title": "G'day from Sydney","date": "August 2, 2019","views": 2687,"rating": 4.4,"image": "/images/sydney_image.jpg","author": {"name": "Grayson Wells","avatar": "/avatars/avatar1.jpg"},"description": "G'day mate! Welcome to Sydney, where you come for the ..."}]}
In the BlogHttpClient
, we need to change the URL to the following:
object BlogHttpClient {const val BASE_URL = "https://bitbucket.org/dmytrodanylyk/travel-blog-resources"const val PATH = "/raw/3eede691af3e8ff795bf6d31effb873d484877be"private const val BLOG_ARTICLES_URL = "$BASE_URL$PATH/blog_articles.json"...}
This gives us the ability to concatenate the BASE_URL
with the relative path of the blog image
or the author avatar
. Let’s add additional get methods to the Author
class and the Blog
class which are going to return full image URLs.
data class Author(val name: String, val avatar: String) {fun getAvatarUrl() = BlogHttpClient.BASE_URL + BlogHttpClient.PATH + avatar}
data class Blog(val id: String,var author: Author,val title: String,val date: String,val image: String,val description: String,val views: Int,val rating: Float) {fun getImageUrl() = BlogHttpClient.BASE_URL + BlogHttpClient.PATH + image}
Now, we can modify the MainActivity
code and add a blog loading code similar to what we have in BlogDetailsActivity
.
class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)loadData()}private fun loadData() {BlogHttpClient.loadBlogArticles(onSuccess = { blogList: List<Blog> ->runOnUiThread { // TODO show data }},onError = {runOnUiThread { showErrorSnackbar() }})}private fun showErrorSnackbar() {Snackbar.make(binding.rootView,"Error during loading blog articles", Snackbar.LENGTH_INDEFINITE).run {setActionTextColor(resources.getColor(R.color.orange500))setAction("Retry") {loadData()dismiss()}}.show()}}
List Adapter
In order for RecyclerView
to render and reuse the list of items, we need to use one of the implementations of the ...