diff --git a/app/build.gradle b/app/build.gradle index 9bb293e..5b5890e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,17 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'kotlin-parcelize' + id 'androidx.navigation.safeargs.kotlin' } android { - compileSdk 30 + compileSdk 31 defaultConfig { applicationId "com.itis.androidlabproject" minSdk 23 - targetSdk 30 + targetSdk 31 versionCode 1 versionName "1.0" @@ -36,13 +38,25 @@ android { } dependencies { + // Navigation + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' - implementation 'androidx.core:core-ktx:1.6.0' + //Glide + implementation 'com.github.bumptech.glide:glide:4.12.0' + implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.2" + + implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.1' - implementation 'android.arch.navigation:navigation-fragment:2.3.5' - implementation 'android.arch.navigation:navigation-ui:2.3.5' + + implementation 'androidx.recyclerview:recyclerview:1.2.1' + + implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + implementation 'de.hdodenhof:circleimageview:3.1.0' + implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0' + testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 69ebd0a..c1e31fd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,8 @@ + + diff --git a/app/src/main/java/com/itis/androidlabproject/MainActivity.kt b/app/src/main/java/com/itis/androidlabproject/MainActivity.kt deleted file mode 100644 index d85e6eb..0000000 --- a/app/src/main/java/com/itis/androidlabproject/MainActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.itis.androidlabproject - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/itis/androidlabproject/activity/MainActivity.kt b/app/src/main/java/com/itis/androidlabproject/activity/MainActivity.kt new file mode 100644 index 0000000..a8a5013 --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/activity/MainActivity.kt @@ -0,0 +1,22 @@ +package com.itis.androidlabproject.activity + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.NavController +import com.itis.androidlabproject.R +import com.itis.androidlabproject.databinding.ActivityMainBinding +import com.itis.androidlabproject.extension.findNavController + +class MainActivity : AppCompatActivity() { + private lateinit var binding: ActivityMainBinding + private lateinit var navController: NavController + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityMainBinding.inflate(layoutInflater).also { + setContentView(it.root) + } + + navController = findNavController(R.id.fragment_container) + } +} diff --git a/app/src/main/java/com/itis/androidlabproject/adapter/PlanetAdapter.kt b/app/src/main/java/com/itis/androidlabproject/adapter/PlanetAdapter.kt new file mode 100644 index 0000000..6eb7e05 --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/adapter/PlanetAdapter.kt @@ -0,0 +1,25 @@ +package com.itis.androidlabproject.adapter + +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.RequestManager +import com.itis.androidlabproject.model.Planet + +class PlanetAdapter( + private val list: List, + private val glide: RequestManager, + private val action: (Int) -> Unit +) : RecyclerView.Adapter() { + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): PlanetHolder = PlanetHolder.create(parent, glide, action) + + override fun onBindViewHolder(holder: PlanetHolder, position: Int) { + holder.bind(list[position]) + } + + override fun getItemCount(): Int = list.size; + +} diff --git a/app/src/main/java/com/itis/androidlabproject/adapter/PlanetHolder.kt b/app/src/main/java/com/itis/androidlabproject/adapter/PlanetHolder.kt new file mode 100644 index 0000000..136e13e --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/adapter/PlanetHolder.kt @@ -0,0 +1,61 @@ +package com.itis.androidlabproject.adapter + +import android.annotation.SuppressLint +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.bumptech.glide.Priority +import com.bumptech.glide.RequestManager +import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.request.RequestOptions +import com.itis.androidlabproject.databinding.ItemPlanetBinding +import com.itis.androidlabproject.model.Planet + +class PlanetHolder( + private val binding: ItemPlanetBinding, + private val glige: RequestManager, + private val action: (Int) -> Unit +) : RecyclerView.ViewHolder(binding.root) { + private var planet: Planet? = null + + private val options = RequestOptions() + .priority(Priority.HIGH) + .diskCacheStrategy(DiskCacheStrategy.ALL) + + init { + itemView.setOnClickListener { + planet?.run { + action(this.id) + } + } + } + + @SuppressLint("SetTextI18n") + fun bind(item: Planet) { + this.planet = item + with(binding) { + tvDetName.text = item.name + tvNumberOfSatellite.text = "Количество спутников: ${item.numberOfSatellite}" + + glige.load(item.url) + .apply(options) + .into(ivImage) + } + } + + companion object { + fun create( + parent: ViewGroup, + glige: RequestManager, + action: (Int) -> Unit + ) = PlanetHolder( + ItemPlanetBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ), + glige, + action + ) + } +} diff --git a/app/src/main/java/com/itis/androidlabproject/extension/ActivityExt.kt b/app/src/main/java/com/itis/androidlabproject/extension/ActivityExt.kt new file mode 100644 index 0000000..8fc4c5c --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/extension/ActivityExt.kt @@ -0,0 +1,9 @@ +package com.itis.androidlabproject.extension + +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.NavController +import androidx.navigation.fragment.NavHostFragment + +fun AppCompatActivity.findNavController(id: Int): NavController { + return (supportFragmentManager.findFragmentById(id) as NavHostFragment).navController +} diff --git a/app/src/main/java/com/itis/androidlabproject/fragment/DetailsFragment.kt b/app/src/main/java/com/itis/androidlabproject/fragment/DetailsFragment.kt new file mode 100644 index 0000000..89d82f5 --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/fragment/DetailsFragment.kt @@ -0,0 +1,49 @@ +package com.itis.androidlabproject.fragment + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.bumptech.glide.Glide +import com.itis.androidlabproject.databinding.FragmentDetailsBinding +import com.itis.androidlabproject.model.Planet +import com.itis.androidlabproject.repository.PlanetRepository + +class DetailsFragment : Fragment() { + private lateinit var binding: FragmentDetailsBinding + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding.run { + arguments?.getInt("planetId")?.let { planetId -> + PlanetRepository.getPlanetById(planetId).let { + showChosenPlanet(it) + } + } + } + + } + + @SuppressLint("SetTextI18n") + private fun showChosenPlanet(planet: Planet) { + with(binding) { + Glide.with(this.root).load(planet.url).into(ivPhoto) + tvDetName.text = "Название планеты: ${planet.name}" + tvDetNumberOfSatellite.text = "Количество спутников ${planet.numberOfSatellite}" + tvDetDescription.text = "Описание: ${planet.description}" + collapsingToolbar.title = planet.name + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentDetailsBinding.inflate(inflater, container, false) + return binding.root + } +} diff --git a/app/src/main/java/com/itis/androidlabproject/fragment/ListFragment.kt b/app/src/main/java/com/itis/androidlabproject/fragment/ListFragment.kt new file mode 100644 index 0000000..6cf414a --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/fragment/ListFragment.kt @@ -0,0 +1,49 @@ +package com.itis.androidlabproject.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.os.bundleOf +import androidx.fragment.app.Fragment +import androidx.navigation.NavOptions +import androidx.navigation.fragment.findNavController +import com.bumptech.glide.Glide +import com.itis.androidlabproject.R +import com.itis.androidlabproject.adapter.PlanetAdapter +import com.itis.androidlabproject.databinding.FragmentListBinding +import com.itis.androidlabproject.repository.PlanetRepository + +class ListFragment : Fragment(R.layout.fragment_list) { + private lateinit var binding: FragmentListBinding + private lateinit var adapter: PlanetAdapter + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentListBinding.inflate(inflater, container, false) + adapter = PlanetAdapter(PlanetRepository.planets, Glide.with(this)) { + showPlanetDetails(it); + } + binding.rvPlanets.adapter = adapter + + return binding.root + } + + private fun showPlanetDetails(id: Int) { + val bundle = bundleOf( + "planetId" to id + ) + + val options = NavOptions.Builder() + .setLaunchSingleTop(false) + .setEnterAnim(R.anim.enter_from_right) + .setExitAnim(R.anim.fade_out) + .setPopEnterAnim(R.anim.fade_in) + .setPopExitAnim(R.anim.exit_to_right) + .build() + findNavController().navigate(R.id.action_listFragment_to_detailsFragment, bundle, options) + } +} diff --git a/app/src/main/java/com/itis/androidlabproject/model/Planet.kt b/app/src/main/java/com/itis/androidlabproject/model/Planet.kt new file mode 100644 index 0000000..0d874fd --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/model/Planet.kt @@ -0,0 +1,9 @@ +package com.itis.androidlabproject.model + +data class Planet( + var id: Int, + var name: String, + val numberOfSatellite: Int = 0, + var url: String, + var description: String +) diff --git a/app/src/main/java/com/itis/androidlabproject/repository/PlanetRepository.kt b/app/src/main/java/com/itis/androidlabproject/repository/PlanetRepository.kt new file mode 100644 index 0000000..6ace681 --- /dev/null +++ b/app/src/main/java/com/itis/androidlabproject/repository/PlanetRepository.kt @@ -0,0 +1,81 @@ +package com.itis.androidlabproject.repository + +import com.itis.androidlabproject.model.Planet + +object PlanetRepository { + var autoIncId = 0; + val planets = arrayListOf( + Planet( + id = autoIncId++, + name = "Меркурий", + url = "https://cosmos.agency/wp-content/uploads/2015/08/pluto_heart_colored.png", + description = "Меркурий — самая близкая к Солнцу планета Солнечной системы, обращающаяся вокруг Солнца за 88 земных суток. Продолжительность одних звёздных суток на Меркурии составляет 58,65 земных[, а солнечных — 176 земных. Планета названа в честь древнеримского бога торговли — быстроногого Меркурия, поскольку она движется по небу быстрее других планет. Меркурий относится к планетам земной группы. После лишения Плутона в 2006 году статуса планеты к Меркурию перешло звание самой маленькой планеты Солнечной системы. Снимок сделан межпланетной станцией «Мессенджер»" + ), + Planet( + id = autoIncId++, + name = "Венера", + url = "https://cosmos.agency/wp-content/uploads/2015/08/venus_magellan.png", + description = "Венера — самая горячая планета Солнечной системы. В глубокой древности Венера, как полагают, настолько разогрелась, что подобные земным океаны, которыми, как считается, она обладала, полностью испарились, оставив после себя пустынный пейзаж с множеством плитоподобных скал. По структуре и размеру Венера подобна Земле. Ее толстая, токсичная атмосфера удерживает тепло, держа температуру поверхности достаточно горячей, для того, чтобы плавился свинец. Сфотографированна с межпланетной станции Магеллан." + ), + Planet( + id = autoIncId++, + name = "Земля", + numberOfSatellite = 1, + url = "https://cosmos.agency/wp-content/uploads/2015/08/earth.png", + description = "Земля — третья от Солнца планета. Пятая по размеру среди всех планет Солнечной системы. Она является также крупнейшей по диаметру, массе и плотности среди планет земной группы. Мы все на ней живем." + ), + Planet( + id = autoIncId++, + name = "Марс", + numberOfSatellite = 2, + url = "https://cosmos.agency/wp-content/uploads/2015/08/mars-globe-valles-marineris-enhanced-800.png", + description = "Марс — четвёртая по удалённости от Солнца (после Меркурия, Венеры и Земли) и седьмая по размерам планета Солнечной системы. Рельеф Марса обладает многими уникальными чертами. Марсианский потухший вулкан гора Олимп — самая высокая известная гора на планетах Солнечной системы, а долины Маринер — самый крупный известный каньон. Долины имеют длину 4500 км (четверть окружности планеты), ширину — 200 км и глубину — до 11 км. Эта система каньонов превышает знаменитый Большой каньон в 10 раз по длине, в 7 — по ширине и в 7 — по глубине. Композитная фотография планеты Марс с видом на долины Маринер." + ), + Planet( + id = autoIncId++, + name = "Юпитер", + numberOfSatellite = 79, + url = "https://cosmos.agency/wp-content/uploads/2015/08/planet_jupiter_mid_cosmos_agency.png", + description = "Юпитер — пятая планета от Солнца, располагается между Марсом и Сатурном. Отдалена от Солнца на 778.5 миллионов километров. Газовый гигант (три других газовых гиганта: Сатурн, Уран, Нептун), самая большая планета в Солнечной системе. Сутки на Юпитере длятся почти 10 часов, а год — 4333 земных дней, т.е. 11,8 лет." + ), + Planet( + id = autoIncId++, + name = "Сатурн", + numberOfSatellite = 62, + url = "https://cosmos.agency/wp-content/uploads/2015/08/saturn.png", + description = "Украшенный тысячами красивых колец, Сатурн является уникальной планетой. Все четыре газовых гиганта (Нептун, Уран, Сатурн, Юпитер) имеют кольца из глыбин льда и камней, но только Сатурн может похвастаться такой зрелищностью. Как и другие газовые гиганты, Сатурн в основном состоит из водорода и гелия. Планета находится в 1430 млн км от солнца, в 10 раз дальше чем Земля. Вокруг планеты обращается 62 известных на данный момент спутника. Титан — самый крупный из них, а также второй по размерам спутник в Солнечной системе (после спутника Юпитера, Ганимеда), который превосходит по своим размерам Меркурий и обладает единственной среди спутников Солнечной системы плотной атмосферой. Этот портрет Сатурна и его колец скомпонован любителем и фанатом Кассини Горданом Угарковичем из изображений полученных с космического аппарата NASA Кассини 10 октября 2013." + ), + Planet( + id = autoIncId++, + name = "Уран", + numberOfSatellite = 0, + url = "https://cosmos.agency/wp-content/uploads/2015/08/768px-Uranus2.png", + description = "Уран — седьмая планета Солнечной системы по удалённости от Солнца, третья по диаметру и четвёртая по массе. Была открыта в 1781 году английским астрономом Уильямом Гершелем и названа в честь греческого бога неба Урана, отца Кроноса (в римской мифологии Сатурна) и, соответственно, деда Зевса (у римлян — Юпитер). Фотография планеты Уран сделанная космическим аппаратом «Вояджер-2» в 1986" + ), + Planet( + id = autoIncId++, + name = "Нептун", + numberOfSatellite = 0, + url = "https://cosmos.agency/wp-content/uploads/2015/08/neptune_800.png", + description = "Темная, холодная, овеваемая сверхзвуковыми ветрами, планета Нептун, состоит из водорода и гелия и является самой дальней из газовых гигантов в нашей солнечной системе. Она находится на расстоянии в 4.5 миллиарда километров (что в 30 раз дальше чем Земля) от Солнца. Один год на Нептуне длится 165 земных лет, в 2011 году завершился первый год с момента его открытия в 1846. Нептун — восьмая планета Солнечной системы. Нептун также является четвёртой по диаметру и третьей по массе планетой. Масса Нептуна в 17,2 раза, а диаметр экватора в 3,9 раза больше таковых у Земли. Планета была названа в честь римского бога морей. Фотография планеты Нептун. Сделана космическим аппаратом «Вояджер 2» в 1989" + ), + Planet( + id = autoIncId++, + name = "Плутон", + numberOfSatellite = 0, + url = "https://cosmos.agency/wp-content/uploads/2015/08/pluto_heart_colored.png", + description = "Плутон — крупнейшая по размеру известная карликовая планета Солнечной системы, транснептуновый объект (ТНО) и десятое по массе (без учёта спутников) небесное тело, обращающееся вокруг Солнца — после восьми планет Солнечной системы и Эриды. Первоначально Плутон классифицировался как классическая планета, однако сейчас он считается карликовой планетой и самым крупным объектом в поясе Койпера. Цветное изображение Плутона, полученное автоматической межпланетной станцией «Новые горизонты» 14 июля 2015 года с расстояния 450 000 км" + ), + Planet( + id = autoIncId++, + name = "Ио", + numberOfSatellite = 0, + url = "https://cosmos.agency/wp-content/uploads/2015/08/Io_highest_resolution_true_color1.png", + description = "Фото Ио, сделанное аппаратом «Галилео» в 1999 году. Желтоватый цвет говорит о высоком содержании серы. Тёмное пятно левее центра — извергающийся вулкан Прометей, его окружают светлые равнины, покрытые оксидом серы. Хоть Ио и спутник Юпитера и не подходит для нашей подборки фотографий планет (в т.ч. одной карликовой) Солнечной системы от NASA, он весьма необычен и заслуживает место в списке." + ) + ) + + fun getPlanetById(id: Int): Planet { + return this.planets[id] + } +} diff --git a/app/src/main/res/anim/enter_from_right.xml b/app/src/main/res/anim/enter_from_right.xml new file mode 100644 index 0000000..d424f42 --- /dev/null +++ b/app/src/main/res/anim/enter_from_right.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/exit_to_right.xml b/app/src/main/res/anim/exit_to_right.xml new file mode 100644 index 0000000..7becffd --- /dev/null +++ b/app/src/main/res/anim/exit_to_right.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..2f74325 --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..678a617 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fa45b0..7c0b9e9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,15 +4,18 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".activity.MainActivity"> - + app:layout_constraintTop_toTopOf="parent" + app:navGraph="@navigation/nav_graph" /> diff --git a/app/src/main/res/layout/fragment_details.xml b/app/src/main/res/layout/fragment_details.xml new file mode 100644 index 0000000..e571860 --- /dev/null +++ b/app/src/main/res/layout/fragment_details.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml new file mode 100644 index 0000000..37cbb9b --- /dev/null +++ b/app/src/main/res/layout/fragment_list.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/res/layout/item_planet.xml b/app/src/main/res/layout/item_planet.xml new file mode 100644 index 0000000..0d533a6 --- /dev/null +++ b/app/src/main/res/layout/item_planet.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 0000000..466805e --- /dev/null +++ b/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f931ae8..4ac4d6e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ AndroidLabProject - \ No newline at end of file + Название планеты + Количество спутников + diff --git a/build.gradle b/build.gradle index 12f1d4c..4afb132 100644 --- a/build.gradle +++ b/build.gradle @@ -5,8 +5,9 @@ buildscript { mavenCentral() } dependencies { - classpath "com.android.tools.build:gradle:7.0.2" + classpath 'com.android.tools.build:gradle:7.0.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30" + classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files