Skip to content

Commit

Permalink
Make submission button floating
Browse files Browse the repository at this point in the history
  • Loading branch information
XanderZhu committed Mar 22, 2024
1 parent 9a31c3b commit 6e25efd
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ 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

object StepQuizViewStateDelegateFactory {
fun create(
fragmentStepQuizBinding: FragmentStepQuizBinding,
stepQuizButtonsBinding: LayoutQuizButtonsBinding,
descriptionBinding: LayoutStepQuizDescriptionBinding?,
skeletonView: View,
vararg quizViews: View
Expand All @@ -35,7 +37,7 @@ object StepQuizViewStateDelegateFactory {
*listOfNotNull(
fragmentStepQuizBinding.stepQuizFeedbackBlocks.root,
descriptionBinding?.stepQuizDescription,
fragmentStepQuizBinding.stepQuizButtons.stepQuizSubmitButton,
stepQuizButtonsBinding.stepQuizSubmitButton,
*quizViews
).toTypedArray()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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<StepQuizFeature.StepQuizState>? = null

Expand Down Expand Up @@ -135,14 +149,15 @@ abstract class DefaultStepQuizFragment :

stepQuizStateDelegate = StepQuizViewStateDelegateFactory.create(
fragmentStepQuizBinding = viewBinding,
stepQuizButtonsBinding = stepQuizButtons,
descriptionBinding = descriptionBinding,
skeletonView = skeletonView,
quizViews = quizViews
)
stepQuizFeedbackBlocksDelegate =
StepQuizFeedbackBlocksDelegate(requireContext(), viewBinding.stepQuizFeedbackBlocks)
stepQuizFormDelegate = createStepQuizFormDelegate().also { delegate ->
delegate.customizeSubmissionButton(viewBinding.stepQuizButtons.stepQuizSubmitButton)
delegate.customizeSubmissionButton(stepQuizButtons.stepQuizSubmitButton)
}
stepQuizHintsDelegate = StepQuizHintsDelegate(
binding = viewBinding.stepQuizHints,
Expand Down Expand Up @@ -171,35 +186,35 @@ abstract class DefaultStepQuizFragment :

private fun initButtonsViewStateDelegate() {
stepQuizButtonsViewStateDelegate = ViewStateDelegate<StepQuizButtonsState>().apply {
addState<StepQuizButtonsState.Submit>(viewBinding.stepQuizButtons.stepQuizSubmitButton)
addState<StepQuizButtonsState.Retry>(viewBinding.stepQuizButtons.stepQuizRetryButton)
addState<StepQuizButtonsState.Submit>(stepQuizButtons.stepQuizSubmitButton)
addState<StepQuizButtonsState.Retry>(stepQuizButtons.stepQuizRetryButton)
addState<StepQuizButtonsState.Continue>(
viewBinding.stepQuizButtons.stepQuizContinueButton,
viewBinding.stepQuizButtons.stepQuizContinueFrame
stepQuizButtons.stepQuizContinueButton,
stepQuizButtons.stepQuizContinueFrame
)
addState<StepQuizButtonsState.RetryLogoAndSubmit>(
viewBinding.stepQuizButtons.stepQuizRetryLogoOnlyButton,
viewBinding.stepQuizButtons.stepQuizSubmitButton
stepQuizButtons.stepQuizRetryLogoOnlyButton,
stepQuizButtons.stepQuizSubmitButton
)
addState<StepQuizButtonsState.RetryLogoAndContinue>(
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)
}
Expand Down Expand Up @@ -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 -> {
Expand All @@ -407,6 +422,7 @@ abstract class DefaultStepQuizFragment :
else -> StepQuizButtonsState.Submit
}
stepQuizButtonsViewStateDelegate?.switchState(buttonsState)
updateFeedbackMargin()

val replyValidation = submissionState.replyValidation
if (replyValidation is ReplyValidationResult.Error) {
Expand All @@ -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<MarginLayoutParams> {
bottomMargin = buttons.height + buttons.marginBottom + buttons.marginTop
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,14 @@
android:visibility="gone"
tools:visibility="visible"/>

<include
android:id="@+id/stepQuizButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
layout="@layout/layout_quiz_buttons" />

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,14 @@
android:visibility="gone"
tools:visibility="visible"/>

<include
android:id="@+id/stepQuizButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
layout="@layout/layout_quiz_buttons" />

</androidx.constraintlayout.widget.ConstraintLayout>
12 changes: 1 addition & 11 deletions androidHyperskillApp/src/main/res/layout/fragment_step_quiz.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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" />

<include
android:id="@+id/stepQuizButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
layout="@layout/layout_quiz_buttons" />
app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit 6e25efd

Please sign in to comment.