CB-8753 android: Adds SplashMaintainAspectRatio preference (close #43)

This commit is contained in:
Alex Talis 2015-03-27 11:33:01 -07:00 committed by Andrew Grieve
parent 5dc26d7e65
commit dd9c88204c
2 changed files with 66 additions and 16 deletions

View File

@ -51,10 +51,15 @@ In your `config.xml`, you need to add the following preferences:
<preference name="SplashScreen" value="foo" /> <preference name="SplashScreen" value="foo" />
<preference name="SplashScreenDelay" value="10000" /> <preference name="SplashScreenDelay" value="10000" />
<preference name="SplashMaintainAspectRatio" value="true|false" />
Where foo is the name of the splashscreen file, preferably a 9 patch file. Make sure to add your splashcreen files to your res/xml directory under the appropriate folders. The second parameter represents how long the splashscreen will appear in milliseconds. It defaults to 3000 ms. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) Where foo is the name of the splashscreen file, preferably a 9 patch file. Make sure to add your splashcreen files to your res/xml directory under the appropriate folders. The second parameter represents how long the splashscreen will appear in milliseconds. It defaults to 3000 ms. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)
for more information. for more information.
"SplashMaintainAspectRatio" preference is optional. If set to true, splash screen drawable is not stretched to fit screen, but instead simply "covers" the screen, like CSS "background-size:cover". This is very useful when splash screen images cannot be distorted in any way, for example when they contain scenery or text. This setting works best with images that have large margins (safe areas) that can be safely cropped on screens with different aspect ratios.
The plugin reloads splash drawable whenever orientation changes, so you can specify different drawables for portrait and landscape orientations.
### Browser Quirks ### Browser Quirks
You can use the following preferences in your `config.xml`: You can use the following preferences in your `config.xml`:

View File

@ -22,13 +22,14 @@ package org.apache.cordova.splashscreen;
import android.app.Dialog; import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.res.Configuration;
import android.graphics.Color; import android.graphics.Color;
import android.os.Handler; import android.os.Handler;
import android.view.Display; import android.view.Display;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import org.apache.cordova.CallbackContext; import org.apache.cordova.CallbackContext;
@ -46,7 +47,17 @@ public class SplashScreen extends CordovaPlugin {
private static ProgressDialog spinnerDialog; private static ProgressDialog spinnerDialog;
private static boolean firstShow = true; private static boolean firstShow = true;
// Helper to be compile-time compatable with both Cordova 3.x and 4.x. /**
* Displays the splash drawable.
*/
private ImageView splashImageView;
/**
* Remember last device orientation to detect orientation changes.
*/
private int orientation;
// Helper to be compile-time compatible with both Cordova 3.x and 4.x.
private View getView() { private View getView() {
try { try {
return (View)webView.getClass().getMethod("getView").invoke(webView); return (View)webView.getClass().getMethod("getView").invoke(webView);
@ -74,11 +85,21 @@ public class SplashScreen extends CordovaPlugin {
} }
} }
// Save initial orientation.
orientation = cordova.getActivity().getResources().getConfiguration().orientation;
firstShow = false; firstShow = false;
loadSpinner(); loadSpinner();
showSplashScreen(true); showSplashScreen(true);
} }
/**
* Shorter way to check value of "SplashMaintainAspectRatio" preference.
*/
private boolean isMaintainAspectRatio () {
return preferences.getBoolean("SplashMaintainAspectRatio", false);
}
@Override @Override
public void onPause(boolean multitasking) { public void onPause(boolean multitasking) {
if (HAS_BUILT_IN_SPLASH_SCREEN) { if (HAS_BUILT_IN_SPLASH_SCREEN) {
@ -152,12 +173,28 @@ public class SplashScreen extends CordovaPlugin {
return null; return null;
} }
// Don't add @Override so that plugin still compiles on 3.x.x for a while
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig.orientation != orientation) {
orientation = newConfig.orientation;
// Splash drawable may change with orientation, so reload it.
if (splashImageView != null) {
int drawableId = preferences.getInteger("SplashDrawableId", 0);
if (drawableId != 0) {
splashImageView.setImageDrawable(cordova.getActivity().getResources().getDrawable(drawableId));
}
}
}
}
private void removeSplashScreen() { private void removeSplashScreen() {
cordova.getActivity().runOnUiThread(new Runnable() { cordova.getActivity().runOnUiThread(new Runnable() {
public void run() { public void run() {
if (splashDialog != null && splashDialog.isShowing()) { if (splashDialog != null && splashDialog.isShowing()) {
splashDialog.dismiss(); splashDialog.dismiss();
splashDialog = null; splashDialog = null;
splashImageView = null;
} }
} }
}); });
@ -172,7 +209,7 @@ public class SplashScreen extends CordovaPlugin {
final int drawableId = preferences.getInteger("SplashDrawableId", 0); final int drawableId = preferences.getInteger("SplashDrawableId", 0);
// If the splash dialog is showing don't try to show it again // If the splash dialog is showing don't try to show it again
if (this.splashDialog != null && splashDialog.isShowing()) { if (splashDialog != null && splashDialog.isShowing()) {
return; return;
} }
if (drawableId == 0 || (splashscreenTime <= 0 && hideAfterDelay)) { if (drawableId == 0 || (splashscreenTime <= 0 && hideAfterDelay)) {
@ -185,18 +222,26 @@ public class SplashScreen extends CordovaPlugin {
Display display = cordova.getActivity().getWindowManager().getDefaultDisplay(); Display display = cordova.getActivity().getWindowManager().getDefaultDisplay();
Context context = webView.getContext(); Context context = webView.getContext();
// Create the layout for the dialog // Use an ImageView to render the image because of its flexible scaling options.
LinearLayout root = new LinearLayout(context); splashImageView = new ImageView(context);
root.setMinimumHeight(display.getHeight()); splashImageView.setImageResource(drawableId);
root.setMinimumWidth(display.getWidth()); LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
root.setOrientation(LinearLayout.VERTICAL); splashImageView.setLayoutParams(layoutParams);
// TODO: Use the background color of the webview's parent instead of using the splashImageView.setMinimumHeight(display.getHeight());
// preference. splashImageView.setMinimumWidth(display.getWidth());
root.setBackgroundColor(preferences.getInteger("backgroundColor", Color.BLACK));
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, // TODO: Use the background color of the webView's parent instead of using the preference.
ViewGroup.LayoutParams.MATCH_PARENT, 0.0F)); splashImageView.setBackgroundColor(preferences.getInteger("backgroundColor", Color.BLACK));
root.setBackgroundResource(drawableId);
if (isMaintainAspectRatio()) {
// CENTER_CROP scale mode is equivalent to CSS "background-size:cover"
splashImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
else {
// FIT_XY scales image non-uniformly to fit into image view.
splashImageView.setScaleType(ImageView.ScaleType.FIT_XY);
}
// Create and show the dialog // Create and show the dialog
splashDialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar); splashDialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);
@ -206,7 +251,7 @@ public class SplashScreen extends CordovaPlugin {
splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowManager.LayoutParams.FLAG_FULLSCREEN);
} }
splashDialog.setContentView(root); splashDialog.setContentView(splashImageView);
splashDialog.setCancelable(false); splashDialog.setCancelable(false);
splashDialog.show(); splashDialog.show();