Open In App

Android Jetpack Compose – Create a Movie App

Last Updated : 04 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In the modern digital era, the demand for movie apps is soaring. These applications provide users with an immersive experience, allowing them to discover, explore, and enjoy a wide range of movies. Jetpack Compose, a declarative UI toolkit for Android, has gained immense popularity due to its simplicity, flexibility, and powerful features. In this article, we will explore how to create a movie app using Jetpack Compose. 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. While choosing the template, select Empty Compose Activity. If you do not find this template, try upgrading the Android Studio to the latest version. We demonstrated the application in Kotlin, so make sure you select Kotlin as the primary language while creating a New Project.

Step 2: Designing the user interface

Navigate to the MainActivity.kt file. Define the main screen layout using Jetpack Compose’s composable functions. Utilize various Compose components like Scaffold, Column, LazyColumn, Text, Image, etc., to structure the UI and display movie data.

Kotlin




package com.example.jetmovieapp
  
import android.annotation.SuppressLint
import android.content.ContentValues.TAG
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.jetmovieapp.model.Movie
import com.example.jetmovieapp.navigation.MovieNavigation
import com.example.jetmovieapp.ui.theme.JetMovieAppTheme
  
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                  MovieNavigation()
            }
        }
    }
}
  
@Composable
fun MyApp(content: @Composable () -> Unit){
    JetMovieAppTheme {
        content()
    }
}
  
@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
  
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MyApp {
      MovieNavigation()
    }
}


Step 3: Create a Movie Class to fetch Movie Data

Kotlin




package com.example.jetmovieapp.model
  
data class Movie(
    
    val id : String,
    val  title : String ,
    val year : String,
    val genre : String,
    val director : String,
    val actors : String,
    val plot : String,
    val poster : String,
    val images : List<String>,
    val rating : String
)
  
fun getMovies() : List<Movie> {
    return listOf(
        Movie(
        id = "101",
        title = "Avatar",
        images  = listOf(
        ),
            year = "2009",
            genre = "Action",
            director = "James Cameron",
            actors = "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
            plot = "\"A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
            rating = "7.9"
    ) ,
        Movie(
            id = "102",
            title = "I Am Legend",
            images  = listOf(
            ),
            year = "2007",
            genre = "Drama, Horror, Sci-Fi",
            director = "Francis Lawrence",
            actors = "Will Smith, Alice Braga, Charlie Tahan, Salli Richardson-Whitfield",
            plot = "Years after a plague kills most of humanity and transforms the rest into monsters, the sole survivor in New York City struggles valiantly to find a cure.",
            rating = "9.8"
        ) ,
        Movie (
            id = "103",
            title ="The Avengers",
            year =  "2012",
    director =  "Joss Whedon",
    images = listOf(
            ) ,
            genre = "Action, Sci-Fi, Thriller",
            actors = "Robert Downey Jr., Chris Evans, Mark Ruffalo, Chris Hemsworth",
            plot = "Earth's mightiest heroes must come together and learn to fight as a team if they are to stop the mischievous Loki and his alien army from enslaving humanity.",
            rating = "8.1",
                ),
        Movie(
            id = "104",
            title ="The Wolf of Wall Street",
            year =  "2013",
            director =  "Martin Scorsese",
            images = listOf(
            ) ,
            genre = "Biography, Comedy, Crime",
            actors = "Leonardo DiCaprio, Jonah Hill, Margot Robbie, Matthew McConaughey",
            plot = "Based on the true story of Jordan Belfort, from his rise to a wealthy stock-broker living the high life to his fall involving crime, corruption and the federal government.",
            rating = "8.2",
        ) ,
        Movie(
            id = "105",
            title ="Interstellar",
            year =  "2014",
            director =  "Christopher Nolan",
            images = listOf(
            ) ,
            genre = "Adventure, Drama, Sci-Fi",
            actors = "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
            plot = "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
            rating = "8.6",
  
        )
  
    )
  
}


Step 4: Create a MovieNavigation function

MovieNavigation composable function, which is responsible for setting up the navigation flow within the movie app using Jetpack Navigation with Jetpack Compose.

Kotlin




@Composable
fun  MovieNavigation() {
 val navController = rememberNavController()
    NavHost(navController = navController,
        startDestination =  MovieScreens.HomeScreen.name) {
        composable(MovieScreens.HomeScreen.name) {
           // here we pass where this 
           // should lead us to
           HomeScreen(navController)
        }
        composable(MovieScreens.DetailsScreen.name+"/{movie}",
        arguments = listOf(navArgument(name = "movie" ) {type = NavType.StringType})
        ) {
            backStackEntry->
            DetailsScreen(navController = navController ,
                backStackEntry.arguments?.getString("movie"))
        }
    }
}


Step 5: Create a movie Screen Enum Class

The MovieScreens enum class has two enum values: HomeScreen and DetailsScreen, representing the home screen and details screen, respectively.

Kotlin




package com.example.jetmovieapp.navigation
  
enum class MovieScreens {
    HomeScreen,
    DetailsScreen ;
    companion object {
        fun fromRoute(route :String?)  : MovieScreens
         = when (route?.substringBefore("/")) {
             HomeScreen.name -> HomeScreen
             DetailsScreen.name -> DetailsScreen
            null -> HomeScreen
            else -> throw java.lang.IllegalArgumentException("Route $route is not recognized")
         }
    }
}


Step 6: Create HomeScreen Function

The HomeScreen composable function takes a NavController as a parameter and represents the main screen of the app. It uses the Scaffold component to set up the basic layout structure. Within the Scaffold, a TopAppBar is displayed with a white background and an elevation of 5dp. The title “Movies” is displayed within the app bar.

Kotlin




@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun HomeScreen(navController : NavController) {
    Scaffold(
        topBar = {
            TopAppBar(
                backgroundColor = Color.White,
                elevation = 5.dp
            ) {
                Text(text = "Movies")
            }
        },
    ) {
           MainContent(navController = navController)
    }
}
  
@Composable
fun MainContent(
    navController: NavController,
    movieList: List<Movie> =  getMovies() )  {
  
    Column(modifier = Modifier.padding(12.dp)) {
        LazyColumn {
            items(items  = movieList) {
                MovieRow(movie = it) { movie ->
                 navController.navigate(route = MovieScreens.DetailsScreen.name + "/$movie")
                }
            }
        }
    }
}


Step 7: Create DetailsScreen function

This function provides details related to the movie on which the user clicks. In the DetailsScreen function, the movieId parameter is received, which represents the identifier of the movie being displayed. Inside the function, a new list of movies is obtained by filtering the result of the getMovies() function based on the movieId. This list is stored in the newMovieList variable.

Kotlin




@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun DetailsScreen(navController: NavController, movieId: String?) {
    val newMovieList = getMovies().filter { movie->
          movie.id == movieId
    }
    Scaffold(topBar = {
        TopAppBar(backgroundColor = Color.White,
            elevation = 0.dp) {
            Row(horizontalArrangement = Arrangement.Start) {
                Icon(imageVector = Icons.Default.ArrowBack, contentDescription =  "Arrow",
                    modifier = Modifier.clickable {
                        navController.popBackStack()
                    })
                Spacer(modifier = Modifier.width(10.dp))
                Text(text = "Movies", style = TextStyle(color = Color.Black))
  
            }
  
        }
    }) {
  
        Surface(modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight()) {
            Column(horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Top) {
                MovieRow(movie = newMovieList.first())
                Spacer(modifier = Modifier.height(8.dp))
               Divider()
                Text(text = "Movie Image")
                HorizontalScrollableImageView(newMovieList)
            }
        }
    }
  
}
  
@Composable
private fun HorizontalScrollableImageView(newMovieList: List<Movie>) {
    LazyRow {
        items(newMovieList[0].images) { image ->
            Card(modifier = Modifier
                .padding(12.dp)
                .size(240.dp)) {
                AsyncImage(
                    model = image,
                    modifier = Modifier.fillMaxHeight(),
                    contentDescription = "Movie Poaster"
                )
            }
        }
    }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads