diff --git a/app/src/main/java/org/oppia/android/app/databinding/MarginBindingAdapters.java b/app/src/main/java/org/oppia/android/app/databinding/MarginBindingAdapters.java index 5c336d0c05c..69dd1f379c4 100644 --- a/app/src/main/java/org/oppia/android/app/databinding/MarginBindingAdapters.java +++ b/app/src/main/java/org/oppia/android/app/databinding/MarginBindingAdapters.java @@ -3,7 +3,7 @@ import android.view.View; import android.view.ViewGroup.MarginLayoutParams; import androidx.annotation.NonNull; -import androidx.core.view.ViewCompat; +import androidx.core.view.MarginLayoutParamsCompat; import androidx.databinding.BindingAdapter; /** Holds all custom binding adapters that set margin values. */ @@ -14,12 +14,7 @@ public final class MarginBindingAdapters { public static void setLayoutMarginStart(@NonNull View view, float marginStart) { if (view.getLayoutParams() instanceof MarginLayoutParams) { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - float marginEnd = params.getMarginEnd(); - if (isRtlLayout(view)) { - setLayoutDirectionalMargins(view, (int) marginEnd, (int) marginStart); - } else { - setLayoutDirectionalMargins(view, (int) marginStart, (int) marginEnd); - } + MarginLayoutParamsCompat.setMarginStart(params, (int) marginStart); view.requestLayout(); } } @@ -29,36 +24,18 @@ public static void setLayoutMarginStart(@NonNull View view, float marginStart) { public static void setLayoutMarginEnd(@NonNull View view, float marginEnd) { if (view.getLayoutParams() instanceof MarginLayoutParams) { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - float marginStart = params.getMarginStart(); - if (isRtlLayout(view)) { - setLayoutDirectionalMargins(view, (int) marginEnd, (int) marginStart); - } else { - setLayoutDirectionalMargins(view, (int) marginStart, (int) marginEnd); - } + MarginLayoutParamsCompat.setMarginEnd(params, (int) marginEnd); view.requestLayout(); } } - private static void setLayoutDirectionalMargins( - @NonNull View view, - int marginStart, - int marginEnd - ) { - MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - params.setMargins(marginStart, params.topMargin, marginEnd, params.bottomMargin); - } - /** Used to set a margin-top for views. */ @BindingAdapter("app:layoutMarginTop") public static void setLayoutMarginTop(@NonNull View view, float marginTop) { if (view.getLayoutParams() instanceof MarginLayoutParams) { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - params.setMargins( - params.getMarginStart(), - (int) marginTop, - params.getMarginEnd(), - params.bottomMargin - ); + params.topMargin = (int) marginTop; + view.setLayoutParams(params); view.requestLayout(); } } @@ -68,12 +45,8 @@ public static void setLayoutMarginTop(@NonNull View view, float marginTop) { public static void setLayoutMarginBottom(@NonNull View view, float marginBottom) { if (view.getLayoutParams() instanceof MarginLayoutParams) { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); - params.setMargins( - params.getMarginStart(), - params.topMargin, - params.getMarginEnd(), - (int) marginBottom - ); + params.bottomMargin = (int) marginBottom; + view.setLayoutParams(params); view.requestLayout(); } } @@ -92,8 +65,4 @@ public static void setLayoutMargin(@NonNull View view, float margin) { view.requestLayout(); } } - - private static boolean isRtlLayout(View view) { - return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL; - } } diff --git a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt index 35faf761900..5b7202c4d9b 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/databinding/MarginBindingAdaptersTest.kt @@ -4,6 +4,7 @@ import android.app.Activity import android.app.Application import android.content.Context import android.content.Intent +import android.view.View import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat @@ -34,8 +35,10 @@ import org.oppia.android.app.application.ApplicationInjectorProvider import org.oppia.android.app.application.ApplicationModule import org.oppia.android.app.application.ApplicationStartupListenerModule import org.oppia.android.app.application.testing.TestingBuildFlavorModule +import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginBottom import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginEnd import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginStart +import org.oppia.android.app.databinding.MarginBindingAdapters.setLayoutMarginTop import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule @@ -79,6 +82,7 @@ import org.oppia.android.testing.TestImageLoaderModule import org.oppia.android.testing.TestLogReportingModule import org.oppia.android.testing.junit.InitializeDefaultLocaleRule import org.oppia.android.testing.robolectric.RobolectricModule +import org.oppia.android.testing.threading.TestCoroutineDispatchers import org.oppia.android.testing.threading.TestDispatcherModule import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule @@ -109,8 +113,8 @@ class MarginBindingAdaptersTest { @get:Rule val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() - @Inject - lateinit var context: Context + @Inject lateinit var context: Context + @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers @get:Rule val oppiaTestRule = OppiaTestRule() @@ -128,13 +132,27 @@ class MarginBindingAdaptersTest { fun setUp() { setUpTestApplicationComponent() Intents.init() + testCoroutineDispatchers.registerIdlingResource() } @After fun tearDown() { + testCoroutineDispatchers.unregisterIdlingResource() Intents.release() } + @Config(qualifiers = "land") + @Test + fun testMarginBindableAdapters_landscape_topAndBottomIsCorrect() { + testMarginBindableAdapters_topAndBottomIsCorrect() + } + + @Config(qualifiers = "sw600dp-land") + @Test + fun testMarginBindableAdapters_landscapeWide_topAndBottomIsCorrect() { + testMarginBindableAdapters_topAndBottomIsCorrect() + } + @Config(qualifiers = "port") @Test fun testMarginBindableAdapters_ltrIsEnabled_port_marginStartAndMarginEndForLtrIsCorrect() { @@ -275,6 +293,21 @@ class MarginBindingAdaptersTest { assertThat(textView.marginEnd.toFloat()).isWithin(TOLERANCE).of(40f) } + private fun testMarginBindableAdapters_topAndBottomIsCorrect() { + activityRule.scenario.runWithActivity { + val textView: TextView = it.findViewById(R.id.test_margin_text_view) + setLayoutMarginBottom(textView, /* marginBottom= */ 24f) + setLayoutMarginTop(textView, /* marginTop= */ 40f) + + testCoroutineDispatchers.runCurrent() + + val computedTopMargin = textView.y + val computedBottomMargin = (textView.parent as View).height - textView.y - textView.height + assertThat(computedTopMargin).isWithin(TOLERANCE).of(40f) + assertThat(computedBottomMargin).isWithin(TOLERANCE).of(24f) + } + } + private inline fun ActivityScenario.runWithActivity( crossinline action: (A) -> V ): V {