Skip to content

Commit

Permalink
Set and require android:supportsRtl="true" for RTL layout (#44538)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #44538

Android originated without RTL support. When RTL support was added, Applications needed to set `android:supportsRtl="true"` in their manifest, to allow Android to do RTL specific layout and drawing. This became the default for new projects created by Android Studio at some point.

React Native was not setting this in template, which means apps created from it do not do any of Android's RTL layout, text alignment, or drawing (e.g. in D3652980 8 years ago, a native drawer component came from the wrong side of the screen). RN would still layout the app using Yoga in RTL if in RTL locale though.

This change sets `android:supportsRtl` in template matching default new Android projects, and to avoid mismatched states in the future, will only tell I18NManager that RTL is allowed if `android:supportsRtl` is also set. This is breaking, since existing apps may not get Yoga RTL support unless telling Android that the application should support RTL layout.

Changelog:
[Android][Breaking] - Set and require `android:supportsRtl="true"` for RTL layout

Reviewed By: joevilches

Differential Revision: D57248205

fbshipit-source-id: 3f60c9f855db26f8d34a2e05d460f95961f5ffeb
  • Loading branch information
NickGerleman authored and facebook-github-bot committed May 17, 2024
1 parent 258b481 commit 82c6f8a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.facebook.react.modules.i18nmanager

import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.core.text.TextUtilsCompat
import androidx.core.view.ViewCompat
import java.util.Locale
Expand All @@ -23,6 +24,19 @@ public class I18nUtil private constructor() {
true
} else isRTLAllowed(context) && isDevicePreferredLanguageRTL

/**
* Android relies on the presence of `android:supportsRtl="true"` being set in order to resolve
* RTL as a layout direction for native Android views. RTL in React Native relies on this being
* set.
*/
private fun applicationHasRtlSupport(context: Context): Boolean {
return (context.getApplicationInfo().flags and ApplicationInfo.FLAG_SUPPORTS_RTL) != 0
}

public fun hasRtlSupport(context: Context): Boolean {
return applicationHasRtlSupport(context) || isRTLAllowed(context)
}

/**
* Should be used very early during app start up Before the bridge is initialized
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:supportsRtl="true">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
Expand Down
3 changes: 2 additions & 1 deletion packages/rn-tester/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:supportsRtl="true">
<activity
android:name=".RNTesterActivity"
android:label="@string/app_name"
Expand Down

0 comments on commit 82c6f8a

Please sign in to comment.