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
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ 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.fragment:fragment-ktx:1.8.8'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.fragment:fragment:1.8.8'
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
8 changes: 8 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@
<activity
android:name=".MainActivity"
android:exported="true">
</activity>
<activity
android:name=".ActivityA"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActivityB"
android:exported="true">
</activity>
</application>

</manifest>
18 changes: 18 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/ActivityA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class ActivityA : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment_a)

if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_activity_container, FragmentA())
.commit()
}
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/ActivityB.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package otus.gpb.homework.fragments

import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class ActivityB : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment_b)

if (savedInstanceState == null) {
val currentOrientation = resources.configuration.orientation
val fragmentBA = FragmentBA.newInstance(Color.WHITE)

if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_b_activity_container, fragmentBA)
.commit()
} else {
val fragmentBB = FragmentBB.newInstance(Color.YELLOW)

supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container_ba_land, fragmentBA)
.replace(R.id.fragment_container_bb_land, fragmentBB)
.commit()
}
}
}

companion object {
const val REQUEST_KEY_COLOR = "request_key_color"
const val BUNDLE_KEY_COLOR = "bundle_key_color"
}
}
66 changes: 66 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/ChildFragmentAA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package otus.gpb.homework.fragments

import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment

class ChildFragmentAA : Fragment() {

private var listener: ParentFragmentListener? = null
private var backgroundColor: Int = Color.WHITE


override fun onAttach(context: Context) {
super.onAttach(context)
if (parentFragment is ParentFragmentListener) {
listener = parentFragment as ParentFragmentListener
} else {
throw RuntimeException("${parentFragment} must implement ParentFragmentListener")
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
backgroundColor = it.getInt(ARG_BACKGROUND_COLOR)
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.child_fragment_aa, container, false)
view.setBackgroundColor(backgroundColor)
val openChildFragmentABButton: Button =
view.findViewById(R.id.button_open_child_fragment_ab)
openChildFragmentABButton.setOnClickListener {
listener?.onOpenChildFragmentABClicked()
}
return view
}

override fun onDetach() {
super.onDetach()
listener = null
}

companion object {
private const val ARG_BACKGROUND_COLOR = "background_color"

fun newInstance(color: Int): ChildFragmentAA {
val fragment = ChildFragmentAA()
val args = Bundle().apply {
putInt(ARG_BACKGROUND_COLOR, color)
}
fragment.arguments = args
return fragment
}
}
}
43 changes: 43 additions & 0 deletions app/src/main/java/otus/gpb/homework/fragments/ChildFragmentAB.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package otus.gpb.homework.fragments

import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class ChildFragmentAB : Fragment() {

private var backgroundColor: Int = Color.WHITE

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
backgroundColor = it.getInt(ARG_BACKGROUND_COLOR, Color.WHITE)
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.child_fragment_ab, container, false)
view?.setBackgroundColor(backgroundColor)
return view
}

companion object {
private const val ARG_BACKGROUND_COLOR = "background_color_ab"

fun newInstance(color: Int): ChildFragmentAB {
val fragment = ChildFragmentAB()
val args = Bundle().apply {
putInt(ARG_BACKGROUND_COLOR, color)
}
fragment.arguments = args
return fragment
}
}
}
105 changes: 105 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,105 @@
package otus.gpb.homework.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager


class FragmentA : Fragment(), ParentFragmentListener {

private lateinit var openChildFragmentAAButton: Button
private lateinit var onBackPressedCallback: OnBackPressedCallback

private val childBackStackListener = FragmentManager.OnBackStackChangedListener {
updateOpenChildButtonVisibility()
}


override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_parent_a, container, false)

openChildFragmentAAButton = view.findViewById(R.id.button_open_fragment_aa)

openChildFragmentAAButton.setOnClickListener {
openChildFragmentAA()
}

onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (childFragmentManager.backStackEntryCount > 0) {
childFragmentManager.popBackStack()
} else {
isEnabled = false
requireActivity().onBackPressedDispatcher.onBackPressed()
isEnabled = true
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
onBackPressedCallback
)

