add navigation bar with fragments

master
Julien THEME 2 years ago
parent 4d34f8db47
commit dca834b7fc

@ -23,6 +23,11 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
buildFeatures {
viewBinding true
}
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8

@ -5,49 +5,39 @@ import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.fragment.app.Fragment
import com.android.volley.VolleyError import com.android.volley.VolleyError
import com.android.volley.toolbox.StringRequest import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley import com.android.volley.toolbox.Volley
import com.example.cinapp.databinding.ActivityMainBinding
import com.example.cinapp.model.Movie import com.example.cinapp.model.Movie
import com.example.cinapp.navigation.MainScreen import com.example.cinapp.navigation.MovieFragment
import com.example.cinapp.navigation.SearchFragment
import com.example.cinapp.navigation.SerieFragment
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
//setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater)
setContent { setContentView(binding.root)
MaterialTheme { MainScreen() } replaceFragment(MovieFragment())
binding.bottomNavigation.setOnItemSelectedListener {
when(it.itemId){
R.id.movie -> replaceFragment(MovieFragment())
R.id.serie -> replaceFragment(SerieFragment())
R.id.search -> replaceFragment(SearchFragment())
else -> false
}
true
} }
/*
// TextView
val textView = findViewById<TextView>(R.id.text)
// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(this)
val url = "https://api.themoviedb.org/3/search/tv?api_key=e53e59cf1e29b9afff93d9ca1208f0cf&query=One%20Piece&language=fr"
// Request a string response from the provided URL.
val stringRequest = StringRequest(url,
{ response ->
// Display the first 500 characters of the response string.
textView.text = "Response is: ${response.substring(0, 500)}"
},
{ error: VolleyError ->
textView.text = "That didn't work!"
} }
)
// Add the request to the RequestQueue.
queue.add(stringRequest)
//bottom navigation with jetpack compose
*/
private fun replaceFragment(fragment: Fragment){
supportFragmentManager.beginTransaction().replace(R.id.frame_layout, fragment).commit()
} }
} }

@ -1,24 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
@Composable
fun BottomNavGraph(navController: NavHostController){
NavHost(
navController = navController,
startDestination = BottomNavigation.Movie.route
) {
composable(BottomNavigation.Movie.route) {
MovieScreen()
}
composable(BottomNavigation.Search.route) {
SearchScreen()
}
composable(BottomNavigation.Serie.route) {
SerieScreen()
}
}
}

@ -1,30 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.LiveTv
import androidx.compose.material.icons.filled.Movie
import androidx.compose.material.icons.filled.Search
import androidx.compose.ui.graphics.vector.ImageVector
sealed class BottomNavigation(
val route: String,
val icon: ImageVector,
val title: String
) {
object Movie : BottomNavigation(
route = "movie",
//icon = R.drawable.ic_baseline_movie_24,
icon = Icons.Filled.Movie,
title = "Movie")
object Search : BottomNavigation(
route = "search",
//icon = R.drawable.ic_baseline_search_24,
icon = Icons.Filled.Search,
title = "Search")
object Serie : BottomNavigation(
route = "serie",
//icon = R.drawable.ic_baseline_live_tv_24,
icon = Icons.Filled.LiveTv,
title = "Serie")
}

@ -1,78 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.navigation.compose.rememberNavController
import androidx.compose.ui.Modifier
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.ui.setupWithNavController
@Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomBar(navController = navController) }
) {
BottomNavGraph(navController = navController)
}
}
@Composable
fun BottomBar(navController: NavHostController) {
val screens = listOf(
BottomNavigation.Movie,
BottomNavigation.Serie,
BottomNavigation.Search,
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
BottomNavigation {
screens.forEach { screen ->
AddItem(
screen = screen,
currentDestination = currentDestination,
navController = navController
)
}
}
}
@Composable
fun RowScope.AddItem(
screen: BottomNavigation,
currentDestination: NavDestination?,
navController: NavHostController
) {
BottomNavigationItem(
label = {
Text(text = screen.title)
},
icon = {
Icon(
imageVector = screen.icon,
contentDescription = "Navigation Icon"
)
},
selected = currentDestination?.hierarchy?.any {
it.route == screen.route
} == true,
unselectedContentColor = LocalContentColor.current.copy(alpha = ContentAlpha.disabled),
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true
}
}
)
}

@ -1,8 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.runtime.Composable
@Composable
fun MovieScreen() {
}

@ -0,0 +1,60 @@
package com.example.cinapp.navigation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.cinapp.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [MovieFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class MovieFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_movie, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment MovieFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
MovieFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

@ -1,8 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.runtime.Composable
@Composable
fun SerieScreen() {
}

@ -0,0 +1,60 @@
package com.example.cinapp.navigation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.cinapp.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [SearchFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class SearchFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_search, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SearchFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
SearchFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

@ -1,8 +0,0 @@
package com.example.cinapp.navigation
import androidx.compose.runtime.Composable
@Composable
fun SearchScreen() {
}

@ -0,0 +1,60 @@
package com.example.cinapp.navigation
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.cinapp.R
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [SerieFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class SerieFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_serie, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SerieFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
SerieFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}

@ -6,14 +6,24 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView <FrameLayout
android:id="@+id/text" android:id="@+id/frame_layout"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:menu="@menu/bottom_nav" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/material_dynamic_secondary30"
tools:context=".navigation.MovieFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Movie"
android:textSize="26dp"
android:layout_gravity="center"/>
</FrameLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/purple_700"
tools:context=".navigation.SearchFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:textSize="26dp"
android:layout_gravity="center"/>
</FrameLayout>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/purple_200"
tools:context=".navigation.SerieFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Serie"
android:textSize="26dp"
android:layout_gravity="center"/>
</FrameLayout>

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="409dp"
android:layout_height="43dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.428"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.997">
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Movie"
android:id="@+id/movie"
android:icon="@drawable/ic_baseline_movie_24" />
<item android:title="Serie"
android:id="@+id/serie"
android:icon="@drawable/ic_baseline_live_tv_24" />
<item android:title="Search"
android:id="@+id/search"
android:icon="@drawable/ic_baseline_search_24" />
</menu>

@ -1,3 +1,5 @@
<resources> <resources>
<string name="app_name">Cin\'app</string> <string name="app_name">Cin\'app</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources> </resources>
Loading…
Cancel
Save