Splash screen dispose/remove after loaded - xamarin

I am launching a splash screen in my xamarin android application and what happens is the splash screen keeps appearing
on other pages as background.
Whatever I do it's there.
I have tried to "Finish" the activity,NoHistory=true but nothing ,keeps showing on other pages in the background.
Taken from
https://alexdunn.org/2017/02/07/creating-a-splash-page-for-xamarin-forms-android/
Any ideas why?
[Activity(Label = "MyApp",
Theme = "#style/MyTheme.Splash",
Icon = "#drawable/icon",
MainLauncher = true,
NoHistory = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.tabs;
ToolbarResource = Resource.Layout.toolbar;
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App(new AndroidInitializer()));
}
}
[Activity(
Theme = "#style/MyTheme.Splash",
MainLauncher = true,
NoHistory = true,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashActivity : AppCompatActivity
{
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
}
protected override void OnResume()
{
base.OnResume();
var startUp = new Task(() =>
{
var intent = new Intent(this, typeof(MainActivity));
StartActivity(intent);
});
startUp.ContinueWith(t => Finish());
startUp.Start();
}
<style name="MyTheme.Splash" parent ="Theme.AppCompat.Light">
<item name="android:windowBackground">#drawable/splash_screen</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

This is caused by Theme = "#style/MyTheme.Splash". Both activities use the same theme.
Create a different theme for the other activities.
<style name="MyTheme.Main" parent ="Theme.AppCompat.Light">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
Change the theme in Activity:
[Activity(
Theme = "#style/MyTheme.Main",
MainLauncher = true,
NoHistory = true,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashActivity : AppCompatActivity
{
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
}
}

Another solution instead of creating a new theme is to set a background color in the layout file for the parent view in every activity that isn't the SplashScreen activity.

Your problem is mainly caused by two activities using the same theme.
In the "MainActivity" change the theme from "#style/MyTheme.Splash" to "#style/MainTheme", this will make the main activity use the default theme.

Related

Xamarin Forms Android 12 SplashScreen backward compability

Im using xamarin and recently update my targetSdkVersion to 31 (Android 12) and wanted to use a SplashScreen, managed to get it working on a device with android 12, but for lower versions it doesnt show anything just a blank screen
styles.xml
<resources>
<style name="MainTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="snackbarStyle">#style/MySnackbar</item>
<item name="colorPrimary">#242424</item>
// Set the splash screen background, and icon background.
<item name="android:windowSplashScreenBackground">#242424</item>
<item name="android:windowSplashScreenIconBackgroundColor">#242424</item>
// Use windowSplashScreenAnimatedIcon to add either a drawable or an
// animated drawable. One of these is required.
// Use windowSplashScreenBrandingImage to add a drawable displayed at the bottom
// of the splash screen.
<item name="android:windowSplashScreenAnimatedIcon">#drawable/icone2</item>
<item name="android:windowSplashScreenBrandingImage">#drawable/logo</item>
</style>
<style name="MySnackbar" parent="Widget.MaterialComponents.Snackbar">
<item name="android:layout_margin">6dp</item>
</style>
</resources>
MainActivity
namespace App.Droid
{
[Activity(Label = "App", Icon = "#drawable/icone", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
UserDialogs.Init(this);
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
AndroidEnvironment.UnhandledExceptionRaiser += UnhandledExceptionRaiser;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
ZXing.Net.Mobile.Forms.Android.Platform.Init();
Forms.Init(this, bundle);
Popup.Init(this);
Platform.Init(this, bundle);
LoadApplication(new App());
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
if (App.Current.Resources.TryGetValue("PrimaryColor", out object objectStyle))
{
Window.SetStatusBarColor(Android.Graphics.Color.ParseColor(((Color)objectStyle).ToHex()));
Window.SetNavigationBarColor(Android.Graphics.Color.ParseColor(((Color)objectStyle).ToHex()));
}
else
{
Window.SetStatusBarColor(Android.Graphics.Color.Black);
Window.SetNavigationBarColor(Android.Graphics.Color.Black);
}
}
App.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
}
}
}
PrintAndroidOld
PrintAndroid12
Managed to do something, just doing an splash activity that wont show on android 12 and up
using Android.App;
using Android.Content;
using Android.OS;
using Xamarin.Forms;
namespace App.Droid
{
[Activity(Label = "App", Icon = "#drawable/icone", Theme = "#style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : Activity
{
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
Forms.Init(this, savedInstanceState);
}
protected override void OnResume()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.S)
{
base.OnResume();
StartActivity(new Intent(Android.App.Application.Context, typeof(MainActivity)));
return;
}
base.OnResume();
StartActivity(new Intent(Android.App.Application.Context, typeof(MainActivity)));
}
public override void OnBackPressed() { }
}
}

Menu is created, but disappears after navigations

I created menu in Xamarin Android application. It is showing on first page, but after PushAsync it disappears. Also after returning to first page it is not showing any more. Here is a code:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IOnMenuItemClickListener
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.InflateMenu(Resource.Menu.action_menu);
toolbar.SetOnMenuItemClickListener(this);
}
public bool OnMenuItemClick(IMenuItem item)
{
...
return true;
}
}
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
public partial class MainPage : ContentPage
{
...
private async void OnSecondPageClicked()
{
await Navigation.PushAsync(new SecondPage());
}
}
File action_menu.xml:
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/item1"
android:title="new_game"
android:showAsAction="always"/>
<item android:id="#+id/item2"
android:title="help"
android:showAsAction="always"/>
</menu>
You have a mixture of a Xamarin.Android app and a Xamarin.Forms app. This answer assumes you want a forms app. You should remove the following lines from OnCreate
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
toolbar.InflateMenu(Resource.Menu.action_menu);
toolbar.SetOnMenuItemClickListener(this);
And add these lines to the constructor of MainPage
this.ToolbarItems.Add(new ToolbarItem("New Game", "", () => { }));
this.ToolbarItems.Add(new ToolbarItem("Help", "", () => { }));
If that works you should move MainPage and App into your Cross Platform project.

