diff --git a/app/build.gradle b/app/build.gradle index c5cf1b8..a5eb15c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ kotlin { } android { - compileSdk 34 + compileSdk 35 namespace "otus.gpb.homework.fragments" defaultConfig { @@ -34,6 +34,10 @@ android { kotlinOptions { jvmTarget = '17' } + + buildFeatures { + viewBinding = true + } } dependencies { @@ -42,6 +46,7 @@ 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.10.1' testImplementation 'junit:junit:4.13.2' 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 9604b34..46bc072 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,12 @@ android:supportsRtl="true" android:theme="@style/Theme.Fragments" tools:targetApi="31"> + + diff --git a/app/src/main/java/otus/gpb/homework/fragments/ActivityA.kt b/app/src/main/java/otus/gpb/homework/fragments/ActivityA.kt new file mode 100644 index 0000000..bab7e51 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/ActivityA.kt @@ -0,0 +1,34 @@ +package otus.gpb.homework.fragments + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.fragment.app.Fragment + +class ActivityA : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_a) + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container_a)) { v, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) + insets + } + if (savedInstanceState == null) { + supportFragmentManager.beginTransaction() + .replace(R.id.container_a, FragmentA.newInstance()) + .commit() + } + } + + companion object { + fun newIntent(context: Context): Intent{ + return Intent(context, ActivityA::class.java) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/ActivityB.kt b/app/src/main/java/otus/gpb/homework/fragments/ActivityB.kt new file mode 100644 index 0000000..39b8cba --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/ActivityB.kt @@ -0,0 +1,33 @@ +package otus.gpb.homework.fragments + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat + +class ActivityB : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_b) + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container_b)) { v, insets -> + val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) + insets + } + if (savedInstanceState == null){ + supportFragmentManager.beginTransaction() + .replace(R.id.container_b, FragmentB.newInstance()) + .commit() + } + } + + companion object { + fun newIntent(context: Context): Intent { + return Intent(context, ActivityB::class.java) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentA.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentA.kt new file mode 100644 index 0000000..6f6584f --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentA.kt @@ -0,0 +1,55 @@ +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.activity.OnBackPressedCallback +import otus.gpb.homework.fragments.databinding.FragmentABinding + +class FragmentA : Fragment() { + + private var _binding: FragmentABinding? = null + private val binding: FragmentABinding + get() = _binding ?: throw RuntimeException("FragmentABinding == null") + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentABinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true){ + override fun handleOnBackPressed() { + if (childFragmentManager.backStackEntryCount <= 0){ + requireActivity().finish() + } else { + childFragmentManager.popBackStack() + } + } + }) + binding.buttonFragmentAA.setOnClickListener(){ + childFragmentManager.popBackStack() + childFragmentManager.beginTransaction() + .replace(R.id.containerFragmentA, FragmentAA.newInstance(ColorGenerator.generateColor())) + .addToBackStack(null) + .commit() + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + fun newInstance(): FragmentA{ + return FragmentA() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentAA.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentAA.kt new file mode 100644 index 0000000..0c6bfe6 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentAA.kt @@ -0,0 +1,63 @@ +package otus.gpb.homework.fragments + +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import otus.gpb.homework.fragments.databinding.FragmentAABinding + +class FragmentAA : Fragment() { + + private var _binding: FragmentAABinding? = null + private val binding: FragmentAABinding + get() = _binding ?: throw RuntimeException("FragmentAABinding == null") + private var colorInt: Int? = 0 + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + colorInt = arguments?.getInt(COLOR) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentAABinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.buttonFragmentAB.setOnClickListener(){ + parentFragmentManager.beginTransaction() + .replace(R.id.containerFragmentA, FragmentAB.newInstance(ColorGenerator.generateColor())) + .addToBackStack(null) + .commit() + } + colorInt?.let { + binding.layoutFragmentAA.setBackgroundColor(it) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + + private const val COLOR = "color" + + fun newInstance(color: Int): FragmentAA { + return FragmentAA().apply { + arguments = Bundle().apply { + putInt(COLOR, color) + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentAB.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentAB.kt new file mode 100644 index 0000000..0df914c --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentAB.kt @@ -0,0 +1,56 @@ +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.FragmentAA.Companion +import otus.gpb.homework.fragments.databinding.FragmentAABinding +import otus.gpb.homework.fragments.databinding.FragmentABBinding + +class FragmentAB : Fragment() { + + private var _binding: FragmentABBinding? = null + private val binding: FragmentABBinding + get() = _binding ?: throw RuntimeException("FragmentAABinding == null") + private var colorInt: Int? = 0 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + colorInt = arguments?.getInt(COLOR) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentABBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + colorInt?.let { + binding.layoutFragmentAB.setBackgroundColor(it) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + + private const val COLOR = "color" + + fun newInstance(color: Int): FragmentAB { + return FragmentAB().apply { + arguments = Bundle().apply { + putInt(COLOR, color) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentB.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentB.kt new file mode 100644 index 0000000..0aa683b --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentB.kt @@ -0,0 +1,54 @@ +package otus.gpb.homework.fragments + +import android.os.Bundle +import android.util.Log +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.FragmentContainerView +import otus.gpb.homework.fragments.databinding.FragmentBBinding + +class FragmentB : Fragment() { + + private var _binding: FragmentBBinding? = null + private val binding: FragmentBBinding + get() = _binding ?: throw RuntimeException("FragmentAABinding == null") + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentBBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if (binding.containerFragmentB == null) { + childFragmentManager.beginTransaction() + .replace(R.id.containerFragmentB1, FragmentBA.newInstance()) + .commit() + childFragmentManager.beginTransaction() + .replace(R.id.containerFragmentB2, FragmentBB.newInstance()) + .commit() + } else { + childFragmentManager.beginTransaction() + .replace(R.id.containerFragmentB, FragmentBA.newInstance()) + .addToBackStack(null) + .commit() + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + + fun newInstance(): FragmentB{ + return FragmentB() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentBA.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentBA.kt new file mode 100644 index 0000000..769d4ed --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentBA.kt @@ -0,0 +1,55 @@ +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 android.widget.Button +import androidx.fragment.app.FragmentContainerView +import otus.gpb.homework.fragments.databinding.FragmentAABinding +import otus.gpb.homework.fragments.databinding.FragmentABBinding +import otus.gpb.homework.fragments.databinding.FragmentBABinding + +class FragmentBA : Fragment() { + + private var _binding: FragmentBABinding? = null + private val binding: FragmentBABinding + get() = _binding ?: throw RuntimeException("FragmentAABinding == null") + + 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) + parentFragmentManager.setFragmentResultListener(REQUEST_KEY_BB, this){ key, bundle -> + val color = bundle.getInt(EXTRA_COLOR) + binding.layoutFragmentBA.setBackgroundColor(color) + } + if(binding.buttonFragmentBB != null){ + binding.buttonFragmentBB?.setOnClickListener(){ + parentFragmentManager.beginTransaction() + .replace(R.id.containerFragmentB, FragmentBB.newInstance()) + .addToBackStack(null) + .commit() + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + + fun newInstance(): FragmentBA{ + return FragmentBA() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/FragmentBB.kt b/app/src/main/java/otus/gpb/homework/fragments/FragmentBB.kt new file mode 100644 index 0000000..f500f62 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentBB.kt @@ -0,0 +1,48 @@ +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.FragmentABBinding +import otus.gpb.homework.fragments.databinding.FragmentBABinding +import otus.gpb.homework.fragments.databinding.FragmentBBBinding + +class FragmentBB : Fragment() { + + private var _binding: FragmentBBBinding? = null + private val binding: FragmentBBBinding + get() = _binding ?: throw RuntimeException("FragmentAABinding == null") + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentBBBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.buttonSendColor.setOnClickListener(){ + parentFragmentManager.popBackStack() + parentFragmentManager.setFragmentResult( + REQUEST_KEY_BB, + bundleOf(EXTRA_COLOR to ColorGenerator.generateColor()) + ) + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + companion object { + fun newInstance(): FragmentBB{ + return FragmentBB() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/MainActivity.kt b/app/src/main/java/otus/gpb/homework/fragments/MainActivity.kt index 5e89c44..103ebc8 100644 --- a/app/src/main/java/otus/gpb/homework/fragments/MainActivity.kt +++ b/app/src/main/java/otus/gpb/homework/fragments/MainActivity.kt @@ -2,11 +2,24 @@ package otus.gpb.homework.fragments import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import otus.gpb.homework.fragments.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { + private val binding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + setContentView(binding.root) + binding.button1.setOnClickListener(){ + val intent = ActivityA.newIntent(this) + startActivity(intent) + } + binding.button2.setOnClickListener(){ + val intent = ActivityB.newIntent(this) + startActivity(intent) + } } } \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/homework/fragments/const.kt b/app/src/main/java/otus/gpb/homework/fragments/const.kt new file mode 100644 index 0000000..bf6fe59 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/const.kt @@ -0,0 +1,4 @@ +package otus.gpb.homework.fragments + +const val REQUEST_KEY_BB = "request_key_bb" +const val EXTRA_COLOR = "color" \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_b.xml b/app/src/main/res/layout-land/fragment_b.xml new file mode 100644 index 0000000..92ede34 --- /dev/null +++ b/app/src/main/res/layout-land/fragment_b.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_b_a.xml b/app/src/main/res/layout-land/fragment_b_a.xml new file mode 100644 index 0000000..1c38379 --- /dev/null +++ b/app/src/main/res/layout-land/fragment_b_a.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_a.xml b/app/src/main/res/layout/activity_a.xml new file mode 100644 index 0000000..bc83179 --- /dev/null +++ b/app/src/main/res/layout/activity_a.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_b.xml b/app/src/main/res/layout/activity_b.xml new file mode 100644 index 0000000..5bea7da --- /dev/null +++ b/app/src/main/res/layout/activity_b.xml @@ -0,0 +1,10 @@ + + + + \ 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 17eab17..549ad7e 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,15 +4,31 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:orientation="vertical" tools:context=".MainActivity"> - + +