Compare commits

...

8 Commits

@ -244,9 +244,9 @@ StubManager --|> DataManager
- :white_check_mark: [**Partie 5**](.drone.yml) : **Conception et réalisation du Model**
- :warning: [**Partie 6**](.drone.yml) : **Persistance des donnéees**
- :white_check_mark: [**Partie 6**](.drone.yml) : **Persistance des donnéees**
- :x: [**Partie 7**](.drone.yml) : **Réalisation de la barre de recherche**
- :white_check_mark: [**Partie 7**](.drone.yml) : **Réalisation de la barre de recherche**
- :x: [**Partie 8**](.drone.yml) : **Affichage des images SVG**

@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
android {
@ -13,8 +14,8 @@ android {
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true
}
buildTypes {
@ -49,7 +50,10 @@ dependencies {
// Room
implementation 'androidx.room:room-runtime:2.5.1'
implementation 'androidx.room:room-ktx:2.5.1'
kapt "androidx.room:room-compiler:2.5.1"
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'

Binary file not shown.

@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".application.ScorItApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"

@ -1,11 +1,6 @@
package uca.iut.clermont.api
import AreaManager
import CompetitionsManager
import DataManager
import MatchesManager
import PeopleManager
import TeamsManager
import kotlinx.coroutines.coroutineScope
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

@ -13,6 +13,8 @@ import uca.iut.clermont.model.PlayerResponse
interface FootballApi {
// Area
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("areas/{id}")
suspend fun getArea(@Path("id") id: Int): Area
@ -21,10 +23,14 @@ interface FootballApi {
@GET("areas")
suspend fun getAreas(): AreaResponse
// Person
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("persons/{id}")
suspend fun getPlayer(@Path("id") playerId: Int): PlayerResponse
// Competition
@Headers("X-Auth-Token: 621ef06e148542f98b4993a5442421eb")
@GET("competitions")
suspend fun getCompetitions(): CompetitionResponse
@ -33,6 +39,21 @@ interface FootballApi {
@GET("competitions/{id}")
suspend fun getCompetition(@Path("id") id: Int): CompetitionResult
// Team
@Headers("X-Auth-Token: 9983c8c887464274bed01ff046775bed")
@GET("teams?limit=1000")
suspend fun getTeams(): CompetitionResponse
@Headers("X-Auth-Token: 84c47f4211244a0d9b3cb9376e00f4aa")
@GET("competitions/{id}/teams")
suspend fun getTeamsByCompetition(): CompetitionResponse
@Headers("X-Auth-Token: 9983c8c887464274bed01ff046775bed")
@GET("teams/{id}")
suspend fun getTeam(): CompetitionResponse
// Match
@Headers("X-Auth-Token: 7814ffe5b0314b5291a287d32a178e57")
@GET("matches")
suspend fun getMatches(): MatchResponse

@ -0,0 +1,10 @@
package uca.iut.clermont.application
import android.app.Application
import uca.iut.clermont.data.BDD
class ScorItApplication: Application() {
val db: BDD by lazy { BDD.getInstance(this) }
}

@ -0,0 +1,30 @@
package uca.iut.clermont.converters
import androidx.room.TypeConverter
import com.google.gson.Gson
import uca.iut.clermont.model.Area
import uca.iut.clermont.model.Season
class Converters {
@TypeConverter
fun fromJson(json: String): Season {
return Gson().fromJson(json, Season::class.java)
}
@TypeConverter
fun toJson(season: Season): String {
return Gson().toJson(season)
}
@TypeConverter
fun fromJsonArea(json: String): Area {
return Gson().fromJson(json, Area::class.java)
}
@TypeConverter
fun toJson(area: Area): String {
return Gson().toJson(area)
}
}

@ -1,13 +1,13 @@
package uca.iut.clermont.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.*
import uca.iut.clermont.converters.Converters
import uca.iut.clermont.data.dao.CompetitionDao
import uca.iut.clermont.model.Competition
@Database(entities = arrayOf(Competition::class), version = 1)
@TypeConverters(Converters::class)
abstract class BDD : RoomDatabase() {
abstract fun competitionDao(): CompetitionDao
@ -24,6 +24,7 @@ abstract class BDD : RoomDatabase() {
"ScorItDB"
).build()
INSTANCE = db
INSTANCE!!
}
}

@ -1,11 +1,6 @@
package uca.iut.clermont.data
import AreaManager
import CompetitionsManager
import DataManager
import MatchesManager
import PeopleManager
import TeamsManager
import uca.iut.clermont.model.*
import java.util.*

@ -13,10 +13,13 @@ interface CompetitionDao {
@Delete
fun deleteCompetition(competition: Competition)
@Query("SELECT * FROM competition")
@Query("SELECT * FROM competitions")
fun getAllCompetitions(): Flow<List<Competition>>
@Insert
fun insertCompetition(competition: Competition)
@Query("SELECT * FROM competitions WHERE id=:id")
fun getCompetitionById(id: Int): Flow<Competition?>
}

@ -11,6 +11,6 @@ class Competition(
@ColumnInfo val code: String,
@ColumnInfo val type: String,
@ColumnInfo val emblem: String,
@ColumnInfo val currentSeason: Season,
val currentSeason: Season,
val area: Area
)

@ -1,4 +1,4 @@
import uca.iut.clermont.model.*
package uca.iut.clermont.model
abstract class DataManager {
abstract val areaMgr: AreaManager

@ -15,9 +15,11 @@ import uca.iut.clermont.R
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import uca.iut.clermont.application.ScorItApplication
import uca.iut.clermont.model.Competition
import uca.iut.clermont.view.adapter.MatchesAdapter
import uca.iut.clermont.view.viewModel.DetailViewModel
import uca.iut.clermont.view.viewModel.ViewModelFactory
import java.text.SimpleDateFormat
import java.util.*
@ -25,8 +27,9 @@ class DetailFragment : Fragment() {
private var isLiked = false
private lateinit var competition: Competition
private val viewModel: DetailViewModel by viewModels()
private val viewModel: DetailViewModel by viewModels {
ViewModelFactory((requireActivity().application as ScorItApplication).db.competitionDao())
}
override fun onCreateView(
inflater: LayoutInflater,
@ -36,9 +39,9 @@ class DetailFragment : Fragment() {
val view = inflater.inflate(R.layout.fragment_detail, container, false)
val likeButton = view.findViewById<ImageButton>(R.id.buttonLike)
val id = arguments?.getInt("idItem")!!
viewModel.competition.observe(viewLifecycleOwner, Observer { comp ->
comp?.let {
competition = comp
@ -55,6 +58,24 @@ class DetailFragment : Fragment() {
}
})
viewModel.check(id).observe(viewLifecycleOwner, Observer { competition ->
competition?.let {
isLiked = true
likeButton.setImageResource(R.drawable.full_like)
}
})
likeButton.setOnClickListener {
if (isLiked) {
viewModel.deleteCompetition(competition)
likeButton.setImageResource(R.drawable.empty_like)
} else {
viewModel.insertCompetition(competition)
likeButton.setImageResource(R.drawable.full_like)
}
isLiked = !isLiked
}
viewModel.competitionMatches.observe(viewLifecycleOwner, Observer { competitions ->
competitions?.let {
initRecyclerView(view)
@ -62,28 +83,24 @@ class DetailFragment : Fragment() {
}
})
viewModel.loadMatches(id)
return view;
}
private fun initializeView(view: View) {
val button = view.findViewById<ImageButton>(R.id.buttonLike)
val buttonExit = view.findViewById<ImageButton>(R.id.buttonExit)
val imageHeader = view.findViewById<ImageView>(R.id.imageDetail)
val titleHeader = view.findViewById<TextView>(R.id.title)
val nbMatches = view.findViewById<TextView>(R.id.nbMatches)
val dateEnd = view.findViewById<TextView>(R.id.dateEnd)
val dateStart = view.findViewById<TextView>(R.id.dateStart)
buttonExit.setOnClickListener {
findNavController().navigate(R.id.favoriteFragment)
}
val fragmentId = arguments?.getInt("fragmentId")
button.setOnClickListener {
isLiked = !isLiked
button.setImageResource(if (isLiked) R.drawable.full_like else R.drawable.empty_like)
buttonExit.setOnClickListener {
fragmentId?.let {
findNavController().navigate(fragmentId)
}
}
Glide.with(view.context)
@ -124,6 +141,5 @@ class DetailFragment : Fragment() {
)
}
}
}
}

@ -14,13 +14,19 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import uca.iut.clermont.R
import uca.iut.clermont.application.ScorItApplication
import uca.iut.clermont.model.Competition
import uca.iut.clermont.view.adapter.FavoritesAdapter
import uca.iut.clermont.view.adapter.CompetitionsAdapter
import uca.iut.clermont.view.viewModel.FavoriteViewModel
import uca.iut.clermont.view.viewModel.ViewModelFactory
class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener {
class FavoriteFragment : Fragment(), CompetitionsAdapter.OnItemClickListener {
private val viewModel: FavoriteViewModel by viewModels()
private var favorites: List<Competition> = mutableListOf()
private val viewModel: FavoriteViewModel by viewModels {
ViewModelFactory((requireActivity().application as ScorItApplication).db.competitionDao())
}
override fun onCreateView(
inflater: LayoutInflater,
@ -28,14 +34,14 @@ class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener {
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_favorite, container, false)
viewModel.competitions.observe(viewLifecycleOwner, Observer { competitions ->
viewModel.getAllCompetitions().observe(viewLifecycleOwner, Observer { competitions ->
competitions?.let {
favorites = competitions
initRecyclerView(view, competitions, this)
}
})
viewModel.loadCompetitions()
initializeView(view)
return view
@ -61,18 +67,21 @@ class FavoriteFragment : Fragment(), FavoritesAdapter.OnItemClickListener {
private fun initRecyclerView(
view: View,
favorites: List<Competition>,
listener: FavoritesAdapter.OnItemClickListener
listener: CompetitionsAdapter.OnItemClickListener
) {
val recyclerViewFavorites = view.findViewById<RecyclerView>(R.id.listFavorites)
with(recyclerViewFavorites) {
layoutManager = LinearLayoutManager(view.context)
adapter = FavoritesAdapter(favorites.toList().toTypedArray(), listener)
adapter = CompetitionsAdapter(favorites.toList().toTypedArray(), listener)
}
}
override fun onItemClick(position: Int) {
val competitions = viewModel.competitions.value!!
val bundle = bundleOf("idItem" to competitions[position].id)
val bundle = bundleOf(
"idItem" to favorites[position].id,
"fragmentId" to R.id.favoriteFragment
)
findNavController().navigate(R.id.action_favoriteFragment_to_detailFragment, bundle)
}
}

@ -1,11 +1,15 @@
package uca.iut.clermont.view
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageButton
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
@ -13,13 +17,19 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import uca.iut.clermont.R
import uca.iut.clermont.model.Competition
import uca.iut.clermont.model.Match
import uca.iut.clermont.view.adapter.CompetitionsAdapter
import uca.iut.clermont.view.adapter.MatchesAdapter
import uca.iut.clermont.view.viewModel.HomeViewModel
class HomeFragment : Fragment() {
class HomeFragment : Fragment(), CompetitionsAdapter.OnItemClickListener {
private val viewModel: HomeViewModel by viewModels()
private lateinit var searchBar: EditText
private lateinit var searchAdapter: RecyclerView
private var searchList: MutableList<Competition> = mutableListOf()
val viewModel: HomeViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
@ -31,7 +41,10 @@ class HomeFragment : Fragment() {
val buttonFavorite = view.findViewById<ImageButton>(R.id.buttonFavorite)
val restartMatches = view.findViewById<ImageButton>(R.id.restartMatches)
searchAdapter = view.findViewById(R.id.listSearch)
searchBar = view.findViewById(R.id.searchBar);
searchBar.addTextChangedListener(textWatcher);
val text = view.findViewById<TextView>(R.id.textEmpty)
viewModel.matches.observe(viewLifecycleOwner, Observer { matches ->
matches?.let {
@ -43,7 +56,11 @@ class HomeFragment : Fragment() {
}
})
searchAdapter.layoutManager = LinearLayoutManager(view.context)
displayMatches()
viewModel.loadCompetitions()
buttonFavorite.setOnClickListener {
findNavController().navigate(R.id.favoriteFragment)
@ -56,17 +73,66 @@ class HomeFragment : Fragment() {
return view
}
private fun initRecyclerView(view: View, matches: List<Match>) {
private val textWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// No need for the function
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
searchNames(s.toString())
}
override fun afterTextChanged(s: Editable?) {
// No need for the function
}
}
private fun searchNames(query: String) {
val filteredCompetition = viewModel.competitions.value.orEmpty()
.asSequence()
.filter { it.name.lowercase().contains(query.lowercase()) }
.take(3)
.toMutableList()
searchList = filteredCompetition
searchList(filteredCompetition, this)
}
private fun initRecyclerView(
view: View,
matches: List<Match>
) {
val recyclerViewMatches = view.findViewById<RecyclerView>(R.id.listRecentsMatches)
with(recyclerViewMatches) {
layoutManager = LinearLayoutManager(view.context)
adapter = MatchesAdapter(matches.toList().toTypedArray())
}
}
private fun searchList(
competitons: List<Competition>,
listener: CompetitionsAdapter.OnItemClickListener
) {
searchAdapter.adapter = CompetitionsAdapter(competitons.toTypedArray(), listener)
}
private fun displayMatches() {
viewModel.loadMatches()
}
override fun onPause() {
super.onPause()
searchBar.removeTextChangedListener(textWatcher)
}
override fun onItemClick(position: Int) {
val bundle = bundleOf(
"idItem" to searchList[position].id,
"fragmentId" to R.id.homeFragment
)
findNavController().navigate(R.id.action_homeFragment_to_detailFragment, bundle)
}
}

@ -10,11 +10,11 @@ import com.bumptech.glide.Glide
import uca.iut.clermont.R
import uca.iut.clermont.model.Competition
class FavoritesAdapter(
class CompetitionsAdapter(
private val favoriteCompetition: Array<Competition>,
private val listener: OnItemClickListener,
) :
RecyclerView.Adapter<FavoritesAdapter.FavoriteHolder>() {
RecyclerView.Adapter<CompetitionsAdapter.FavoriteHolder>() {
inner class FavoriteHolder(view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {

@ -1,45 +1,69 @@
package uca.iut.clermont.view.viewModel
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import uca.iut.clermont.api.ApiManager
import uca.iut.clermont.data.dao.CompetitionDao
import uca.iut.clermont.model.Competition
import uca.iut.clermont.model.Match
import java.util.*
class DetailViewModel(
//val dao: CompetitionDao
val dao: CompetitionDao
) : ViewModel() {
val ERROR = "too many requests"
val manager = ApiManager()
val competition = MutableLiveData<Competition?>()
val competitionMatches = MutableLiveData<List<Match>>()
val nbCompetitionMatches = MutableLiveData<Int>()
val isFavorite = MutableLiveData<Boolean>()
/*fun insertCompetition(competition: Competition) =
viewModelScope.launch {
fun insertCompetition(competition: Competition) =
viewModelScope.launch(Dispatchers.IO) {
dao.insertCompetition(competition)
}
*/
fun deleteCompetition(competition: Competition) =
viewModelScope.launch(Dispatchers.IO) {
dao.deleteCompetition(competition)
}
fun check(id: Int) = dao.getCompetitionById(id).asLiveData()
fun loadCurrentCompetition(id: Int) = viewModelScope.launch {
val result = manager.competitionsMgr.getItemById(id)
competition.value = result
try {
val result = manager.competitionsMgr.getItemById(id)
competition.value = result
} catch (e: HttpException) {
Log.d(e.toString(), ERROR)
}
}
fun loadMatches(id: Int) = viewModelScope.launch {
val matchResults = manager.matchesMgr.getItemsByCompetition(id)
competitionMatches.value =
matchResults.filter { it.status != "TIMED" && it.status != "SCHEDULED" && it.status != "POSTPONED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
try {
val matchResults = manager.matchesMgr.getItemsByCompetition(id)
competitionMatches.value =
matchResults.filter { it.status != "TIMED" && it.status != "SCHEDULED" && it.status != "POSTPONED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
} catch (e: HttpException) {
Log.d(e.toString(), ERROR)
}
}
fun loadNumberMatches() = viewModelScope.launch {
nbCompetitionMatches.value = competitionMatches.value?.size
try {
nbCompetitionMatches.value = competitionMatches.value?.size
} catch (e: HttpException) {
Log.d(e.toString(), ERROR)
}
}
}

@ -1,25 +1,11 @@
package uca.iut.clermont.view.viewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import uca.iut.clermont.api.ApiManager
import uca.iut.clermont.model.Competition
import androidx.lifecycle.asLiveData
import uca.iut.clermont.data.dao.CompetitionDao
class FavoriteViewModel(
//val dao: CompetitionDao
val dao: CompetitionDao
) : ViewModel() {
val manager = ApiManager()
val competitions = MutableLiveData<List<Competition>>()
//fun getAllCompetitions() = dao.getAllCompetitions()
//.isLiveDate()
fun loadCompetitions() = viewModelScope.launch {
val result = manager.competitionsMgr.getItems()
competitions.value = result
}
fun getAllCompetitions() = dao.getAllCompetitions().asLiveData()
}

@ -1,24 +1,42 @@
package uca.iut.clermont.view.viewModel
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import retrofit2.HttpException
import uca.iut.clermont.api.ApiManager
import uca.iut.clermont.model.Competition
import uca.iut.clermont.model.Match
import java.util.*
class HomeViewModel : ViewModel() {
val ERROR = "too many requests"
val manager = ApiManager()
val matches = MutableLiveData<List<Match>?>()
val competitions = MutableLiveData<List<Competition>>()
fun loadMatches() = viewModelScope.launch {
val matchResults = manager.matchesMgr.getItems()
matches.value = matchResults.filter { it.status != "TIMED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
try {
val matchResults = manager.matchesMgr.getItems()
matches.value = matchResults.filter { it.status != "TIMED" }
.apply { forEach { it.date.add(Calendar.HOUR_OF_DAY, 2) } }
.sortedBy { it.competition.name }
.sortedByDescending { it.date }
} catch (e: HttpException) {
Log.d(e.toString(),ERROR)
}
}
fun loadCompetitions() = viewModelScope.launch {
try {
val result = manager.competitionsMgr.getItems()
competitions.value = result
} catch (e: HttpException) {
Log.d(e.toString(),ERROR)
}
}
}

@ -0,0 +1,19 @@
package uca.iut.clermont.view.viewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import uca.iut.clermont.data.dao.CompetitionDao
class ViewModelFactory(private val dao: CompetitionDao): ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(FavoriteViewModel::class.java)){
return FavoriteViewModel(dao) as T
}
if (modelClass.isAssignableFrom(DetailViewModel::class.java)){
return DetailViewModel(dao) as T
}
throw IllegalArgumentException("Unknown viewModel class")
}
}

@ -50,7 +50,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listFavorites"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

@ -1,9 +1,9 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:paddingHorizontal="30dp">
<FrameLayout
@ -30,9 +30,9 @@
android:layout_height="34dp"
android:layout_gravity="end"
android:background="@android:color/transparent"
android:contentDescription="@string/imageNotFound"
android:scaleType="fitCenter"
android:src="@drawable/icon_like"
android:contentDescription="@string/imageNotFound" />
android:src="@drawable/icon_like" />
</FrameLayout>
@ -91,33 +91,56 @@
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textViewRecentMatches"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Recent Matches"
android:textColor="@color/title"
android:textSize="30dp"
android:textStyle="bold" />
<ImageButton
android:id="@+id/restartMatches"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="right"
android:layout_marginTop="20dp"
android:background="@android:color/transparent"
android:scaleType="fitCenter"
android:src="@drawable/restart" />
</FrameLayout>
<TextView
android:id="@+id/textViewRecentMatches"
android:id="@+id/textEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Recent Matches"
android:textColor="@color/title"
android:textSize="30dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchBarContainer" />
android:textSize="20dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listRecentsMatches"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewRecentMatches"
tools:itemCount="10" />
</LinearLayout>

@ -52,7 +52,7 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listFavorites"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

@ -84,6 +84,14 @@
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/listSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchBarContainer" />
<TextView
android:id="@+id/textViewRecentMatches"
android:layout_width="wrap_content"
@ -94,7 +102,7 @@
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchBarContainer" />
app:layout_constraintTop_toBottomOf="@+id/listSearch" />
<ImageButton
android:id="@+id/restartMatches"
@ -105,7 +113,7 @@
android:scaleType="fitCenter"
android:src="@drawable/restart"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchBarContainer" />
app:layout_constraintTop_toBottomOf="@id/listSearch" />
<TextView
android:id="@+id/textEmpty"

@ -20,6 +20,9 @@
<action
android:id="@+id/action_homeFragment_to_favoriteFragment"
app:destination="@id/favoriteFragment" />
<action
android:id="@+id/action_homeFragment_to_detailFragment"
app:destination="@id/detailFragment" />
</fragment>
<fragment

Loading…
Cancel
Save