Xamarin BLE scanning only sometimes

I created simple Xamarin.Forms Bluetooth low energy scanning application. As I will use Bluetooth only on Android, I implemented scanning in MainActivity.cs of Android project:
namespace BlankAppXamlXamarinForms.Droid
{
[Activity(Label = "BlankAppXamlXamarinForms", Icon = "#drawable/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
private BluetoothManager _manager;
App app;
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
app = new App();
var appContext = Application.Context;
_manager = (BluetoothManager)appContext.GetSystemService(BluetoothService);
_manager.Adapter.BluetoothLeScanner.StartScan(new MyScanCallback(app));
LoadApplication(new App());
}
}
public class MyScanCallback : ScanCallback
{
App _app;
public MyScanCallback(App app) {
_app = app;
}
public override void OnScanResult(ScanCallbackType callbackType, ScanResult result)
{
_app.newDevice(result.Device.Name + " - " + result.Device.Address);
}
}
}
The problem is that OnScanResult receives advertising packets only a moment after the application is started and when I switch the display of my phone off and then turn it on again. Meanwhile the application receives almost no advertising packets. How to receive advertising packets all the time my application is active?
You are creating two instances of App. Instead of LoadApplication(new App()); you should be passing in your field app, i.e. LoadApplication(app);
Also, instead of starting the scan in OnCreate, you might want to start the scan in OnResume and stop the scan in OnPause e.g.:
public class MainActivity : FormsAppCompatActivity
{
BluetoothManager bleManager;
App app;
ScanCallback scanCallback;
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
Forms.Init(this, bundle);
app = new App();
bleManager = (BluetoothManager)Application.Context.GetSystemService(BluetoothService);
scanCallback = new MyScanCallback(app);
LoadApplication(new App());
}
protected override void OnResume()
{
base.OnResume();
bleManager.Adapter.BluetoothLeScanner.StartScan(scanCallback);
}
protected override void OnPause()
{
base.OnPause();
bleManager.Adapter.BluetoothLeScanner.StopScan(scanCallback);
}
}

Xamarin forms splash screen issue