childFragmentManager.addOnBackStackChangedListener(childBackStackListener)
updateOpenChildButtonVisibility()
return view
}

override fun onDestroyView() {
super.onDestroyView()
childFragmentManager.removeOnBackStackChangedListener(childBackStackListener)
}

private fun updateOpenChildButtonVisibility() {
val hasChildFragment =
childFragmentManager.findFragmentById(R.id.parent_fragment_a_child_container) != null
val isChildBackStackEmpty = childFragmentManager.backStackEntryCount == 0

if (hasChildFragment && isChildBackStackEmpty) {
} else if (!hasChildFragment && isChildBackStackEmpty) {
openChildFragmentAAButton.visibility = View.VISIBLE
} else {
openChildFragmentAAButton.visibility = View.GONE
}

openChildFragmentAAButton.visibility =
if (childFragmentManager.backStackEntryCount == 0 && childFragmentManager.findFragmentById(
R.id.parent_fragment_a_child_container
) == null
) View.VISIBLE else View.GONE
openChildFragmentAAButton.visibility =
if (childFragmentManager.backStackEntryCount == 0) View.VISIBLE else View.GONE
}

private fun openChildFragmentAA() {
val randomColor = ColorGenerator.generateColor()
val childFragmentAA = ChildFragmentAA.newInstance(randomColor)
childFragmentManager.beginTransaction()
.replace(R.id.parent_fragment_a_child_container, childFragmentAA)
.addToBackStack("ChildFragmentAA")
.commit()
openChildFragmentAAButton.visibility = View.GONE
}

private fun openChildFragmentAB() {
val randomColor = ColorGenerator.generateColor()
val childFragmentAB = ChildFragmentAB.newInstance(randomColor)
childFragmentManager.beginTransaction()
.replace(R.id.parent_fragment_a_child_container, childFragmentAB)
.addToBackStack("ChildFragmentAB")
.commit()
}

override fun onOpenChildFragmentABClicked() {
openChildFragmentAB()
}
}
87 changes: 87 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,87 @@
package otus.gpb.homework.fragments

import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment

class FragmentBA : Fragment() {

private var backgroundColor: Int = Color.WHITE
private lateinit var openFragmentBBButton: Button

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
backgroundColor = it.getInt(ARG_BACKGROUND_COLOR, Color.WHITE)
}
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(
R.layout.fragment_ba,
container,
false
)
view.setBackgroundColor(backgroundColor)
return view
}

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

parentFragmentManager.setFragmentResultListener(
ActivityB.REQUEST_KEY_COLOR,
viewLifecycleOwner
) { requestKey, bundle ->
if (requestKey == ActivityB.REQUEST_KEY_COLOR) {
val newColor = bundle.getInt(ActivityB.BUNDLE_KEY_COLOR, Color.WHITE)
view.setBackgroundColor(newColor)
this.backgroundColor = newColor
}
}

openFragmentBBButton = view.findViewById(R.id.button_open_fragment_bb)

val currentOrientation = resources.configuration.orientation
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
openFragmentBBButton.visibility = View.VISIBLE
openFragmentBBButton.setOnClickListener {
openFragmentBBInPortrait()
}
} else {
openFragmentBBButton.visibility = View.GONE
}
}

private fun openFragmentBBInPortrait() {
val randomColor = ColorGenerator.generateColor()
val fragmentBB = FragmentBB.newInstance(randomColor)

parentFragmentManager.beginTransaction()
.replace(R.id.fragment_b_activity_container, fragmentBB)
.addToBackStack("FragmentBBFromBA")
.commit()
}

companion object {
private const val ARG_BACKGROUND_COLOR = "background_color_ba"

fun newInstance(color: Int): FragmentBA {
val fragment = FragmentBA()
val args = Bundle().apply {
putInt(ARG_BACKGROUND_COLOR, color)
}
fragment.arguments = args
return fragment
}
}
}
Loading