diff --git a/README.md b/README.md index c0193b60..8f030a0c 100644 --- a/README.md +++ b/README.md @@ -10,32 +10,33 @@ http://swapi.dev/ http://docs.starwarsfavorites.apiary.io/# -### Lista de Personagens +### ✅ Lista de Personagens Para obter os personagens, sua aplicação deverá utilizar o recurso `people` da Swapi (documentação disponível no topo do documento). A aplicação deve exibir todos os 87 personagens e permitir pesquisar o personagem pelo nome. Sugerimos exibir as primeiras páginas enquanto carrega as outras, em um formato de scroll infinito. A lista de itens deve exibir as seguintes informações: -+ Nome [name] -+ Altura [height] -+ Genero [gender] -+ Peso [mass] + +- Nome [name] +- Altura [height] +- Genero [gender] +- Peso [mass] Os dados devem ser salvos em banco de dados local para acesso offline e atualizados sempre que a tela for aberta. -### Detalhes do Personagem +### ✅ Detalhes do Personagem Ao clicar em um item da lista o seu app deve mostrar as informações abaixo: -+ name -+ height -+ mass -+ hair_color -+ skin_color -+ eye_color -+ birth_year -+ gender -+ Nome do Planeta Natal -+ Nome da Espécie +- name +- height +- mass +- hair_color +- skin_color +- eye_color +- birth_year +- gender +- Nome do Planeta Natal +- Nome da Espécie A busca pelo nome do planeta e da espécie deve ser feita em paralelo. @@ -47,19 +48,22 @@ Na lista e nos detalhes deve ser possível adicionar e remover um personagem a s URL BASE: http://private-782d3-starwarsfavorites.apiary-mock.com/ -Ao adicionar um favorito a aplicação deve fazer um request para a api starwarsfavorites (documentação disponível no topo do documento). +Ao adicionar um favorito a aplicação deve fazer um request para a api starwarsfavorites (documentação disponível no topo do documento). A aplicação deve: -+ Exibir a mensagem de retorno da API em caso de sucesso ou erro. -+ Reenviar a requisição da próxima vez que o app for aberto em caso de erro. -+ Salvar no banco de dados local quais personagens foram favoritados. -+ Tratar a remoção de favoritos apenas no banco de dados local. + +- Exibir a mensagem de retorno da API em caso de sucesso ou erro. +- Reenviar a requisição da próxima vez que o app for aberto em caso de erro. +- Salvar no banco de dados local quais personagens foram favoritados. +- Tratar a remoção de favoritos apenas no banco de dados local. Em metade das requisições enviadas para a api starwarsfavorites a aplicação deve adicionar o header `Prefer` com o valor `status=400`. P.S.: O candidato deve escolher o ID. --- + #### LICENSE + ``` MIT License diff --git a/StarWarsWiki/.gitignore b/StarWarsWiki/.gitignore new file mode 100644 index 00000000..aa724b77 --- /dev/null +++ b/StarWarsWiki/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/StarWarsWiki/.idea/.gitignore b/StarWarsWiki/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/StarWarsWiki/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/StarWarsWiki/.idea/.name b/StarWarsWiki/.idea/.name new file mode 100644 index 00000000..0757cbfb --- /dev/null +++ b/StarWarsWiki/.idea/.name @@ -0,0 +1 @@ +Star Wars Wiki \ No newline at end of file diff --git a/StarWarsWiki/.idea/codeStyles/Project.xml b/StarWarsWiki/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..3c7772a0 --- /dev/null +++ b/StarWarsWiki/.idea/codeStyles/Project.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/codeStyles/codeStyleConfig.xml b/StarWarsWiki/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/StarWarsWiki/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/compiler.xml b/StarWarsWiki/.idea/compiler.xml new file mode 100644 index 00000000..fb7f4a8a --- /dev/null +++ b/StarWarsWiki/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/gradle.xml b/StarWarsWiki/.idea/gradle.xml new file mode 100644 index 00000000..5cd135a0 --- /dev/null +++ b/StarWarsWiki/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/jarRepositories.xml b/StarWarsWiki/.idea/jarRepositories.xml new file mode 100644 index 00000000..a5f05cd8 --- /dev/null +++ b/StarWarsWiki/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/misc.xml b/StarWarsWiki/.idea/misc.xml new file mode 100644 index 00000000..6199cc2a --- /dev/null +++ b/StarWarsWiki/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/runConfigurations.xml b/StarWarsWiki/.idea/runConfigurations.xml new file mode 100644 index 00000000..797acea5 --- /dev/null +++ b/StarWarsWiki/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/.idea/vcs.xml b/StarWarsWiki/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/StarWarsWiki/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/.gitignore b/StarWarsWiki/app/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/StarWarsWiki/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/StarWarsWiki/app/build.gradle b/StarWarsWiki/app/build.gradle new file mode 100644 index 00000000..37419d0d --- /dev/null +++ b/StarWarsWiki/app/build.gradle @@ -0,0 +1,72 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' + id 'kotlin-kapt' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.github.weslleystos" + minSdkVersion 22 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + javaCompileOptions { + annotationProcessorOptions { + arguments["room.incremental"] = "true" + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + viewBinding true + } + buildFeatures { + dataBinding true + } +} + +ext { + retrofit_version = '2.9.0' + room_version = "2.2.6" + paging_version = "2.1.2" +} + +dependencies { + + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.2' + + // Retrofit + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + + // Data binding + kapt 'androidx.databinding:databinding-compiler:4.2.0-beta02' + + // Room + implementation "androidx.room:room-runtime:$room_version" + implementation "androidx.room:room-ktx:$room_version" + kapt "androidx.room:room-compiler:$room_version" +} \ No newline at end of file diff --git a/StarWarsWiki/app/proguard-rules.pro b/StarWarsWiki/app/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/StarWarsWiki/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/AndroidManifest.xml b/StarWarsWiki/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1f098e9e --- /dev/null +++ b/StarWarsWiki/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/App.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/App.kt new file mode 100644 index 00000000..a632e4dd --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/App.kt @@ -0,0 +1,31 @@ +package com.github.weslleystos + +import android.app.Application +import android.content.Context +import androidx.room.Room +import com.github.weslleystos.shared.services.DatabaseService +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +class App : Application() { + companion object { + lateinit var getContext: Context + lateinit var database: DatabaseService + } + + override fun onCreate() { + super.onCreate() + getContext = applicationContext + + database = Room.databaseBuilder( + applicationContext, + DatabaseService::class.java, + "database.db" + ).build() + + GlobalScope.launch(Dispatchers.IO) { + database.clearAllTables() + } + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/MainActivity.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/MainActivity.kt new file mode 100644 index 00000000..4ad06b20 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/MainActivity.kt @@ -0,0 +1,50 @@ +package com.github.weslleystos + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import android.view.Menu +import android.view.MenuItem +import com.github.weslleystos.databinding.ActivityMainBinding + +class MainActivity : AppCompatActivity() { + + private lateinit var appBarConfiguration: AppBarConfiguration + private lateinit var binding: ActivityMainBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + + setSupportActionBar(binding.toolbar) + + val navController = findNavController(R.id.nav_host_fragment_content_main) + appBarConfiguration = AppBarConfiguration(navController.graph) + setupActionBarWithNavController(navController, appBarConfiguration) + + binding.fab.setOnClickListener {} + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_main, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + R.id.action_settings -> true + else -> super.onOptionsItemSelected(item) + } + } + + override fun onSupportNavigateUp(): Boolean { + val navController = findNavController(R.id.nav_host_fragment_content_main) + return navController.navigateUp(appBarConfiguration) + || super.onSupportNavigateUp() + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/repository/remote/DetailsRepository.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/repository/remote/DetailsRepository.kt new file mode 100644 index 00000000..15fa3bd8 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/repository/remote/DetailsRepository.kt @@ -0,0 +1,15 @@ +package com.github.weslleystos.features.details.repository.remote + +import com.github.weslleystos.shared.entities.Planet +import com.github.weslleystos.shared.entities.Specie +import retrofit2.Call +import retrofit2.http.GET +import retrofit2.http.Url + +interface DetailsRepository { + @GET + fun getHomeWorld(@Url url: String): Call + + @GET + fun getSpecie(@Url url: String): Call +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/service/DetailsService.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/service/DetailsService.kt new file mode 100644 index 00000000..43a19a16 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/service/DetailsService.kt @@ -0,0 +1,49 @@ +package com.github.weslleystos.features.details.service + +import androidx.lifecycle.MutableLiveData +import com.github.weslleystos.features.details.repository.remote.DetailsRepository +import com.github.weslleystos.shared.entities.Planet +import com.github.weslleystos.shared.entities.Specie +import com.github.weslleystos.shared.services.RetrofitService +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class DetailsService { + private val detailRepository = RetrofitService().create() + + fun getHomeWorld(url: String, planetLiveData: MutableLiveData>) { + val service = detailRepository.getHomeWorld(url) + service.enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + when { + response.isSuccessful -> planetLiveData.value = Pair(true, response.body()) + else -> planetLiveData.value = Pair(false, null) + } + } + + override fun onFailure(call: Call, t: Throwable) { + planetLiveData.value = Pair(false, null) + } + }) + + } + + fun getSpecie(url: String, specieLiveData: MutableLiveData>) { + val service = detailRepository.getSpecie(url) + service.enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + when { + response.isSuccessful -> specieLiveData.value = Pair(true, response.body()) + else -> specieLiveData.value = Pair(false, null) + } + } + + override fun onFailure(call: Call, t: Throwable) { + specieLiveData.value = Pair(false, null) + } + }) + } + + +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/ui/DetailsFragment.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/ui/DetailsFragment.kt new file mode 100644 index 00000000..d462ce35 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/ui/DetailsFragment.kt @@ -0,0 +1,89 @@ +package com.github.weslleystos.features.details.ui + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer +import com.github.weslleystos.MainActivity +import com.github.weslleystos.R +import com.github.weslleystos.databinding.FragmentDetailBinding +import com.github.weslleystos.features.details.viewmodel.DetailsViewModel +import com.github.weslleystos.shared.entities.People +import com.github.weslleystos.shared.entities.Planet +import com.github.weslleystos.shared.entities.Specie + +class DetailsFragment : Fragment() { + + private var _binding: FragmentDetailBinding? = null + private val binding get() = _binding!! + private val detailsViewModel: DetailsViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentDetailBinding.inflate(inflater, container, false) + return binding.root + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val people = arguments?.get("people") as People + + (activity as MainActivity).supportActionBar?.title = people.name + binding.people = people + + detailsViewModel.specieLiveData.observe(viewLifecycleOwner, specieObserver) + detailsViewModel.planetLiveData.observe(viewLifecycleOwner, planetObserver) + + if (people.homeWorld.isNotEmpty()) { + detailsViewModel.getHomeWorld(people.homeWorld) + } + + if (!people.specie.isNullOrEmpty()) { + detailsViewModel.getSpecie(people.specie!!) + } + } + + private val specieObserver = Observer> { response -> + when { + response.first -> { + binding.specie.visibility = View.VISIBLE + binding.specieName.text = response.second?.name + } + else -> { + Toast.makeText( + context, + getString(R.string.species_not_found), + Toast.LENGTH_SHORT + ).show() + } + } + } + + private val planetObserver = Observer> { response -> + when { + response.first -> { + binding.planet.visibility = View.VISIBLE + binding.planetName.text = response.second?.name + } + else -> { + Toast.makeText( + context, + getString(R.string.planets_not_found), + Toast.LENGTH_SHORT + ).show() + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/viewmodel/DetailsViewModel.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/viewmodel/DetailsViewModel.kt new file mode 100644 index 00000000..fe85c550 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/details/viewmodel/DetailsViewModel.kt @@ -0,0 +1,20 @@ +package com.github.weslleystos.features.details.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.github.weslleystos.features.details.service.DetailsService +import com.github.weslleystos.shared.entities.Planet +import com.github.weslleystos.shared.entities.Specie + +class DetailsViewModel : ViewModel() { + val planetLiveData: MutableLiveData> = MutableLiveData() + val specieLiveData: MutableLiveData> = MutableLiveData() + + fun getHomeWorld(url: String) { + DetailsService().getHomeWorld(url, planetLiveData) + } + + fun getSpecie(url: String) { + DetailsService().getSpecie(url, specieLiveData) + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/local/IPeopleListDao.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/local/IPeopleListDao.kt new file mode 100644 index 00000000..4834007e --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/local/IPeopleListDao.kt @@ -0,0 +1,16 @@ +package com.github.weslleystos.features.list.repository.local + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.github.weslleystos.shared.entities.People + +@Dao +interface IPeopleListDao { + @Query("SELECT * FROM peoples ORDER BY id LIMIT :limit OFFSET :offset") + fun getAll(offset: Int, limit: Int = 10): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(vararg peoples: People) +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/remote/IPeopleListRepository.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/remote/IPeopleListRepository.kt new file mode 100644 index 00000000..2241a260 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/repository/remote/IPeopleListRepository.kt @@ -0,0 +1,18 @@ +package com.github.weslleystos.features.list.repository.remote + +import com.github.weslleystos.shared.entities.People +import retrofit2.Call +import retrofit2.http.GET +import retrofit2.http.Query + +interface IPeopleListRepository { + @GET("people/") + fun getAll(@Query("page") page: Int): Call +} + +data class Response( + val count: Int, + val next: Any, + val previous: String, + val results: List +) \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/services/PeopleListService.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/services/PeopleListService.kt new file mode 100644 index 00000000..4dba51bb --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/services/PeopleListService.kt @@ -0,0 +1,63 @@ +package com.github.weslleystos.features.list.services + +import androidx.lifecycle.MutableLiveData +import com.github.weslleystos.App +import com.github.weslleystos.features.list.repository.remote.IPeopleListRepository +import com.github.weslleystos.features.list.repository.remote.Response +import com.github.weslleystos.shared.entities.People +import com.github.weslleystos.shared.services.RetrofitService +import com.github.weslleystos.shared.utils.LiveDateState +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import retrofit2.Call +import retrofit2.Callback + + +class PeopleListService { + private val peoplesDao = App.database.peoplesDao() + private val peoplesService = RetrofitService().create() + + fun getAll(page: Int, peoplesLiveData: MutableLiveData?>>) { + val peoples = peoplesDao.getAll(page * 10) + if (peoples.isEmpty()) { + val service = peoplesService.getAll(page + 1) + service.enqueue(object : Callback { + override fun onResponse( + call: Call, + response: retrofit2.Response + ) { + when { + response.isSuccessful -> { + val results = response.body()!!.results + peoplesLiveData.postValue(Pair(LiveDateState.FETCHED, results)) + persistInDatabase(parseData(results)) + } + else -> peoplesLiveData.postValue(Pair(LiveDateState.FAILED, null)) + } + } + + override fun onFailure(call: Call, t: Throwable) { + peoplesLiveData.postValue(Pair(LiveDateState.FAILED, null)) + } + }) + } else { + peoplesLiveData.postValue(Pair(LiveDateState.FETCHED, peoples)) + } + } + + private fun parseData(results: List): List { + results.forEach { people -> + if (people.species?.size != 0) { + people.specie = people.species?.get(0) + } + } + return results + } + + private fun persistInDatabase(results: List) { + GlobalScope.launch(Dispatchers.IO) { + peoplesDao.insertAll(peoples = results.toTypedArray()) + } + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesAdapter.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesAdapter.kt new file mode 100644 index 00000000..22a14424 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesAdapter.kt @@ -0,0 +1,67 @@ +package com.github.weslleystos.features.list.ui + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.os.bundleOf +import androidx.navigation.fragment.findNavController +import androidx.recyclerview.widget.RecyclerView +import com.github.weslleystos.R +import com.github.weslleystos.databinding.PeoplesRowBinding +import com.github.weslleystos.shared.entities.People + +class PeoplesAdapter(private val fragment: PeoplesList) : + RecyclerView.Adapter() { + private val dataset = mutableListOf() + private val peoples = mutableListOf() + + fun setPeoples(peoples: List) { + val oldSize = this.dataset.size + this.dataset.addAll(peoples) + this.peoples.addAll(peoples) + notifyItemRangeInserted(oldSize, this.dataset.size) + } + + fun setFilter(word: String) { + this.dataset.clear() + if (word.isBlank()) { + fragment.isSearching = false + this.dataset.addAll(peoples) + } else { + fragment.isSearching = true + val filteredPeoples = peoples.filter { people -> people.name.contains(word, true) } + this.dataset.addAll(filteredPeoples) + } + notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PeopleVH { + return PeopleVH( + PeoplesRowBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: PeopleVH, position: Int) { + holder.bind(dataset[position]) + } + + override fun getItemCount() = dataset.size + + inner class PeopleVH(private val binding: PeoplesRowBinding) : + RecyclerView.ViewHolder(binding.root) { + + fun bind(people: People) { + binding.people = people + binding.container.setOnClickListener { + fragment.peoplesViewModel.clearLiveData() + fragment.findNavController().navigate( + R.id.action_PeopleListFragment_to_DetailFragment, + bundleOf("people" to people) + ) + } + } + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesList.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesList.kt new file mode 100644 index 00000000..0a4b93b0 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/ui/PeoplesList.kt @@ -0,0 +1,120 @@ +package com.github.weslleystos.features.list.ui + +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.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.Observer +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.OnScrollListener +import com.github.weslleystos.MainActivity +import com.github.weslleystos.R +import com.github.weslleystos.databinding.FragmentPeopleListBinding +import com.github.weslleystos.features.list.viewmodel.PeopleListViewModel +import com.github.weslleystos.shared.entities.People +import com.github.weslleystos.shared.utils.LiveDateState +import com.github.weslleystos.shared.utils.hide +import com.github.weslleystos.shared.utils.show + +class PeoplesList : Fragment() { + var isSearching = false + private var currentPage = 0 + private var isLoading = false + private lateinit var peoplesAdapter: PeoplesAdapter + private var _binding: FragmentPeopleListBinding? = null + val peoplesViewModel: PeopleListViewModel by viewModels() + + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentPeopleListBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + currentPage = 0 + (activity as MainActivity).supportActionBar?.title = + getString(R.string.fragmet_list_people_title) + + val linearLayoutManager = LinearLayoutManager(context) + peoplesAdapter = PeoplesAdapter(this) + + val divider = DividerItemDecoration(context, DividerItemDecoration.VERTICAL) + + val recyclerView = binding.recyclerPeoples + recyclerView.apply { + layoutManager = linearLayoutManager + adapter = peoplesAdapter + addItemDecoration(divider) + addOnScrollListener(endlessScrolling) + } + + binding.searchBar.addTextChangedListener(searchTextWatch) + + peoplesViewModel.peoplesLiveData.observe(viewLifecycleOwner, observer) + + peoplesViewModel.getAll(currentPage) + } + + private val observer = Observer?>> { response -> + isLoading = false + binding.progressCircular.hide() + when (response.first) { + LiveDateState.FETCHED -> { + currentPage++ + peoplesAdapter.setPeoples(response.second!!) + } + LiveDateState.FAILED -> { + Toast.makeText( + context, + getString(R.string.peoples_not_found), + Toast.LENGTH_SHORT + ).show() + } + } + } + + private fun fetchPeoples() { + isLoading = true + binding.progressCircular.show() + peoplesViewModel.getAll(currentPage) + } + + private val endlessScrolling = object : OnScrollListener() { + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + val layoutManager = recyclerView.layoutManager!! as LinearLayoutManager + val lastItem = layoutManager.findLastVisibleItemPosition() + 1 + val totalItems = layoutManager.itemCount + + if (!isLoading && !isSearching && lastItem == totalItems) { + fetchPeoples() + } + } + } + + private val searchTextWatch = object : TextWatcher { + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + peoplesAdapter.setFilter(s.toString()) + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + override fun afterTextChanged(s: Editable?) {} + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/viewmodel/PeopleListViewModel.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/viewmodel/PeopleListViewModel.kt new file mode 100644 index 00000000..15fbf008 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/features/list/viewmodel/PeopleListViewModel.kt @@ -0,0 +1,24 @@ +package com.github.weslleystos.features.list.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.github.weslleystos.features.list.services.PeopleListService +import com.github.weslleystos.shared.entities.People +import com.github.weslleystos.shared.utils.LiveDateState +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class PeopleListViewModel : ViewModel() { + val peoplesLiveData: MutableLiveData?>> = MutableLiveData() + + fun getAll(page: Int) { + viewModelScope.launch(Dispatchers.IO) { + PeopleListService().getAll(page, peoplesLiveData) + } + } + + fun clearLiveData() { + peoplesLiveData.value = Pair(LiveDateState.HANDLED, null) + } +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/People.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/People.kt new file mode 100644 index 00000000..e63b1812 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/People.kt @@ -0,0 +1,48 @@ +package com.github.weslleystos.shared.entities + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.Ignore +import androidx.room.PrimaryKey +import com.google.gson.annotations.SerializedName +import java.io.Serializable + +@Entity(tableName = "peoples") +class People( + @PrimaryKey(autoGenerate = true) + var id: Int +) : Serializable { + + lateinit var name: String + + lateinit var height: String + + lateinit var mass: String + + @ColumnInfo(name = "hair_color") + @SerializedName("hair_color") + lateinit var hairColor: String + + @ColumnInfo(name = "skin_color") + @SerializedName("skin_color") + lateinit var skinColor: String + + @ColumnInfo(name = "eye_color") + @SerializedName("eye_color") + lateinit var eyeColor: String + + @ColumnInfo(name = "birth_year") + @SerializedName("birth_year") + lateinit var birthYear: String + + lateinit var gender: String + + @ColumnInfo(name = "homeworld") + @SerializedName("homeworld") + lateinit var homeWorld: String + + var specie: String? = null + + @Ignore + val species: List? = null +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Planet.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Planet.kt new file mode 100644 index 00000000..87c373e5 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Planet.kt @@ -0,0 +1,10 @@ +package com.github.weslleystos.shared.entities + +data class Planet( + val climate: String, + val diameter: String, + val gravity: String, + val name: String, + val population: String, + val terrain: String +) \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Specie.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Specie.kt new file mode 100644 index 00000000..04d13da9 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/entities/Specie.kt @@ -0,0 +1,7 @@ +package com.github.weslleystos.shared.entities + +data class Specie( + val classification: String, + val designation: String, + val name: String, +) \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/DatabaseService.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/DatabaseService.kt new file mode 100644 index 00000000..bcec9e90 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/DatabaseService.kt @@ -0,0 +1,11 @@ +package com.github.weslleystos.shared.services + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.github.weslleystos.features.list.repository.local.IPeopleListDao +import com.github.weslleystos.shared.entities.People + +@Database(entities = [People::class], version = 1, exportSchema = false) +abstract class DatabaseService : RoomDatabase() { + abstract fun peoplesDao(): IPeopleListDao +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/RetrofitService.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/RetrofitService.kt new file mode 100644 index 00000000..fa08c000 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/services/RetrofitService.kt @@ -0,0 +1,18 @@ +package com.github.weslleystos.shared.services + +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class RetrofitService { + companion object { + private const val URL = "https://swapi.dev/api/" + + val retrofit: Retrofit = Retrofit.Builder() + .baseUrl(URL) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + } + + inline fun create(): T = retrofit.create(T::class.java) +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/Extensions.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/Extensions.kt new file mode 100644 index 00000000..1afcfa32 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/Extensions.kt @@ -0,0 +1,15 @@ +package com.github.weslleystos.shared.utils + +import android.view.View +import android.widget.ProgressBar + +fun ProgressBar.show() { + this.visibility = View.VISIBLE +} + +fun ProgressBar.hide() { + this.visibility = View.GONE +} + + + diff --git a/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/LiveDateState.kt b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/LiveDateState.kt new file mode 100644 index 00000000..607dd872 --- /dev/null +++ b/StarWarsWiki/app/src/main/java/com/github/weslleystos/shared/utils/LiveDateState.kt @@ -0,0 +1,7 @@ +package com.github.weslleystos.shared.utils + +enum class LiveDateState { + HANDLED, + FETCHED, + FAILED +} \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/StarWarsWiki/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..2b068d11 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_gender.xml b/StarWarsWiki/app/src/main/res/drawable/ic_gender.xml new file mode 100644 index 00000000..d9ebadae --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_gender.xml @@ -0,0 +1,9 @@ + + + diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_height.xml b/StarWarsWiki/app/src/main/res/drawable/ic_height.xml new file mode 100644 index 00000000..9c3d03d5 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_height.xml @@ -0,0 +1,9 @@ + + + diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_launcher_background.xml b/StarWarsWiki/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..07d5da9c --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_mass.xml b/StarWarsWiki/app/src/main/res/drawable/ic_mass.xml new file mode 100644 index 00000000..4c034865 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_mass.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_star.xml b/StarWarsWiki/app/src/main/res/drawable/ic_star.xml new file mode 100644 index 00000000..16d8f975 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_star.xml @@ -0,0 +1,9 @@ + + + diff --git a/StarWarsWiki/app/src/main/res/drawable/ic_star_border.xml b/StarWarsWiki/app/src/main/res/drawable/ic_star_border.xml new file mode 100644 index 00000000..2bdad2e9 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/drawable/ic_star_border.xml @@ -0,0 +1,9 @@ + + + diff --git a/StarWarsWiki/app/src/main/res/layout/activity_main.xml b/StarWarsWiki/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..aa931112 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/layout/content_main.xml b/StarWarsWiki/app/src/main/res/layout/content_main.xml new file mode 100644 index 00000000..c7d608cb --- /dev/null +++ b/StarWarsWiki/app/src/main/res/layout/content_main.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/layout/fragment_detail.xml b/StarWarsWiki/app/src/main/res/layout/fragment_detail.xml new file mode 100644 index 00000000..5f14af85 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/layout/fragment_detail.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/layout/fragment_people_list.xml b/StarWarsWiki/app/src/main/res/layout/fragment_people_list.xml new file mode 100644 index 00000000..4f09246e --- /dev/null +++ b/StarWarsWiki/app/src/main/res/layout/fragment_people_list.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/layout/peoples_row.xml b/StarWarsWiki/app/src/main/res/layout/peoples_row.xml new file mode 100644 index 00000000..0e756964 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/layout/peoples_row.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/menu/menu_main.xml b/StarWarsWiki/app/src/main/res/menu/menu_main.xml new file mode 100644 index 00000000..03b0aca2 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..eca70cfe --- /dev/null +++ b/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..eca70cfe --- /dev/null +++ b/StarWarsWiki/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher.png b/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..a571e600 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000..61da551c Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher.png b/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..c41dd285 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000..db5080a7 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..6dba46da Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000..da31a871 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..15ac6817 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..b216f2d3 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..f25a4197 Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..e96783cc Binary files /dev/null and b/StarWarsWiki/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/StarWarsWiki/app/src/main/res/navigation/nav_graph.xml b/StarWarsWiki/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 00000000..1b434369 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/values-night/themes.xml b/StarWarsWiki/app/src/main/res/values-night/themes.xml new file mode 100644 index 00000000..943706a0 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/values/colors.xml b/StarWarsWiki/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..f8c6127d --- /dev/null +++ b/StarWarsWiki/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/values/dimens.xml b/StarWarsWiki/app/src/main/res/values/dimens.xml new file mode 100644 index 00000000..125df871 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/values/dimens.xml @@ -0,0 +1,3 @@ + + 16dp + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/values/strings.xml b/StarWarsWiki/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..81ade8c7 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/values/strings.xml @@ -0,0 +1,31 @@ + + Star Wars Wiki + Settings + + People List + Detail Fragment + Next + Previous + + Hello first fragment + Hello second fragment. Arg: %1$s + Icone de altura + Icone de gênero + Icone de peso + Não foi possível carregar mais personagens! + Não foi possível carregar a especie! + Não foi possível carregar o planeta! + Botão de favorito + Digite aqui para pesquisar! + Star Wars Wiki + Peso + Nome + Altura + Cor do cabelo + Cor da pele + Cor do olho + Ano de aniversário + Gênero + Planeta Natal + Especie + \ No newline at end of file diff --git a/StarWarsWiki/app/src/main/res/values/themes.xml b/StarWarsWiki/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..690b0159 --- /dev/null +++ b/StarWarsWiki/app/src/main/res/values/themes.xml @@ -0,0 +1,31 @@ + + + + + + + + +