Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Fixes

- We have fixed the textinputs hiding behind on-screen keyboard.
- We have fixed the Android splash screen being stretched. The Mendix logo is now centered and displayed with the correct proportions on all screen sizes.

### Changes

Expand Down
4 changes: 4 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@
-keep class androidx.biometric.** { *; }
-keep class com.sbaiahmed1.reactnativebiometrics.** { *; }

# Splash window background: inflated by class name from res/drawable/bootsplash.xml,
# so R8 cannot see the reference and would otherwise strip it.
-keep class com.mendix.developerapp.splashscreen.CenterCropDrawable { <init>(...); }

#@d11/react-native-fast-image
-keep public class com.dylanvann.fastimage.* {*;}
-keep public class com.dylanvann.fastimage.** {*;}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.mendix.developerapp.splashscreen

import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import org.xmlpull.v1.XmlPullParser

/**
* Draws its `android:src` bitmap scaled uniformly to cover the bounds and centered, the
* equivalent of [android.widget.ImageView.ScaleType.CENTER_CROP].
*
* A plain `<bitmap>` cannot do this: its gravity either scales both axes independently
* (`fill`, which distorts the image) or does not scale at all (`center`, which leaves
* bars on screens larger than the bitmap). We need it for the splash window background,
* where the logo is baked into the artwork and must keep its aspect ratio on every screen.
*
* Inflated by class name from `res/drawable/bootsplash.xml`, so it needs a public no-arg
* constructor and a ProGuard keep rule.
*/
class CenterCropDrawable : Drawable() {

private val paint = Paint(Paint.FILTER_BITMAP_FLAG)
private val matrix = Matrix()
private var bitmap: Bitmap? = null

override fun inflate(
r: Resources,
parser: XmlPullParser,
attrs: AttributeSet,
theme: Resources.Theme?
) {
super.inflate(r, parser, attrs, theme)

val attributes = intArrayOf(android.R.attr.src)
val a = theme?.obtainStyledAttributes(attrs, attributes, 0, 0)
?: r.obtainAttributes(attrs, attributes)

val srcId = try {
a.getResourceId(0, 0)
} finally {
a.recycle()
}

require(srcId != 0) { "CenterCropDrawable requires an android:src attribute" }

// Decode at the authored pixel size instead of letting the framework upscale for
// the device density: the artwork is only shipped up to xhdpi, and we do our own
// scaling anyway, so this is both cheaper and sharper.
val options = BitmapFactory.Options().apply { inScaled = false }
bitmap = BitmapFactory.decodeResource(r, srcId, options)

updateMatrix(bounds)
}

override fun onBoundsChange(bounds: Rect) {
updateMatrix(bounds)
}

private fun updateMatrix(bounds: Rect) {
val bitmap = bitmap ?: return
if (bounds.isEmpty || bitmap.width == 0 || bitmap.height == 0) return

val scale = maxOf(
bounds.width() / bitmap.width.toFloat(),
bounds.height() / bitmap.height.toFloat()
)

matrix.setScale(scale, scale)
matrix.postTranslate(
bounds.left + (bounds.width() - bitmap.width * scale) / 2f,
bounds.top + (bounds.height() - bitmap.height * scale) / 2f
)
}

override fun draw(canvas: Canvas) {
bitmap?.let { canvas.drawBitmap(it, matrix, paint) }
}

override fun setAlpha(alpha: Int) {
if (paint.alpha != alpha) {
paint.alpha = alpha
invalidateSelf()
}
}

override fun getAlpha(): Int = paint.alpha

override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
invalidateSelf()
}

override fun getColorFilter(): ColorFilter? = paint.colorFilter

// Covering the bounds with an opaque bitmap lets the framework skip drawing whatever
// is underneath; without a bitmap we draw nothing and must not claim to be opaque.
override fun getOpacity(): Int = when {
bitmap == null || paint.alpha < 255 -> PixelFormat.TRANSLUCENT
bitmap?.hasAlpha() == true -> PixelFormat.TRANSLUCENT
else -> PixelFormat.OPAQUE
}
}
Binary file removed android/app/src/main/res/drawable-hdpi/splash.png
Binary file not shown.
Binary file removed android/app/src/main/res/drawable-ldpi/splash.png
Binary file not shown.
Binary file removed android/app/src/main/res/drawable-mdpi/splash.png
Binary file not shown.
Binary file removed android/app/src/main/res/drawable-xhdpi/splash.png
Binary file not shown.
Binary file removed android/app/src/main/res/drawable-xxhdpi/splash.png
Binary file not shown.
Binary file not shown.
18 changes: 18 additions & 0 deletions android/app/src/main/res/drawable/bootsplash.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Splash window background: the artwork is scaled uniformly to cover the window and
centered (center-crop), so the logo baked into it keeps its aspect ratio on every
screen size and orientation. The artwork's grain is ~4% non-opaque, so the solid colour
underneath shows through it (and covers the window if the bitmap fails to decode). -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item>
<shape android:shape="rectangle">
<solid android:color="#161F30" />
</shape>
</item>
<item>
<drawable
class="com.mendix.developerapp.splashscreen.CenterCropDrawable"
android:src="@drawable/splash_screen" />
</item>
</layer-list>
6 changes: 0 additions & 6 deletions android/app/src/main/res/drawable/splash_screen.xml

This file was deleted.

2 changes: 1 addition & 1 deletion android/app/src/production/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@

<!-- BootSplash theme. -->
<style name="BootTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowBackground">@drawable/bootsplash</item>
</style>
</resources>