A black screen with app title is showing when minimizing the app while loading splash screen , also the first screen will display after some time. Here is my splash activity and main activity classes.
[Activity(Theme = "#style/Theme.Splash", Icon = "#drawable/icon", MainLauncher = true, NoHistory = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
ScreenOrientation = ScreenOrientation.Behind)]
public class SplashActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var dpWidth = Resources.DisplayMetrics.WidthPixels/Resources.DisplayMetrics.Density;
RequestedOrientation = dpWidth > 700 ? ScreenOrientation.Unspecified : ScreenOrientation.Portrait;
ThreadPool.QueueUserWorkItem(o => LoadActivity());
}
private void LoadActivity()
{
RunOnUiThread(() => StartActivity(typeof(MainActivity)));
}
public override void OnBackPressed()
{
Environment.Exit(0);
}
}
[Activity(Label = "HACCP", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
ActionBar.SetIcon(Android.Resource.Color.Transparent);
Forms.Init(this, bundle);
// some function //
LoadApplication(new App());
}
}
You tagged Xamarin.Forms so it should be as simple as..
class App : Application
{
public App()
{
MainPage = new MySplashPage();
}
}
class MySplashPage : ContentPage
{
public MySplashPage()
{
Task.Delay(3000); //show my pretty splash for 3 seconds
Application.Current.MainPage = new MyOtherSpiffyPage();
}
}
Not certain if the activity attribute ScreenOrientation = ScreenOrientation.Behind) is causing any issues, we don't use that in our apps.
Here is a "standard" splash activity we do use, letting Xamarin.Android take care of timing etc:
public class SplashActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Start main.
StartActivity(typeof(MainActivity));
}
}
You might try simplifying your app in similar fashion.

Xamarin Forms 2.0 AppCompat android keyboard mode

Xamarin I updated to version 4, Forms and 2.0 versions. On Android, I use AppCompat.
I had a problem. Previously, the Android keyboard caused resize view. Now this does not happen. The keyboard appears on the top view. And the desired Elements to be hiding.
I've tried:
[Activity(WindowSoftInputMode = SoftInput.AdjustResize, Label = "Title", Icon = "#drawable/icon", Theme = "#style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
ToolbarResource = Resource.Layout.toolbar;
TabLayoutResource = Resource.Layout.tabs;
LoadApplication(new App());
Window.DecorView.SetFitsSystemWindows(true);
}
}
Daylight AppCompat has been made on this lesson: https://blog.xamarin.com/material-design-for-your-xamarin-forms-android-apps/
Thank you.
I have solved the problem. Decompile class
"Forms AppCompatActivity" and watched how the method works OnCreate.
As a result, I turned out the following code:
[Activity(Label = "Title", Icon = "#drawable/icon", Theme = "#style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
Window.SetSoftInputMode(SoftInput.AdjustResize);
AndroidBug5497WorkaroundForXamarinAndroid.assistActivity(this);
ToolbarResource = Resource.Layout.toolbar;
TabLayoutResource = Resource.Layout.tabs;
LoadApplication(new App());
}
public class AndroidBug5497WorkaroundForXamarinAndroid
{
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
// CREDIT TO Joseph Johnson (http://stackoverflow.com/users/341631/joseph-johnson) for publishing the original Android solution on stackoverflow.com
public static void assistActivity(Activity activity)
{
new AndroidBug5497WorkaroundForXamarinAndroid(activity);
}
private Android.Views.View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private AndroidBug5497WorkaroundForXamarinAndroid(Activity activity)
{
FrameLayout content = (FrameLayout)activity.FindViewById(Android.Resource.Id.Content);
mChildOfContent = content.GetChildAt(0);
ViewTreeObserver vto = mChildOfContent.ViewTreeObserver;
vto.GlobalLayout += (object sender, EventArgs e) => {
possiblyResizeChildOfContent();
};
frameLayoutParams = (FrameLayout.LayoutParams)mChildOfContent.LayoutParameters;
}
private void possiblyResizeChildOfContent()
{
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious)
{
int usableHeightSansKeyboard = mChildOfContent.RootView.Height;
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
frameLayoutParams.Height = usableHeightSansKeyboard - heightDifference;
mChildOfContent.RequestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight()
{
Rect r = new Rect();
mChildOfContent.GetWindowVisibleDisplayFrame(r);
if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
{
return (r.Bottom - r.Top);
}
return r.Bottom;
}
}
}
It is important to add "Window.SetSoftInputMode(SoftInput.AdjustResize);" After calling base.OnCreate(bundle);

Resources