diff --git a/.kotlin/errors/errors-1746969991873.log b/.kotlin/errors/errors-1746969991873.log new file mode 100644 index 0000000..1219b50 --- /dev/null +++ b/.kotlin/errors/errors-1746969991873.log @@ -0,0 +1,4 @@ +kotlin version: 2.0.21 +error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: + 1. Kotlin compile daemon is ready + diff --git a/app/build.gradle b/app/build.gradle index c5cf1b8..e9b2f4d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,13 +8,13 @@ kotlin { } android { - compileSdk 34 + compileSdk 35 namespace "otus.gpb.homework.fragments" defaultConfig { applicationId "otus.gpb.homework.fragments" minSdk 26 - targetSdk 34 + targetSdk 35 versionCode 1 versionName "1.0" @@ -34,6 +34,10 @@ android { kotlinOptions { jvmTarget = '17' } + + buildFeatures { + viewBinding true + } } dependencies { @@ -42,7 +46,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.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' + implementation("androidx.fragment:fragment-ktx:1.8.6") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9604b34..050dd0d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,14 @@ android:supportsRtl="true" android:theme="@style/Theme.Fragments" tools:targetApi="31"> + + 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..6b93890 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentA.kt @@ -0,0 +1,76 @@ +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 androidx.activity.OnBackPressedCallback +import otus.gpb.homework.fragments.databinding.ActivityTask1Binding +import otus.gpb.homework.fragments.databinding.FragmentABinding + + +/** + * A simple [Fragment] subclass. + * Use the [FragmentA.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentA : Fragment() { + private var _binding: FragmentABinding? = null + private val binding get() = _binding!! + + override fun onAttach(context: Context) { + super.onAttach(context) + val callback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (childFragmentManager.backStackEntryCount > 0) { + childFragmentManager.popBackStack() + val currentFragment = childFragmentManager.findFragmentByTag("AA") + if (currentFragment != null && currentFragment.isVisible ) { + binding.btnOpenFragmentAA.visibility = View.VISIBLE + } + } else { + isEnabled = false + activity?.onBackPressedDispatcher?.onBackPressed() + } + } + } + activity?.onBackPressedDispatcher?.addCallback(callback) + } + + 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) + + binding.btnOpenFragmentAA.setOnClickListener { + val backgroundColor = ColorGenerator.generateColor() + childFragmentManager.beginTransaction() + .replace(R.id.fragmentContainerA, FragmentAA.newInstance(backgroundColor), "AA") + .addToBackStack(null) + .commit() + binding.btnOpenFragmentAA.visibility = View.GONE + } + + } + + + companion object { + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment FragmentA. + */ + @JvmStatic + fun newInstance(): FragmentA = 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..8c72c50 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentAA.kt @@ -0,0 +1,62 @@ +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.FragmentAABinding + +private const val BACKGROUND_COLOR = "background_color" + + +/** + * A simple [Fragment] subclass. + * Use the [FragmentAA.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentAA : Fragment() { + + private var _binding: FragmentAABinding? = null + private val binding get() = _binding!! + private var backGroundColor: Int? = null + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + backGroundColor?.let { view.setBackgroundColor(backGroundColor!!) } + binding.btnOpenFragmentAB.setOnClickListener { + val backgroundColor = ColorGenerator.generateColor() + parentFragmentManager.beginTransaction() + .replace(R.id.fragmentContainerA, FragmentAB.newInstance(backgroundColor), "AB") + .addToBackStack(null) + .commit() + } + } + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = FragmentAABinding.inflate(inflater, container, false) + return binding.root + } + + companion object { + @JvmStatic + fun newInstance(backGroundColor: Int) = + FragmentAA().apply { + arguments = Bundle().apply { + putInt(BACKGROUND_COLOR, backGroundColor) + } + } + } +} \ 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..39fd4b2 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentAB.kt @@ -0,0 +1,57 @@ +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 + +// TODO: Rename parameter arguments, choose names that match +// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER +private const val BACKGROUND_COLOR = "backGroundColor" + +/** + * A simple [Fragment] subclass. + * Use the [FragmentAB.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentAB : Fragment() { + + private var backGroundColor: Int? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + backGroundColor?.let { view.setBackgroundColor(it) } + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_a_b, container, false) + } + + companion object { + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * @return A new instance of fragment FragmentAB. + */ + + @JvmStatic + fun newInstance(backGroundColor: Int) = + FragmentAB().apply { + arguments = Bundle().apply { + putInt(BACKGROUND_COLOR, backGroundColor) + } + } + } +} \ 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..6d728b8 --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentB.kt @@ -0,0 +1,86 @@ +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 android.widget.FrameLayout +import otus.gpb.homework.fragments.databinding.FragmentABinding +import otus.gpb.homework.fragments.databinding.FragmentBBinding + + + +/** + * A simple [Fragment] subclass. + * Use the [FragmentB.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentB : Fragment(), FragmentBA.ButtonFragmentOnClickListener { + + private var isLandScape = false + private var fragmentBAColor: Int? = null + + private var _binding: FragmentBBinding? = null + private val binding get() = _binding!! + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + isLandScape = resources.getBoolean(R.bool.isLandscape) + fragmentBAColor = savedInstanceState?.getInt("fragmentBA_color") + if (fragmentBAColor == null) { + fragmentBAColor = ColorGenerator.generateColor() + } + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + fragmentBAColor?.let { + outState.putInt("fragmentBA_color", it) + } + } + + 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 (!isLandScape) { + val childFragment = FragmentBA.newInstance(fragmentBAColor!!) + childFragmentManager.beginTransaction() + .replace(R.id.container_ba, childFragment) + .commit() + + view.postDelayed({ (childFragment as ButtonController).addButton(true) }, 500) + + + } else { + childFragmentManager.beginTransaction() + .replace(R.id.container_ba, FragmentBA.newInstance(fragmentBAColor!!)) + .replace(R.id.container_bb, FragmentBB.newInstance(ColorGenerator.generateColor())) + .commit() + } + } + + + override fun setButtonFragmentOnClickListener(button: Button) { + val fragmentBB = FragmentBB.newInstance(ColorGenerator.generateColor()) + childFragmentManager.beginTransaction() + .add(R.id.container_ba, fragmentBB) + .addToBackStack(null) + .commit() + } + +} + +interface ButtonController { + fun addButton(isActive: Boolean) +} \ 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..5b4525e --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentBA.kt @@ -0,0 +1,111 @@ +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 android.widget.FrameLayout +import androidx.fragment.app.setFragmentResult +import otus.gpb.homework.fragments.databinding.FragmentAABinding +import otus.gpb.homework.fragments.databinding.FragmentBABinding + +private const val BACKGROUND_COLOR = "background_color" + +/** + * A simple [Fragment] subclass. + * Use the [FragmentBA.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentBA : Fragment(), ButtonController { + + private var backGroundColor: Int? = null + private lateinit var container: FrameLayout + + private var clickListener: ButtonFragmentOnClickListener? = null + + interface ButtonFragmentOnClickListener { + fun setButtonFragmentOnClickListener(button: Button) + } + + override fun onAttach(context: android.content.Context) { + super.onAttach(context) + parentFragment?.let { + if (it is ButtonFragmentOnClickListener) { + clickListener = it + } + } + } + + private var _binding: FragmentBABinding? = null + private val binding get() = _binding!! + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + } + + savedInstanceState?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + } + + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + backGroundColor?.let { + outState.putInt(BACKGROUND_COLOR, it) + } + } + + 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) + backGroundColor?.let { view.setBackgroundColor(it) } + + container = view as FrameLayout + + + parentFragmentManager.setFragmentResultListener("color", this) { _, bundle -> + backGroundColor = bundle.getInt("color") + view.setBackgroundColor(backGroundColor!!) + } + } + + companion object { + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment FragmentBA. + */ + @JvmStatic + fun newInstance(backGroundColor: Int) = + FragmentBA().apply { + arguments = Bundle().apply { + putInt(BACKGROUND_COLOR, backGroundColor) + } + } + } + + override fun addButton(isActive: Boolean) { + val button = layoutInflater.inflate(R.layout.button_for_fragment_ba, container, false) as Button + button.isEnabled = isActive + button.setOnClickListener { + clickListener?.setButtonFragmentOnClickListener(button) + } + container.addView(button) + } + +} \ 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..ef9926f --- /dev/null +++ b/app/src/main/java/otus/gpb/homework/fragments/FragmentBB.kt @@ -0,0 +1,85 @@ +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.core.os.bundleOf +import otus.gpb.homework.fragments.databinding.FragmentAABinding +import otus.gpb.homework.fragments.databinding.FragmentBBBinding + + +private const val BACKGROUND_COLOR = "background_color" + +/** + * A simple [Fragment] subclass. + * Use the [FragmentBB.newInstance] factory method to + * create an instance of this fragment. + */ +class FragmentBB : Fragment() { + + + private var backGroundColor: Int? = null + + private var _binding: FragmentBBBinding? = null + private val binding get() = _binding!! + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + arguments?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + } + + savedInstanceState?.let { + backGroundColor = it.getInt(BACKGROUND_COLOR) + } + } + + 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) + backGroundColor?.let { view.setBackgroundColor(it) } + + view.findViewById