Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajustando o conteúdo das Activitys e a navegação #89

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions solutions/devsprint-bruno-almeida-2/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ dependencies {
//Material Design para tabs
implementation 'com.google.android.material:material:1.4.0'

//lifecycle viewmodel
implementation "androidx.activity:activity-ktx:1.3.1"
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'

//Viewpager
implementation 'androidx.viewpager2:viewpager2:1.0.0'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.devpass.spaceapp">

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

<application
android:allowBackup="true"
Expand All @@ -11,7 +11,20 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SpaceApp">

<activity
android:name=".presentation.RocketDetailsActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".presentation.LaunchActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".presentation.nextlaunches.NextLaunchesActivity"
android:exported="true">
Expand All @@ -21,10 +34,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".presentation.LaunchDetailsActivity"
android:exported="true"/>
android:exported="true" />

<meta-data
android:name="preloaded_fonts"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.devpass.spaceapp

import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

const val BASE_URL = "https://api.spacexdata.com/v5/"
const val BASE_URL = "https://api.spacexdata.com/v4/"

object RetrofitService {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.devpass.spaceapp.data.api

import com.devpass.spaceapp.data.model.RocketDetailResponse
import retrofit2.http.GET
import retrofit2.http.Query

interface RocketdetailAPIClient {

@GET("rockets")
suspend fun getRocketDetails(@Query("id") id: String): List<RocketDetailResponse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.devpass.spaceapp.data.datasource

import com.devpass.spaceapp.data.api.RocketdetailAPIClient
import com.devpass.spaceapp.data.model.RocketDetailResponse

class RocketDetailsDataSource(private val rocketdetailAPIClient: RocketdetailAPIClient) {
suspend fun getRocketDetails(id: String) : RocketDetailResponse {
return rocketdetailAPIClient.getRocketDetails(id)[0]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.devpass.spaceapp.data.model

import java.io.Serializable

data class RocketDetailResponse(
val id: String,
val name: String,
val flickr_images: List<String>,
val description: String
) : Serializable
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.devpass.spaceapp.data.repository

import com.devpass.spaceapp.data.datasource.RocketDetailsDataSource
import com.devpass.spaceapp.data.model.RocketDetailResponse

class RocketDetailsRepository(private val rocketDetailsDataSource: RocketDetailsDataSource) {

suspend fun getRocketDetails(id: String): Result<RocketDetailResponse> {
return handleResult(rocketDetailsDataSource.getRocketDetails(id))
}

private fun handleResult(rocketDetails: RocketDetailResponse): Result<RocketDetailResponse> {
return try {
Result.success(rocketDetails)
} catch (e: Exception) {
Result.failure(e)
}
}
}





Original file line number Diff line number Diff line change
@@ -1,4 +1,83 @@
package com.devpass.spaceapp.presentation

class LaunchActivity {
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

import com.bumptech.glide.Glide
import com.devpass.spaceapp.R
import com.devpass.spaceapp.RetrofitService
import com.devpass.spaceapp.data.api.RocketdetailAPIClient
import com.devpass.spaceapp.data.datasource.RocketDetailsDataSource
import com.devpass.spaceapp.data.model.NextLaunchesModel
import com.devpass.spaceapp.data.repository.RocketDetailsRepository

import com.devpass.spaceapp.databinding.ActivityLaunchBinding
import com.google.android.material.tabs.TabLayoutMediator

class LaunchActivity : AppCompatActivity() {

private val service = RetrofitService.retrofit.create(RocketdetailAPIClient::class.java)
private val rocketDetailsDataSource = RocketDetailsDataSource(service)
private val repository:RocketDetailsRepository = RocketDetailsRepository(rocketDetailsDataSource)
private val rocketDetailsViewModel = RocketDetailsViewModel(repository)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityLaunchBinding.inflate(layoutInflater)
setContentView(binding.root)

// Recuperar o objeto launch da intent
val launch = intent.getSerializableExtra("nextLaunch") as NextLaunchesModel

// Preencher os campos com as informações do objeto launch
binding.apply {
launchTitleTextView.text = launch.name
launchDateTextView.text = launch.date_utc
launchStatusTextView.text = launch.status.toString()
}

if(launch.links.image.small.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não está errado, mas nesse caso a gente pode colocar a função no Glide .error("drawable desejado") assim a gente evita de fazer um if sem "tanta necessidade"

// caso a URL da imagem seja nula ou vazia, carrega uma imagem padrão
Glide.with(this)
.load(R.drawable.space_logo)
.circleCrop()
.into(binding.launchImage)
} else {
// carrega a imagem usando Glide
Glide.with(this)
.load(launch.links.image.small)
.circleCrop()
.into(binding.launchImage)
}

rocketDetailsViewModel.rocketDetail.observe(this) { result ->
result.onSuccess { rocketDetail ->
Log.d("LaunchActivity", "Rocket Detail: $rocketDetail")
// faça algo com os dados de RocketDetail
}.onFailure { exception ->
Log.e("LaunchActivity", "Failed to fetch rocket detail", exception)
// trate o erro
}
}

rocketDetailsViewModel.getRocketDetail(launch.id)

// Cria uma instância do LaunchDetailsPagerAdapter com as informações do lançamento
val launchDetailsPagerAdapter = LaunchDetailsPagerAdapter(this, launch)

// Configura o ViewPager para usar o adapter
binding.viewPager.adapter = launchDetailsPagerAdapter

// Adiciona as abas ao TabLayout
val titles = arrayOf(getString(R.string.tab_title_details), getString(R.string.tab_title_launchpad), getString(R.string.tab_title_rocket))
for (title in titles) {
binding.tabLayout.addTab(binding.tabLayout.newTab().setText(title))
}

// Conecta o TabLayout e ViewPager
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = titles[position]
}.attach()
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.devpass.spaceapp.presentation

import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.devpass.spaceapp.R
import com.devpass.spaceapp.data.model.NextLaunchesModel
import com.devpass.spaceapp.databinding.ActivityLaunchDetailsBinding
import com.google.android.material.tabs.TabLayoutMediator

private const val ARG_LAUNCH = "fullLaunchDescription"

class LaunchDetailsActivity : AppCompatActivity() {

Expand All @@ -15,42 +15,28 @@ class LaunchDetailsActivity : AppCompatActivity() {
val binding = ActivityLaunchDetailsBinding.inflate(layoutInflater)
setContentView(binding.root)

// Recuperar o objeto launch da intent
val launch = intent.getSerializableExtra("nextLaunch") as NextLaunchesModel
// Configurar a Toolbar como a ActionBar da Activity
setSupportActionBar(binding.toolbar2)

// Preencher os campos com as informações do objeto launch
binding.launchTitleTextView.text = launch.name
binding.launchDateTextView.text = launch.date_utc.toString()
binding.launchStatusTextView.text = launch.status.toString()
if(launch.links.image.small.isEmpty()) {
// caso a URL da imagem seja nula ou vazia, carrega uma imagem padrão
Glide.with(this)
.load(R.drawable.space_logo)
.circleCrop()
.into(binding.launchImage)
} else {
// carrega a imagem usando Glide
Glide.with(this)
.load(launch.links.image.small)
.circleCrop()
.into(binding.launchImage)
}
// Habilitar o botão de voltar na Toolbar
supportActionBar?.setDisplayHomeAsUpEnabled(true)

// Cria uma instância do LaunchDetailsPagerAdapter com as informações do lançamento
val launchDetailsPagerAdapter = LaunchDetailsPagerAdapter(this, launch)
// Definir o ícone personalizado de retorno na Toolbar
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_back_arrow)

// Configura o ViewPager para usar o adapter
binding.viewPager.adapter = launchDetailsPagerAdapter
// Recuperar o objeto launch da intent
val details = intent.getCharSequenceExtra(ARG_LAUNCH)

// Adiciona as abas ao TabLayout
val titles = arrayOf("Overview", "Mission", "Rocket")
for (title in titles) {
binding.tabLayout.addTab(binding.tabLayout.newTab().setText(title))
}
// Preencher os campos com as informações do objeto launch
binding.launchDescriptionTextView.text = details
}

// Conecta o TabLayout e ViewPager
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.text = titles[position]
}.attach()
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
// Quando o botão de voltar na Toolbar é pressionado, finaliza a activity atual
finish()
return true
}
return super.onOptionsItemSelected(item)
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.devpass.spaceapp.presentation

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.devpass.spaceapp.R
import com.devpass.spaceapp.data.model.NextLaunchesModel
import com.devpass.spaceapp.databinding.FragmentLaunchDetailsBinding

Expand All @@ -16,7 +18,6 @@ class LaunchDetailsFragment : Fragment() {
private var _binding: FragmentLaunchDetailsBinding? = null
private val binding get() = _binding!!


override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
Expand All @@ -31,8 +32,21 @@ class LaunchDetailsFragment : Fragment() {
// Recupera o objeto NextLaunchesModel dos argumentos
val launch = arguments?.getSerializable(ARG_LAUNCH) as NextLaunchesModel?

// Exibe o nome da missão em um TextView
binding.launchDescription.text = launch?.name ?: "Nome da missão desconhecido"
val fullDescription = launch?.details ?: getString(R.string.details_load_error)

binding.launchDescriptionFragment.text = fullDescription

val viewMore = getString(R.string.view_more)

val viewMoreLink = binding.launchViewMore

viewMoreLink.text = viewMore

viewMoreLink.setOnClickListener {
val intent = Intent(context, LaunchDetailsActivity::class.java)
intent.putExtra("fullLaunchDescription", fullDescription)
startActivity(intent)
}
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
package com.devpass.spaceapp.presentation

class RocketDetailsActivity {
}
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

import com.devpass.spaceapp.databinding.ActivityRocketDetailsBinding

class RocketDetailsActivity : AppCompatActivity() {
private lateinit var binding: ActivityRocketDetailsBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityRocketDetailsBinding.inflate(layoutInflater)
setContentView(binding.root)

}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.devpass.spaceapp.presentation

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.devpass.spaceapp.data.model.RocketDetailResponse
import com.devpass.spaceapp.data.repository.RocketDetailsRepository

import androidx.lifecycle.LiveData

import androidx.lifecycle.viewModelScope

import kotlinx.coroutines.launch

class RocketDetailsViewModel(private val repository: RocketDetailsRepository) : ViewModel() {

private val _rocketDetail = MutableLiveData<Result<RocketDetailResponse>>()
val rocketDetail: LiveData<Result<RocketDetailResponse>>
get() = _rocketDetail

fun getRocketDetail(id: String){
viewModelScope.launch {
_rocketDetail.value = repository.getRocketDetails(id)
}
}
}


Loading