Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ kotlin {
}

android {
compileSdk 34
compileSdk 36
namespace "otus.gpb.homework.fragments"

defaultConfig {
Expand All @@ -21,6 +21,10 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures {
viewBinding true
}

buildTypes {
release {
minifyEnabled false
Expand All @@ -42,6 +46,8 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.activity:activity:1.11.0'
implementation 'androidx.fragment:fragment-ktx:1.8.9'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@
android:supportsRtl="true"
android:theme="@style/Theme.Fragments"
tools:targetApi="31">
<activity
android:name=".ThirdActivity"
android:exported="false" />
<activity
android:name=".SecondActivity"
android:exported="false" />
<activity
android:name=".FirstActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
Expand Down
31 changes: 31 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/ExchangeDataExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package otus.gpb.homework.fragments

import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.setFragmentResultListener

const val COLOR_REQUEST_KEY = "request_key"
const val COLOR_RESULT_KEY = "result_key"

fun Fragment.sendResult(data: Int, isTablet: Boolean = false) {
if (isTablet) {
requireActivity().supportFragmentManager.setFragmentResult(COLOR_REQUEST_KEY, bundleOf(COLOR_RESULT_KEY to data))
} else {
setFragmentResult(COLOR_REQUEST_KEY, bundleOf(COLOR_RESULT_KEY to data))
}
}

fun Fragment.observeResult(isTablet: Boolean = false, callback: (Int) -> Unit) {
if (isTablet) {
requireActivity().supportFragmentManager.setFragmentResultListener(COLOR_REQUEST_KEY, viewLifecycleOwner) { _, bundle ->
val data = bundle.getInt(COLOR_RESULT_KEY)
callback(data)
}
} else {
setFragmentResultListener(COLOR_REQUEST_KEY) { _, bundle ->
val data = bundle.getInt(COLOR_RESULT_KEY)
callback(data)
}
}
}
27 changes: 27 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FirstActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import otus.gpb.homework.fragments.databinding.ActivityFirstBinding

class FirstActivity : AppCompatActivity() {
private var binding: ActivityFirstBinding? = null
private lateinit var fragmentA: FragmentA

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

if (savedInstanceState == null) {
fragmentA = FragmentA()
} else {
fragmentA = supportFragmentManager.findFragmentByTag("FragmentA") as FragmentA
}

supportFragmentManager.beginTransaction()
.replace(R.id.fragmentA_container, fragmentA, "FragmentA")
.addToBackStack(null)
.commit()
}
}
82 changes: 82 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FragmentA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package otus.gpb.homework.fragments

import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isVisible
import otus.gpb.homework.fragments.databinding.FragmentABinding

class FragmentA : Fragment() {
private var _binding: FragmentABinding? = null
val binding get() = _binding!!

override fun onAttach(context: Context) {
super.onAttach(context)

requireActivity().onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
val count = childFragmentManager.backStackEntryCount
Toast.makeText(requireContext(), "BackStack count: $count", Toast.LENGTH_SHORT)
.show()
when {
count > 1 -> childFragmentManager.popBackStack()
count == 1 -> {
binding.buttonA.visibility = View.VISIBLE
binding.textViewA.visibility = View.VISIBLE

childFragmentManager.popBackStack()
}
count == 0 -> requireActivity().finish()
else -> {
isEnabled = false
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
}
})
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentABinding.inflate(inflater, container, false)
val view = binding.root
return view
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonA.setOnClickListener {
openFragmentAA()
}
}

private fun openFragmentAA() {
val fragmentAA = FragmentAA()

sendResult(ColorGenerator.generateColor())

childFragmentManager.beginTransaction()
.replace(R.id.containerA, fragmentAA)
.addToBackStack(null)
.commit()

binding.buttonA.visibility = View.GONE
binding.textViewA.visibility = View.GONE
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

}
52 changes: 52 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FragmentAA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import otus.gpb.homework.fragments.databinding.FragmentAaBinding

class FragmentAA : Fragment() {
private var _binding: FragmentAaBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentAaBinding.inflate(inflater, container, false)
val view = binding.root
observeResult(true) { color ->
binding.containerAA.setBackgroundColor(color)
}
return view
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonAB.setOnClickListener {
openFragmentAB()
}
}

private fun openFragmentAB() {
val fragmentAB = FragmentAB()
val color = ColorGenerator.generateColor()
fragmentAB.arguments = bundleOf("color" to color)
childFragmentManager.beginTransaction()
.replace(R.id.containerAA, fragmentAB)
.addToBackStack(null)
.commit()

binding.buttonAB.visibility = View.GONE
binding.textViewB.visibility = View.GONE
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

}
29 changes: 29 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FragmentAB.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import otus.gpb.homework.fragments.databinding.FragmentAbBinding

class FragmentAB : Fragment() {
private var _binding: FragmentAbBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentAbBinding.inflate(inflater, container, false)
val view = binding.root
val color = arguments?.getInt("color") ?: 0
binding.containerAB.setBackgroundColor(color)
return view
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
27 changes: 27 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FragmentB.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import otus.gpb.homework.fragments.databinding.FragmentBBinding

class FragmentB : Fragment() {
private var _binding: FragmentBBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentBBinding.inflate(inflater, container, false)
val view = binding.root
return view
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
85 changes: 85 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/FragmentBA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package otus.gpb.homework.fragments

import android.content.Context
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.setFragmentResultListener
import otus.gpb.homework.fragments.databinding.FragmentBABinding

class FragmentBA : Fragment() {
private var _binding: FragmentBABinding? = null
private val binding get() = _binding!!
private var isTablet = false

override fun onAttach(context: Context) {
super.onAttach(context)

requireActivity().onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
val count = childFragmentManager.backStackEntryCount
Toast.makeText(requireContext(), "BackStack count: $count", Toast.LENGTH_SHORT)
.show()
when {
count > 1 -> childFragmentManager.popBackStack()
count == 1 -> {
binding.buttonBA.visibility = View.VISIBLE
childFragmentManager.popBackStack()
}

count == 0 -> requireActivity().finish()
else -> {
isEnabled = false
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
}
})
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentBABinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

isTablet = requireActivity().findViewById<View>(R.id.fragment1) != null

observeResult(isTablet) { color ->
binding.containerBA.setBackgroundColor(color)
}

if (isTablet) {
binding.buttonBA.visibility = View.GONE
}

binding.buttonBA.setOnClickListener {
openFragmentBB()
}
}

private fun openFragmentBB() {
val fragmentBB = FragmentBB()
parentFragmentManager.beginTransaction()
.replace(R.id.containerBA, fragmentBB, "FragmentBB")
.addToBackStack(null)
.commit()

binding.buttonBA.visibility = View.GONE
}

fun showButtonBA() {
binding.buttonBA.visibility = View.VISIBLE
}
}
Loading