From 255f9a0061931f030b6b726d6b9ce41dfee6fac1 Mon Sep 17 00:00:00 2001 From: Tiago Pereira Date: Fri, 28 Jun 2019 14:05:42 +0100 Subject: [PATCH] RTL support. --- CHANGELOG.md | 7 +- README.md | 1 + materialspinner/build.gradle | 4 +- .../main/kotlin/com/tiper/MaterialSpinner.kt | 97 +++++++++++++++---- materialspinner/src/main/res/values/attrs.xml | 1 + .../materialspinner/sample/MainActivity.kt | 22 ++--- sample/src/main/res/layout/activity_main.xml | 9 +- sample/src/main/res/values-ar-rEG/arrays.xml | 13 +++ sample/src/main/res/values-ar-rEG/strings.xml | 7 ++ sample/src/main/res/values/strings.xml | 7 +- 10 files changed, 128 insertions(+), 40 deletions(-) create mode 100644 sample/src/main/res/values-ar-rEG/arrays.xml create mode 100644 sample/src/main/res/values-ar-rEG/strings.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index d49f367..6a09f23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ Change Log ========== -Version 1.2.0 *(2019-06-17)* +Version 1.3.0 *(2019-06-28)* +---------------------------- + + * New: Added RTL support. + +Version 1.2.0 *(2019-06-27)* ---------------------------- * New: Added support for custom drawables. diff --git a/README.md b/README.md index 338da5f..3fb8bbc 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ dependencies { - Showing a prompt when `spinnerMode` is `dialog`. - Showing a bottom sheet when `spinnerMode` is `bottomsheet`. - Custom spinner drawables. +- RTL support. ## Usage There is a [sample](https://github.com/tiper/MaterialSpinner/tree/master/sample) provided which shows how to use the library, but for completeness, here is all that is required to get MaterialSpinner working: diff --git a/materialspinner/build.gradle b/materialspinner/build.gradle index 2b94b92..3ee8b09 100644 --- a/materialspinner/build.gradle +++ b/materialspinner/build.gradle @@ -18,8 +18,8 @@ android { defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.sdkVersion - versionCode 120 - versionName "1.2.0" + versionCode 130 + versionName "1.3.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/materialspinner/src/main/kotlin/com/tiper/MaterialSpinner.kt b/materialspinner/src/main/kotlin/com/tiper/MaterialSpinner.kt index f2df08d..49770aa 100644 --- a/materialspinner/src/main/kotlin/com/tiper/MaterialSpinner.kt +++ b/materialspinner/src/main/kotlin/com/tiper/MaterialSpinner.kt @@ -16,20 +16,20 @@ import android.support.design.widget.TextInputEditText import android.support.design.widget.TextInputLayout import android.support.v4.content.res.ResourcesCompat import android.support.v4.graphics.drawable.DrawableCompat +import android.support.v4.text.TextUtilsCompat +import android.support.v4.view.ViewCompat import android.support.v7.widget.ListPopupWindow import android.text.InputType import android.util.AttributeSet +import android.view.Gravity import android.view.SoundEffectConstants import android.view.View import android.view.View.OnFocusChangeListener import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent -import android.widget.AdapterView -import android.widget.ListAdapter -import android.widget.ListView -import android.widget.SpinnerAdapter -import android.widget.ThemedSpinnerAdapter +import android.widget.* import com.tiper.materialspinner.R +import java.util.* /** * Layout which wraps an [TextInputEditText] to show a floating label when the hint is hidden due to @@ -100,6 +100,13 @@ open class MaterialSpinner @JvmOverloads constructor( */ var onItemClickListener: OnItemClickListener? = null + /** + * The layout direction of this view. + * {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL. + * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL. + */ + private var direction = if (isLayoutRtl()) ViewCompat.LAYOUT_DIRECTION_RTL else ViewCompat.LAYOUT_DIRECTION_LTR + /** * The currently selected item. */ @@ -153,6 +160,23 @@ open class MaterialSpinner @JvmOverloads constructor( init { context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinner).run { + getInt(R.styleable.MaterialSpinner_android_gravity, -1).let { + if (it > -1) { + gravity = it + editText.gravity = it + } else { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { + @SuppressLint("RtlHardcoded") + if (isLayoutRtl()) { + gravity = Gravity.RIGHT + editText.gravity = Gravity.RIGHT + } else { + gravity = Gravity.LEFT + editText.gravity = Gravity.LEFT + } + } + } + } editText.isEnabled = getBoolean(R.styleable.MaterialSpinner_android_enabled, editText.isEnabled) editText.isFocusable = @@ -254,18 +278,21 @@ open class MaterialSpinner @JvmOverloads constructor( } fun setDrawable(drawable: Drawable?, applyTint: Boolean = true) { - editText.setCompoundDrawablesWithIntrinsicBounds( - null, - null, - drawable?.let { DrawableCompat.wrap(drawable) }?.apply { - setBounds(0, 0, intrinsicWidth, intrinsicHeight) - if (applyTint) { - DrawableCompat.setTintList(this, colorStateList) - DrawableCompat.setTintMode(this, PorterDuff.Mode.SRC_IN) - } - }, - null - ) + drawable?.let { DrawableCompat.wrap(drawable) }?.apply { + setBounds(0, 0, intrinsicWidth, intrinsicHeight) + if (applyTint) { + DrawableCompat.setTintList(this, colorStateList) + DrawableCompat.setTintMode(this, PorterDuff.Mode.SRC_IN) + } + }.let { + if (isLayoutRtl()) { + Pair(it, null) + } else { + Pair(null, it) + } + }.let { (left, right) -> + editText.setCompoundDrawablesWithIntrinsicBounds(left, null, right, null) + } } override fun setOnClickListener(l: OnClickListener?) { @@ -303,6 +330,19 @@ open class MaterialSpinner @JvmOverloads constructor( super.setFocusableInTouchMode(focusableInTouchMode) } + /** + * @see [android.view.View.onRtlPropertiesChanged] + */ + override fun onRtlPropertiesChanged(layoutDirection: Int) { + if (direction != layoutDirection) { + direction = layoutDirection + editText.compoundDrawables.let { + editText.setCompoundDrawablesWithIntrinsicBounds(it[2], null, it[0], null) + } + } + super.onRtlPropertiesChanged(layoutDirection) + } + /** * Call the OnItemClickListener, if it is defined. * Performs all normal actions associated with clicking: reporting accessibility event, playing @@ -335,6 +375,25 @@ open class MaterialSpinner @JvmOverloads constructor( prompt = context.getText(promptId) } + /** + * Returns if this view layout should be in a RTL direction. + * @return True if is RTL, false otherwise . + */ + private fun isLayoutRtl(): Boolean { + return Locale.getDefault().isLayoutRtl() + } + + /** + * Returns if this Locale direction is RTL. + * @return True if is RTL, false otherwise . + */ + private fun Locale.isLayoutRtl(): Boolean { + return TextUtilsCompat.getLayoutDirectionFromLocale(this) == ViewCompat.LAYOUT_DIRECTION_RTL + } + + /** + * @see [android.support.v4.content.res.ResourcesCompat.getDrawable] + */ private fun Context.getDrawableCompat( @DrawableRes id: Int, theme: Resources.Theme? @@ -342,6 +401,10 @@ open class MaterialSpinner @JvmOverloads constructor( return resources.getDrawableCompat(id, theme) } + /** + * @see [android.support.v4.content.res.ResourcesCompat.getDrawable] + */ + @Throws(Resources.NotFoundException::class) private fun Resources.getDrawableCompat( @DrawableRes id: Int, theme: Resources.Theme? diff --git a/materialspinner/src/main/res/values/attrs.xml b/materialspinner/src/main/res/values/attrs.xml index 57fb8cf..2913a56 100644 --- a/materialspinner/src/main/res/values/attrs.xml +++ b/materialspinner/src/main/res/values/attrs.xml @@ -9,6 +9,7 @@ + diff --git a/sample/src/main/kotlin/com/tiper/materialspinner/sample/MainActivity.kt b/sample/src/main/kotlin/com/tiper/materialspinner/sample/MainActivity.kt index fd1440d..174c84d 100644 --- a/sample/src/main/kotlin/com/tiper/materialspinner/sample/MainActivity.kt +++ b/sample/src/main/kotlin/com/tiper/materialspinner/sample/MainActivity.kt @@ -55,31 +55,23 @@ class MainActivity : AppCompatActivity() { material_spinner_1.selection = ListView.INVALID_POSITION } b1_error.setOnClickListener { - if (material_spinner_1.error.isNullOrEmpty()) { - material_spinner_1.error = "I am an error" - } else { - material_spinner_1.error = null - } + material_spinner_1.onClick() } b2_clear.setOnClickListener { material_spinner_2.selection = ListView.INVALID_POSITION } b2_error.setOnClickListener { - if (material_spinner_2.error.isNullOrEmpty()) { - material_spinner_2.error = "I am an error" - } else { - material_spinner_2.error = null - } + material_spinner_2.onClick() } b3_clear.setOnClickListener { material_spinner_3.selection = ListView.INVALID_POSITION } b3_error.setOnClickListener { - if (material_spinner_3.error.isNullOrEmpty()) { - material_spinner_3.error = "I am an error" - } else { - material_spinner_3.error = null - } + material_spinner_3.onClick() } } + + private fun MaterialSpinner.onClick() { + error = if (error.isNullOrEmpty()) resources.getText(R.string.error) else null + } } diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml index 7e119fa..1c124c3 100644 --- a/sample/src/main/res/layout/activity_main.xml +++ b/sample/src/main/res/layout/activity_main.xml @@ -41,7 +41,7 @@ style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="MaterialSpinner 1" + android:hint="@string/materialspinner_1" app:spinnerMode="bottomsheet" /> diff --git a/sample/src/main/res/values-ar-rEG/arrays.xml b/sample/src/main/res/values-ar-rEG/arrays.xml new file mode 100644 index 0000000..0222505 --- /dev/null +++ b/sample/src/main/res/values-ar-rEG/arrays.xml @@ -0,0 +1,13 @@ + + + + الزئبق + فينوس + الأرض + المريخ + كوكب المشتري + زحل + أورانوس + نبتون + + diff --git a/sample/src/main/res/values-ar-rEG/strings.xml b/sample/src/main/res/values-ar-rEG/strings.xml new file mode 100644 index 0000000..bb9124f --- /dev/null +++ b/sample/src/main/res/values-ar-rEG/strings.xml @@ -0,0 +1,7 @@ + + مادة الدوار + مادة الدوار 1 + مادة الدوار 2 + 3 مادة الدوار + 3أنا خطأ + diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml index 3e47fa2..c40881b 100644 --- a/sample/src/main/res/values/strings.xml +++ b/sample/src/main/res/values/strings.xml @@ -1,3 +1,8 @@ - MaterialSpinner + MaterialSpinner + Material Spinner + Material Spinner 1 + Material Spinner 2 + Material Spinner 3 + I am an error