diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/factory/StepQuizViewStateDelegateFactory.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/factory/StepQuizViewStateDelegateFactory.kt index 1d8f7fb998..a59bbd95ff 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/factory/StepQuizViewStateDelegateFactory.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/factory/StepQuizViewStateDelegateFactory.kt @@ -2,6 +2,7 @@ package org.hyperskill.app.android.step_quiz.view.factory import android.view.View import org.hyperskill.app.android.databinding.FragmentStepQuizBinding +import org.hyperskill.app.android.databinding.LayoutQuizButtonsBinding import org.hyperskill.app.android.databinding.LayoutStepQuizDescriptionBinding import org.hyperskill.app.step_quiz.presentation.StepQuizFeature import ru.nobird.android.view.base.ui.delegate.ViewStateDelegate @@ -9,6 +10,7 @@ import ru.nobird.android.view.base.ui.delegate.ViewStateDelegate object StepQuizViewStateDelegateFactory { fun create( fragmentStepQuizBinding: FragmentStepQuizBinding, + stepQuizButtonsBinding: LayoutQuizButtonsBinding, descriptionBinding: LayoutStepQuizDescriptionBinding?, skeletonView: View, vararg quizViews: View @@ -35,7 +37,7 @@ object StepQuizViewStateDelegateFactory { *listOfNotNull( fragmentStepQuizBinding.stepQuizFeedbackBlocks.root, descriptionBinding?.stepQuizDescription, - fragmentStepQuizBinding.stepQuizButtons.stepQuizSubmitButton, + stepQuizButtonsBinding.stepQuizSubmitButton, *quizViews ).toTypedArray() ) diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt index 303691f42a..72c2df20c7 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz/view/fragment/DefaultStepQuizFragment.kt @@ -7,12 +7,17 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams import android.widget.LinearLayout import android.widget.TextView import androidx.core.view.MenuHost import androidx.core.view.MenuProvider import androidx.core.view.children +import androidx.core.view.doOnNextLayout import androidx.core.view.isVisible +import androidx.core.view.marginBottom +import androidx.core.view.marginTop +import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle @@ -27,6 +32,7 @@ import org.hyperskill.app.android.core.view.ui.dialog.dismissDialogFragmentIfExi import org.hyperskill.app.android.core.view.ui.fragment.parentOfType import org.hyperskill.app.android.core.view.ui.navigation.requireRouter import org.hyperskill.app.android.databinding.FragmentStepQuizBinding +import org.hyperskill.app.android.databinding.LayoutQuizButtonsBinding import org.hyperskill.app.android.databinding.LayoutStepQuizDescriptionBinding import org.hyperskill.app.android.main.view.ui.navigation.MainScreen import org.hyperskill.app.android.main.view.ui.navigation.MainScreenRouter @@ -74,7 +80,15 @@ abstract class DefaultStepQuizFragment : private val stepQuizViewModel: StepQuizViewModel by viewModels { viewModelFactory } - protected val viewBinding: FragmentStepQuizBinding by viewBinding(FragmentStepQuizBinding::bind) + private val viewBinding: FragmentStepQuizBinding by viewBinding(FragmentStepQuizBinding::bind) + protected val stepQuizButtons: LayoutQuizButtonsBinding by viewBinding( + vbFactory = LayoutQuizButtonsBinding::bind, + viewProvider = { + requireParentFragment() + .requireView() + .findViewById(R.id.stepQuizButtons) + } + ) private var stepQuizStateDelegate: ViewStateDelegate? = null @@ -135,6 +149,7 @@ abstract class DefaultStepQuizFragment : stepQuizStateDelegate = StepQuizViewStateDelegateFactory.create( fragmentStepQuizBinding = viewBinding, + stepQuizButtonsBinding = stepQuizButtons, descriptionBinding = descriptionBinding, skeletonView = skeletonView, quizViews = quizViews @@ -142,7 +157,7 @@ abstract class DefaultStepQuizFragment : stepQuizFeedbackBlocksDelegate = StepQuizFeedbackBlocksDelegate(requireContext(), viewBinding.stepQuizFeedbackBlocks) stepQuizFormDelegate = createStepQuizFormDelegate().also { delegate -> - delegate.customizeSubmissionButton(viewBinding.stepQuizButtons.stepQuizSubmitButton) + delegate.customizeSubmissionButton(stepQuizButtons.stepQuizSubmitButton) } stepQuizHintsDelegate = StepQuizHintsDelegate( binding = viewBinding.stepQuizHints, @@ -171,35 +186,35 @@ abstract class DefaultStepQuizFragment : private fun initButtonsViewStateDelegate() { stepQuizButtonsViewStateDelegate = ViewStateDelegate().apply { - addState(viewBinding.stepQuizButtons.stepQuizSubmitButton) - addState(viewBinding.stepQuizButtons.stepQuizRetryButton) + addState(stepQuizButtons.stepQuizSubmitButton) + addState(stepQuizButtons.stepQuizRetryButton) addState( - viewBinding.stepQuizButtons.stepQuizContinueButton, - viewBinding.stepQuizButtons.stepQuizContinueFrame + stepQuizButtons.stepQuizContinueButton, + stepQuizButtons.stepQuizContinueFrame ) addState( - viewBinding.stepQuizButtons.stepQuizRetryLogoOnlyButton, - viewBinding.stepQuizButtons.stepQuizSubmitButton + stepQuizButtons.stepQuizRetryLogoOnlyButton, + stepQuizButtons.stepQuizSubmitButton ) addState( - viewBinding.stepQuizButtons.stepQuizRetryLogoOnlyButton, - viewBinding.stepQuizButtons.stepQuizContinueButton, - viewBinding.stepQuizButtons.stepQuizContinueFrame + stepQuizButtons.stepQuizRetryLogoOnlyButton, + stepQuizButtons.stepQuizContinueButton, + stepQuizButtons.stepQuizContinueFrame ) } } private fun setupQuizButtons() { - viewBinding.stepQuizButtons.stepQuizSubmitButton.setOnClickListener { + stepQuizButtons.stepQuizSubmitButton.setOnClickListener { onSubmitButtonClicked() } - viewBinding.stepQuizButtons.stepQuizRetryButton.setOnClickListener { + stepQuizButtons.stepQuizRetryButton.setOnClickListener { onRetryButtonClicked() } - viewBinding.stepQuizButtons.stepQuizRetryLogoOnlyButton.setOnClickListener { + stepQuizButtons.stepQuizRetryLogoOnlyButton.setOnClickListener { onRetryButtonClicked() } - viewBinding.stepQuizButtons.stepQuizContinueButton.setOnClickListener { + stepQuizButtons.stepQuizContinueButton.setOnClickListener { parentOfType(StepCompletionHost::class.java) ?.onNewMessage(StepCompletionFeature.Message.ContinuePracticingClicked) } @@ -385,7 +400,7 @@ abstract class DefaultStepQuizFragment : stepQuizFeedbackBlocksDelegate?.setState( stepQuizFeedbackMapper.mapToStepQuizFeedbackState(step.block.name, state) ) - viewBinding.stepQuizButtons.stepQuizSubmitButton.isEnabled = StepQuizResolver.isQuizEnabled(state) + stepQuizButtons.stepQuizSubmitButton.isEnabled = StepQuizResolver.isQuizEnabled(state) when (val submissionState = state.submissionState) { is StepQuizFeature.SubmissionState.Loaded -> { @@ -407,6 +422,7 @@ abstract class DefaultStepQuizFragment : else -> StepQuizButtonsState.Submit } stepQuizButtonsViewStateDelegate?.switchState(buttonsState) + updateFeedbackMargin() val replyValidation = submissionState.replyValidation if (replyValidation is ReplyValidationResult.Error) { @@ -417,6 +433,15 @@ abstract class DefaultStepQuizFragment : } is StepQuizFeature.SubmissionState.Empty -> { stepQuizButtonsViewStateDelegate?.switchState(StepQuizButtonsState.Submit) + updateFeedbackMargin() + } + } + } + + private fun updateFeedbackMargin() { + stepQuizButtons.root.doOnNextLayout { buttons -> + viewBinding.root.updateLayoutParams { + bottomMargin = buttons.height + buttons.marginBottom + buttons.marginTop } } } diff --git a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_code/view/fragment/CodeStepQuizFragment.kt b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_code/view/fragment/CodeStepQuizFragment.kt index 8242ab4d77..5fbb7836a1 100644 --- a/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_code/view/fragment/CodeStepQuizFragment.kt +++ b/androidHyperskillApp/src/main/java/org/hyperskill/app/android/step_quiz_code/view/fragment/CodeStepQuizFragment.kt @@ -200,7 +200,7 @@ class CodeStepQuizFragment : lang = lang, code = code, step = step, - isShowRetryButton = viewBinding.stepQuizButtons.stepQuizRetryLogoOnlyButton.isVisible + isShowRetryButton = stepQuizButtons.stepQuizRetryLogoOnlyButton.isVisible ) ) .showIfNotExists(childFragmentManager, CodeStepQuizFullScreenDialogFragment.TAG) diff --git a/androidHyperskillApp/src/main/res/layout/fragment_stage_step_wrapper.xml b/androidHyperskillApp/src/main/res/layout/fragment_stage_step_wrapper.xml index 5ae1f7b733..c4b178204f 100644 --- a/androidHyperskillApp/src/main/res/layout/fragment_stage_step_wrapper.xml +++ b/androidHyperskillApp/src/main/res/layout/fragment_stage_step_wrapper.xml @@ -88,4 +88,14 @@ android:visibility="gone" tools:visibility="visible"/> + + \ No newline at end of file diff --git a/androidHyperskillApp/src/main/res/layout/fragment_step_practice.xml b/androidHyperskillApp/src/main/res/layout/fragment_step_practice.xml index db00ca8fa9..9700e8fa8b 100644 --- a/androidHyperskillApp/src/main/res/layout/fragment_step_practice.xml +++ b/androidHyperskillApp/src/main/res/layout/fragment_step_practice.xml @@ -49,4 +49,14 @@ android:visibility="gone" tools:visibility="visible"/> + + \ No newline at end of file diff --git a/androidHyperskillApp/src/main/res/layout/fragment_step_quiz.xml b/androidHyperskillApp/src/main/res/layout/fragment_step_quiz.xml index a138312251..1fa27e8570 100644 --- a/androidHyperskillApp/src/main/res/layout/fragment_step_quiz.xml +++ b/androidHyperskillApp/src/main/res/layout/fragment_step_quiz.xml @@ -62,18 +62,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" - app:layout_constraintBottom_toTopOf="@+id/stepQuizButtons" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - + app:layout_constraintStart_toStartOf="parent"/> \ No newline at end of file