Open In App

How to Build a Rick and Morty App in Android?

Last Updated : 01 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Rick and Morty is an American animated science fiction sitcom created by Justin Roiland and Dan Harmon. In this article, we will build an application that will display the name and image of all rick and Morty characters using this API. In order to build this application we will be using the Retrofit library. Retrofit is a third-party library that helps us to make a network request. From the json respoanse we will be fetching names and images of characters.

To get started, we will first set up our project and create an interface that defines the endpoints of the Rick and Morty API. Then, we will implement an Activity that makes a GET request to the API and displays the list of characters in a RecyclerView. Finally, we will create an adapter for the RecyclerView that binds the character data to the layout for each item in the list. A sample video is given below to get an idea about what we are going to do in this article.

Step by Step Implementation

Step 1: Create a New Project in Android Studio

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.

Step 2: Add these dependencies in Build.gradle(app) file

// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    
// circular image view
implementation 'de.hdodenhof:circleimageview:3.1.0'
    
// glide library for image processing
implementation 'com.github.bumptech.glide:glide:4.13.2'

Add internet permission in the Android Manifest XML file

XML




<uses-permission android:name="android.permission.INTERNET"/>


Step 3: Generate data classes

Copy the response from the above API. Right-click on the root package and select New->Kotlin-data class from JSON. If you don’t have this plugin, go to File -> Settings -> Plugin and install JSON to Kotlin Plugin. Copy the JSON result and paste it. Give this file a suitable name after that two data classes will be generated.

Kotlin




data class RickMorty(
    val results: List<Result>
)


Kotlin




data class Result(
    val image: String,
    val name: String,
)


Step 4: Create API interface and retrofit instance 

This is an interface in Kotlin called RickApi that defines a single method called getDetails. This method is annotated with the @GET annotation, which specifies that it should perform an HTTP GET request to the specified endpoint (“character” in this case).

Kotlin




// Interface that defines the
// endpoints of the Rick and Morty API
interface RickApi  {
    // HTTP GET request to the character endpoint
    @GET("character")
    fun getDetails() : Call<RickMorty>
}


The api property is initialized by building a Retrofit instance using the Retrofit.Builder class, setting the base URL for the API, adding a converter factory to parse the API’s response data (using Gson in this case), and then creating an implementation of the RickApi interface using the create method of the Retrofit instance.

Kotlin




// Object that holds a single
// instance of the RickApi interface,
// initialized using Retrofit
object RetrofitInstance {
      // Property that lazily initializes
      // the RickApi implementation
    val api : RickApi by lazy {
        // Build the Retrofit instance with 
        // a base URL and a Gson converter factory
        Retrofit.Builder()
            .baseUrl("https://rickandmortyapi.com/api/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(RickApi::class.java)
    }
}


Step 5: Design layout Files

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. Comments are added inside the code to understand the code in more detail.

activity_main.xml

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>


recycler_layout.xml

Since we are using recycler view we need to create a new layout file for that go to res->layout and create a new Layout resource file named recycler_layout.

XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="10dp">
    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/characterImage"
        android:layout_width="75dp"
        android:layout_height="60dp">
    </de.hdodenhof.circleimageview.CircleImageView>
    <TextView
        android:id="@+id/showName"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Name"
        android:padding="18dp"
        android:textSize="20dp">
    </TextView>
</LinearLayout>


Step 6: Create an Adapter class for RecyclerView

This is the code for the RickRecycler class, which is an adapter for a RecyclerView that displays a list of Rick and Morty characters. The adapter holds a list of Result objects, which represent the character data, and updates the RecyclerView when the data is changed.

Kotlin




class RickRecycler : RecyclerView.Adapter<RickRecycler.ViewHolder>() {
    
    // List of characters to display
    var list = ArrayList<Result>()
      
    // Set the data for the adapter and
    // notify the RecyclerView of the change
    fun setData(list  : List<Result>){
        this.list = list as ArrayList<Result>
        notifyDataSetChanged()
    }
      
    // Initialise single item using view holder class
    class ViewHolder(view : View)  : RecyclerView.ViewHolder(view){
        val characterImage = view.characterImage
        val  name = view.showName
    }
  
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.recycler_layout,parent,false)
        return ViewHolder(view)
    }
  
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // loading image using glide library
        Glide.with(holder.itemView).load(list[position].image).into(holder.characterImage)
          
          // loading character name in text View
        holder.name.text = list[position].name
    }
  
    override fun getItemCount(): Int {
       return list.size
    }
}


Step 7: Working with the MainActivity.kt file

This is the code for the MainActivity class, which is the main Activity of the app. The MainActivity sets up the RecyclerView and the RickRecycler adapter and makes a GET request to the Rick and Morty API to retrieve the list of characters.

Kotlin




class MainActivity : AppCompatActivity() {
       // Reference of Adapter Class 
    private lateinit var adapter: RickRecycler
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // initializing recycler view
        adapter = RickRecycler()
        recyclerView.layoutManager = LinearLayoutManager(applicationContext)
        recyclerView.adapter = adapter
        RetrofitInstance.api.getDetails().enqueue(object :Callback<RickMorty>{
            override fun onResponse(call: Call<RickMorty>, response: Response<RickMorty>) {
                   if (response.body()!=null){
                      adapter.setData(response.body()!!.results)
                   }
                 else{
                     return
                   }
            }
  
            override fun onFailure(call: Call<RickMorty>, t: Throwable) {
               Log.d("TAG",t.message.toString())
            }
  
        })
    }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads