diff --git a/health-sdk/example-app/src/main/res/layout/fragment_order_details.xml b/health-sdk/example-app/src/main/res/layout/fragment_order_details.xml
index 599f4af53..eda8a1809 100644
--- a/health-sdk/example-app/src/main/res/layout/fragment_order_details.xml
+++ b/health-sdk/example-app/src/main/res/layout/fragment_order_details.xml
@@ -1,7 +1,6 @@
-
-
-
+
+ android:layout_marginTop="@dimen/gps_large"
+ android:orientation="vertical"
+ app:layout_constraintTop_toTopOf="parent">
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/gps_medium"
+ android:hint="@string/recipient"
+ app:layout_constraintTop_toTopOf="parent"
+ app:boxBackgroundColor="#ffffff">
-
+
+
-
-
+ android:layout_height="wrap_content"
+ android:hint="@string/iban"
+ app:layout_constraintTop_toBottomOf="@id/recipient_input_layout"
+ app:boxBackgroundColor="#ffffff">
-
+
+
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/gps_medium"
+ android:hint="@string/amount"
+ app:layout_constraintTop_toBottomOf="@id/iban_input_layout"
+ app:boxBackgroundColor="#ffffff">
-
+
+
-
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/gps_medium"
+ android:hint="@string/reference_number"
+ app:layout_constraintTop_toBottomOf="@id/amount_input_layout"
+ app:boxBackgroundColor="#ffffff">
-
+
+
+
+
+
\ No newline at end of file
diff --git a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt
index 87348b7cf..7b932c23d 100644
--- a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt
+++ b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt
@@ -2,9 +2,16 @@ package net.gini.android.health.sdk.review
import android.os.Build
import android.os.Bundle
+import android.transition.ChangeBounds
+import android.transition.Transition
+import android.transition.TransitionListenerAdapter
+import android.transition.TransitionManager
+import android.transition.TransitionSet
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.ViewGroup.MarginLayoutParams
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.ViewCompat
@@ -21,12 +28,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import androidx.transition.ChangeBounds
-import androidx.transition.Transition
-import androidx.transition.TransitionListenerAdapter
-import androidx.transition.TransitionManager
-import androidx.transition.TransitionSet
-import com.google.android.material.math.MathUtils.lerp
+import com.google.android.material.animation.AnimationUtils.lerp
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayoutMediator
import dev.chrisbanes.insetter.applyInsetter
@@ -48,6 +50,7 @@ import net.gini.android.internal.payment.utils.autoCleared
import net.gini.android.internal.payment.utils.extensions.getFontScale
import net.gini.android.internal.payment.utils.extensions.getLayoutInflaterWithGiniPaymentThemeAndLocale
import net.gini.android.internal.payment.utils.extensions.getLocaleStringResource
+import net.gini.android.internal.payment.utils.extensions.isLandscapeOrientation
import net.gini.android.internal.payment.utils.extensions.wrappedWithGiniPaymentThemeAndLocale
import org.jetbrains.annotations.VisibleForTesting
@@ -124,7 +127,6 @@ class ReviewFragment private constructor(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val documentPagerHeight = savedInstanceState?.getInt(PAGER_HEIGHT, -1) ?: -1
-
viewModel.userPreferences = UserPreferences(requireContext())
with(binding) {
@@ -138,6 +140,10 @@ class ReviewFragment private constructor(
binding.paymentDetailsInfoBar.updateLayoutParams {
bottomMargin = -resources.getDimensionPixelSize(net.gini.android.internal.payment.R.dimen.gps_medium_12)
}
+
+ if (resources.isLandscapeOrientation()) {
+ setupLandscapeBehavior()
+ }
}
private fun GhsFragmentReviewBinding.setStateListeners() {
@@ -243,6 +249,7 @@ class ReviewFragment private constructor(
}
private fun GhsFragmentReviewBinding.removePagerConstraintAndSetPreviousHeightIfNeeded(savedHeight: Int) {
+ if (resources.isLandscapeOrientation()) return
root.post {
ConstraintSet().apply {
clone(constraintRoot)
@@ -339,24 +346,50 @@ class ReviewFragment private constructor(
}
}
- private fun GhsFragmentReviewBinding.hideInfoBarAnimated() {
- root.doOnLayout {
- if (paymentDetailsInfoBar.isVisible) {
- TransitionManager.beginDelayedTransition(root, TransitionSet().apply {
- addTransition(ChangeBounds())
- addListener(object : TransitionListenerAdapter() {
- override fun onTransitionEnd(transition: Transition) {
- super.onTransitionEnd(transition)
- paymentDetailsInfoBar.isInvisible = true
+ private fun GhsFragmentReviewBinding.hideInfoBarAnimated() {
+ root.doOnLayout {
+ if (!resources.isLandscapeOrientation()) {
+ if (paymentDetailsInfoBar.isVisible) {
+ TransitionManager.beginDelayedTransition(root, TransitionSet().apply {
+ addTransition(ChangeBounds())
+ addListener(object : TransitionListenerAdapter() {
+ override fun onTransitionEnd(transition: Transition) {
+ super.onTransitionEnd(transition)
+ paymentDetailsInfoBar.isInvisible = true
+ }
+ })
+ })
+ paymentDetailsInfoBar.updateLayoutParams {
+ topToTop = paymentDetailsScrollview.id
+ bottomToTop = ConstraintLayout.LayoutParams.UNSET
}
- })
- })
- paymentDetailsInfoBar.updateLayoutParams {
- topToTop = paymentDetailsScrollview.id
- bottomToTop = ConstraintLayout.LayoutParams.UNSET
+ }
+ } else {
+ paymentInfoLabel?.isVisible = false
}
}
}
+
+ private fun setupLandscapeBehavior() {
+ val dragHandle = binding.dragHandle
+ val fieldsLayout = binding.ghsPaymentDetails.findViewById(net.gini.android.internal.payment.R.id.gps_fields_layout)
+ val bottomLayout = binding.ghsPaymentDetails.findViewById(net.gini.android.internal.payment.R.id.gps_bottom_layout)
+
+ binding.root.post {
+ setupConstraintsForTabLayout((dragHandle?.height ?: 0) + bottomLayout.height)
+ }
+
+ dragHandle?.setOnTouchListener { v, event ->
+ fieldsLayout.alpha = if (isVisible) 0f else 1f
+ fieldsLayout.isVisible = !fieldsLayout.isVisible
+ false
+ }
+ }
+
+ private fun setupConstraintsForTabLayout(collapsedBottomSheetHeight: Int) {
+ val layoutParams = binding.indicator.layoutParams as MarginLayoutParams
+ layoutParams.bottomMargin = collapsedBottomSheetHeight + 20
+ binding.indicator.layoutParams = layoutParams
}
private fun getLocaleStringResource(resourceId: Int): String {
diff --git a/health-sdk/sdk/src/main/res/layout-land/ghs_fragment_review.xml b/health-sdk/sdk/src/main/res/layout-land/ghs_fragment_review.xml
new file mode 100644
index 000000000..79d6b765e
--- /dev/null
+++ b/health-sdk/sdk/src/main/res/layout-land/ghs_fragment_review.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/internal-payment-sdk/sdk/src/main/java/net/gini/android/internal/payment/review/reviewBottomSheet/ReviewBottomSheet.kt b/internal-payment-sdk/sdk/src/main/java/net/gini/android/internal/payment/review/reviewBottomSheet/ReviewBottomSheet.kt
index 52a59c603..9fd7ef960 100644
--- a/internal-payment-sdk/sdk/src/main/java/net/gini/android/internal/payment/review/reviewBottomSheet/ReviewBottomSheet.kt
+++ b/internal-payment-sdk/sdk/src/main/java/net/gini/android/internal/payment/review/reviewBottomSheet/ReviewBottomSheet.kt
@@ -3,11 +3,16 @@ package net.gini.android.internal.payment.review.reviewBottomSheet
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.coordinatorlayout.widget.CoordinatorLayout.LayoutParams
+import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
+import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import net.gini.android.internal.payment.GiniInternalPaymentModule
import net.gini.android.internal.payment.api.model.PaymentDetails
@@ -18,8 +23,10 @@ import net.gini.android.internal.payment.utils.BackListener
import net.gini.android.internal.payment.utils.GpsBottomSheetDialogFragment
import net.gini.android.internal.payment.utils.autoCleared
import net.gini.android.internal.payment.utils.extensions.getLayoutInflaterWithGiniPaymentThemeAndLocale
+import net.gini.android.internal.payment.utils.extensions.isLandscapeOrientation
import net.gini.android.internal.payment.utils.extensions.setBackListener
+
class ReviewBottomSheet private constructor(
private val viewModelFactory: ViewModelProvider.Factory?
) : GpsBottomSheetDialogFragment() {
@@ -28,6 +35,7 @@ class ReviewBottomSheet private constructor(
private val viewModel: ReviewBottomSheetViewModel by viewModels { viewModelFactory ?: object : ViewModelProvider.Factory {} }
private var binding: GpsBottomSheetReviewBinding by autoCleared()
+ private lateinit var bottomSheet: FrameLayout
private val listener = object: ReviewViewListener {
override fun onPaymentButtonTapped(paymentDetails: PaymentDetails) {
viewModel.reviewViewListener?.onPaymentButtonTapped(paymentDetails)
@@ -52,6 +60,17 @@ class ReviewBottomSheet private constructor(
viewModel.backListener?.let {
(dialog as BottomSheetDialog).setBackListener(it)
}
+
+ // For the sake of consistency with the review flow WITH document, disable
+ // default draggable behavior on the bottom sheet when in landscape mode
+ dialog.setOnShowListener {
+ bottomSheet = dialog
+ .findViewById(com.google.android.material.R.id.design_bottom_sheet)
+ BottomSheetBehavior.from(bottomSheet).apply {
+ isDraggable = !resources.isLandscapeOrientation()
+ isCancelable = !resources.isLandscapeOrientation()
+ }
+ }
return dialog
}
@@ -63,6 +82,18 @@ class ReviewBottomSheet private constructor(
binding = GpsBottomSheetReviewBinding.inflate(inflater, container, false)
binding.gpsReviewLayout.reviewComponent = viewModel.reviewComponent
binding.gpsReviewLayout.listener = listener
+ if (resources.isLandscapeOrientation()) {
+ val fieldsLayout =
+ binding.gpsReviewLayout.findViewById(net.gini.android.internal.payment.R.id.gps_fields_layout)
+ binding.dragHandle.setOnTouchListener { v, event ->
+ // By default, bottom sheet has gravity TOP - layout changes make it jump to the top of the screen
+ // set layoutGravity = Gravity.BOTTOM prevents that.
+ val layoutParams = bottomSheet.layoutParams as LayoutParams
+ layoutParams.gravity = Gravity.BOTTOM
+ fieldsLayout.isVisible = !fieldsLayout.isVisible
+ false
+ }
+ }
return binding.root
}
diff --git a/internal-payment-sdk/sdk/src/main/res/layout-land/gps_bottom_sheet_review.xml b/internal-payment-sdk/sdk/src/main/res/layout-land/gps_bottom_sheet_review.xml
new file mode 100644
index 000000000..3a7314f14
--- /dev/null
+++ b/internal-payment-sdk/sdk/src/main/res/layout-land/gps_bottom_sheet_review.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/internal-payment-sdk/sdk/src/main/res/layout-land/gps_review.xml b/internal-payment-sdk/sdk/src/main/res/layout-land/gps_review.xml
new file mode 100644
index 000000000..4d1d0e12c
--- /dev/null
+++ b/internal-payment-sdk/sdk/src/main/res/layout-land/gps_review.xml
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file