diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..30bab2a
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..0897082
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..824785d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/other.xml b/.idea/other.xml
new file mode 100644
index 0000000..104e542
--- /dev/null
+++ b/.idea/other.xml
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index d3941a7..18fbdae 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,12 +1,20 @@
+import java.util.Properties
+
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
+ id("kotlin-parcelize")
}
android {
namespace = "com.alom.androidstudy2"
compileSdk = 34
+ buildFeatures {
+ viewBinding = true
+ buildConfig = true
+ }
+
defaultConfig {
applicationId = "com.alom.androidstudy2"
minSdk = 26
@@ -15,6 +23,7 @@ android {
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ buildConfigField ("String", "API_KEY", getApiKey("API_KEY"))
}
buildTypes {
@@ -32,7 +41,27 @@ android {
}
}
+fun getApiKey(propertyKey: String): String {
+ val properties = Properties()
+ val localPropertiesFile = rootProject.file("local.properties")
+ if (localPropertiesFile.exists()) {
+ properties.load(localPropertiesFile.inputStream())
+ }
+ return properties.getProperty(propertyKey)
+}
+
dependencies {
+ implementation(libs.lifecycle.viewmodel.ktx)
+ implementation(libs.lifecycle.livedata.ktx)
+ implementation(libs.lifecycle.runtime.ktx)
+
+ implementation(libs.retrofit)
+ implementation(libs.converter.gson)
+ implementation(libs.okhttp)
+ implementation(libs.logging.interceptor)
+
+ implementation(libs.glide)
+ annotationProcessor(libs.compiler)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0acee2a..8e4dd4f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
+
+
+
diff --git a/app/src/main/java/com/alom/androidstudy2/Adapter.kt b/app/src/main/java/com/alom/androidstudy2/Adapter.kt
new file mode 100644
index 0000000..544fcd7
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/Adapter.kt
@@ -0,0 +1,44 @@
+package com.alom.androidstudy2
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import com.alom.androidstudy2.data.Item
+import com.alom.androidstudy2.databinding.ItemSampleBinding
+import com.bumptech.glide.Glide
+
+class Adapter: ListAdapter- (diffUtil) {
+ inner class ItemViewHolder(private val binding: ItemSampleBinding): RecyclerView.ViewHolder(binding.root) {
+ fun bind(itemModel: Item) {
+ binding.tvTitle.text = itemModel.title
+ binding.tvPrice.text = itemModel.price
+ binding.tvTime.text = itemModel.time
+ Glide
+ .with(binding.image.context)
+ .load(itemModel.imageUrl)
+ .into(binding.image)
+ }
+ }
+
+ companion object {
+ val diffUtil = object:DiffUtil.ItemCallback
- () {
+ override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
+ return oldItem.id == newItem.id
+ }
+
+ override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
+ return oldItem == newItem
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
+ return ItemViewHolder(ItemSampleBinding.inflate(LayoutInflater.from(parent.context), parent, false))
+ }
+
+ override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
+ holder.bind(currentList[position])
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/ApiService.kt b/app/src/main/java/com/alom/androidstudy2/ApiService.kt
new file mode 100644
index 0000000..89f302e
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/ApiService.kt
@@ -0,0 +1,18 @@
+package com.alom.androidstudy2
+
+import com.alom.androidstudy2.data.Request
+import com.alom.androidstudy2.data.ResponseData
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.POST
+
+interface ApiService {
+ @POST("rpc/add_item1")
+ fun addItem (
+ @Body body: Request
+ ): Call
+
+ @POST("rpc/get_item1")
+ fun getItem(): Call
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/MainActivity.kt b/app/src/main/java/com/alom/androidstudy2/MainActivity.kt
deleted file mode 100644
index 54ce3ce..0000000
--- a/app/src/main/java/com/alom/androidstudy2/MainActivity.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.alom.androidstudy2
-
-import android.os.Bundle
-import androidx.activity.enableEdgeToEdge
-import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
-
-class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContentView(R.layout.activity_main)
- ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
- val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
- v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
- insets
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/Repository.kt b/app/src/main/java/com/alom/androidstudy2/Repository.kt
new file mode 100644
index 0000000..6f3fff1
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/Repository.kt
@@ -0,0 +1,10 @@
+package com.alom.androidstudy2
+
+import com.alom.androidstudy2.data.Item
+import com.alom.androidstudy2.data.Request
+import kotlinx.coroutines.flow.Flow
+
+interface Repository {
+ suspend fun getItem(): Flow
>
+ suspend fun addItem(request: Request): Result
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/RepositoryImpl.kt b/app/src/main/java/com/alom/androidstudy2/RepositoryImpl.kt
new file mode 100644
index 0000000..05e11bd
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/RepositoryImpl.kt
@@ -0,0 +1,37 @@
+package com.alom.androidstudy2
+
+import com.alom.androidstudy2.data.Item
+import com.alom.androidstudy2.data.Request
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flow
+import retrofit2.await
+import retrofit2.awaitResponse
+
+class RepositoryImpl: Repository {
+ override suspend fun getItem(): Flow> = flow {
+ try {
+ val response = Retrofit.instance.getItem().awaitResponse()
+ if (response.isSuccessful) {
+ emit(response.body()?.data ?: emptyList())
+ } else {
+ emit(emptyList())
+ }
+ } catch (e: Exception) {
+ emit(emptyList())
+ }
+ }
+
+ override suspend fun addItem(request: Request): Result {
+ return try {
+ val response = Retrofit.instance.addItem(request).awaitResponse()
+ if (response.isSuccessful) {
+ Result.success(Unit)
+ } else {
+ Result.failure(Exception("Failed to add Item"))
+ }
+ } catch (e: Exception) {
+ Result.failure(e)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/Retrofit.kt b/app/src/main/java/com/alom/androidstudy2/Retrofit.kt
new file mode 100644
index 0000000..86e7da1
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/Retrofit.kt
@@ -0,0 +1,40 @@
+package com.alom.androidstudy2
+
+import android.util.Log
+import okhttp3.Interceptor
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import java.util.concurrent.TimeUnit
+
+
+object Retrofit {
+ private const val BASE_URL = "https://goaplrynweyxovekoezl.supabase.co/rest/v1/"
+
+ val instance : ApiService by lazy {
+ val logging = HttpLoggingInterceptor()
+ logging.setLevel(HttpLoggingInterceptor.Level.BODY)
+
+ val apiKeyInterceptor = Interceptor { chain ->
+ val request = chain.request().newBuilder()
+ .addHeader("apikey", BuildConfig.API_KEY)
+ .build()
+ chain.proceed(request)
+ }
+
+ val okHttpClient = OkHttpClient.Builder()
+ .connectTimeout(30, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .writeTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(apiKeyInterceptor)
+ .build()
+
+ val retrofit = Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .client(okHttpClient)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+ retrofit.create(ApiService::class.java)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/ViewModel.kt b/app/src/main/java/com/alom/androidstudy2/ViewModel.kt
new file mode 100644
index 0000000..db0e7dc
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/ViewModel.kt
@@ -0,0 +1,47 @@
+package com.alom.androidstudy2
+
+import android.util.Log
+import android.widget.Toast
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.alom.androidstudy2.activity.MainActivity
+import com.alom.androidstudy2.data.Item
+import com.alom.androidstudy2.data.Request
+import com.alom.androidstudy2.data.ResponseData
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class ViewModel(private val repository:Repository) : ViewModel() {
+ private val _item = MutableStateFlow>(emptyList())
+ val item: StateFlow> get() = _item
+
+ init {
+ updateItems()
+ }
+
+ fun updateItems() {
+ viewModelScope.launch {
+ repository.getItem().collect { items ->
+ _item.value = items
+ }
+ }
+ }
+
+ fun addItem(request: Request, onSuccess: () -> Unit, onFailure: () -> Unit) {
+ viewModelScope.launch {
+ val result = repository.addItem(request)
+ if (result.isSuccess) {
+ onSuccess()
+ } else {
+ onFailure()
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/ViewModelFactory.kt b/app/src/main/java/com/alom/androidstudy2/ViewModelFactory.kt
new file mode 100644
index 0000000..c5044a9
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/ViewModelFactory.kt
@@ -0,0 +1,13 @@
+package com.alom.androidstudy2
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+
+class ViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(com.alom.androidstudy2.ViewModel::class.java)) {
+ return ViewModel(repository) as T
+ }
+ throw IllegalArgumentException("ViewModel class not found")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/activity/AddActivity.kt b/app/src/main/java/com/alom/androidstudy2/activity/AddActivity.kt
new file mode 100644
index 0000000..21c101c
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/activity/AddActivity.kt
@@ -0,0 +1,46 @@
+package com.alom.androidstudy2.activity
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.alom.androidstudy2.Retrofit
+import com.alom.androidstudy2.data.Request
+import com.alom.androidstudy2.data.ResponseData
+import com.alom.androidstudy2.databinding.ActivityAddBinding
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class AddActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityAddBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityAddBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.btnBack.setOnClickListener {
+ finish()
+ }
+
+ binding.btnSave.setOnClickListener {
+ val title = binding.etTitle.text.toString()
+ val price = binding.etPrice.text.toString()
+ val time = binding.etTime.text.toString()
+
+ if (title.isEmpty() || price.isEmpty() || time.isEmpty()) {
+ Toast.makeText(this, "입력해라", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ val requestData = Request(title, price, time)
+
+ val returnIntent = Intent()
+ returnIntent.putExtra("requestData", requestData)
+ setResult(RESULT_OK, returnIntent)
+ finish()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/activity/MainActivity.kt b/app/src/main/java/com/alom/androidstudy2/activity/MainActivity.kt
new file mode 100644
index 0000000..6c82d81
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/activity/MainActivity.kt
@@ -0,0 +1,75 @@
+package com.alom.androidstudy2.activity
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.viewmodel.viewModelFactory
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.alom.androidstudy2.Adapter
+import com.alom.androidstudy2.RepositoryImpl
+import com.alom.androidstudy2.ViewModel
+import com.alom.androidstudy2.ViewModelFactory
+import com.alom.androidstudy2.data.Request
+import com.alom.androidstudy2.databinding.ActivityMainBinding
+import kotlinx.coroutines.launch
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var viewModel: ViewModel
+ private lateinit var adapter: Adapter
+
+ private val addActivityLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == RESULT_OK) {
+ val requestData = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ result.data?.getParcelableExtra("requestData", Request::class.java)
+ } else {
+ result.data?.getParcelableExtra("requestData") as? Request
+ }
+
+ Log.d("MainActivity", requestData.toString())
+ viewModel.addItem(requestData!!, onSuccess = { onSuccess() }, onFailure = { onFailure() })
+ }
+ }
+
+ private fun onSuccess() {
+ Toast.makeText(this, "업로드 성공", Toast.LENGTH_SHORT).show()
+ viewModel.updateItems()
+ }
+
+ private fun onFailure() {
+ Toast.makeText(this, "업로드 실패", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ val intent = Intent(this, AddActivity::class.java)
+
+ val repository = RepositoryImpl()
+ val factory = ViewModelFactory(repository)
+
+ viewModel = ViewModelProvider(this, factory).get(ViewModel::class.java)
+ adapter = Adapter()
+
+ binding.rcv.layoutManager = LinearLayoutManager(this)
+ binding.rcv.adapter = adapter
+ lifecycleScope.launch {
+ viewModel.item.collect { items ->
+ adapter.submitList(items)
+ Log.d("MainActivity", items.toString())
+ }
+ }
+
+ binding.btnAdd.setOnClickListener {
+ addActivityLauncher.launch(intent)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/alom/androidstudy2/data/Request.kt b/app/src/main/java/com/alom/androidstudy2/data/Request.kt
new file mode 100644
index 0000000..4d8e7b8
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/data/Request.kt
@@ -0,0 +1,15 @@
+package com.alom.androidstudy2.data
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.parcelize.Parcelize
+
+@Parcelize
+data class Request(
+ @SerializedName("p_title")
+ val title: String,
+ @SerializedName("p_price")
+ val price: String,
+ @SerializedName("p_time")
+ val time: String
+) : Parcelable
diff --git a/app/src/main/java/com/alom/androidstudy2/data/ResponseData.kt b/app/src/main/java/com/alom/androidstudy2/data/ResponseData.kt
new file mode 100644
index 0000000..8bc71dc
--- /dev/null
+++ b/app/src/main/java/com/alom/androidstudy2/data/ResponseData.kt
@@ -0,0 +1,22 @@
+package com.alom.androidstudy2.data
+
+import com.google.gson.annotations.SerializedName
+
+data class ResponseData(
+ val result: Int,
+ val message: String,
+ val data: MutableList-
+)
+
+data class Item(
+ @SerializedName("id")
+ val id: Int,
+ @SerializedName("title")
+ val title: String,
+ @SerializedName("price")
+ val price: String,
+ @SerializedName("image_url")
+ val imageUrl: String,
+ @SerializedName("time")
+ val time: String
+)
diff --git a/app/src/main/res/layout/activity_add.xml b/app/src/main/res/layout/activity_add.xml
new file mode 100644
index 0000000..01cb1d2
--- /dev/null
+++ b/app/src/main/res/layout/activity_add.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 86a5d97..d4063a7 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -5,15 +5,46 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".MainActivity">
+ android:background="@color/white"
+ tools:context=".activity.MainActivity">
-
+ app:layout_constraintStart_toStartOf="parent">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_sample.xml b/app/src/main/res/layout/item_sample.xml
new file mode 100644
index 0000000..a48879f
--- /dev/null
+++ b/app/src/main/res/layout/item_sample.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ca0ae81..b862355 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,5 @@
android_study_14_2
+
+ Hello blank fragment
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 9b2b101..c0939d8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -9,6 +9,11 @@ appcompat = "1.7.0"
material = "1.12.0"
activity = "1.9.3"
constraintlayout = "2.1.4"
+retrofitVersion = "2.9.0"
+okhttpVersion = "4.12.0"
+lifecycleVersion = "2.8.4"
+glideVersion = "4.16.0"
+compilerVersion = "4.14.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -19,6 +24,17 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofitVersion"}
+converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofitVersion"}
+okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttpVersion"}
+logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttpVersion"}
+
+lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleVersion"}
+lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleVersion"}
+lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleVersion"}
+
+glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glideVersion" }
+compiler = { group = "com.github.bumptech.glide", name = "compiler", version.ref = "compilerVersion" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }