I have a requirement that asks to call an API from onResume of Activity-A and its response is used to block users from using the app if required by showing an Activity-B on top of Activity-A.
Another requirement was to have a few messages in the middle of Activity-B's UI and have the rest of the screen of Activity-B transparent. These messages show the user why they were blocked and redirect them to a URL to get themselves unblocked.
When the user returns from the redirected URL, the same API is called from Activity-B's onResume to check the current status.
Now the problem is, whenever the app is brought back from the background to the foreground when Activity-B is showing, onResume of Activity-A is also called which causes a double API call.
I've used the following theme style to make my Activity-B transparent:
<style name="Theme.AppCompat.Transparent.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
and then setting this theme in the manifest of Activity-B
in Activity-B
public void onPause(){
finish();
super.onPause();
}
This will finish Activity-B and the next time the user goes back to the app Activity-A will handle the api call like normal and recreate Activity-B if necessary.
Although I don't know your specific use case but you could just have a GONE overlay that is the size of the screen. When the user is not supposed to use the app the overlay is then set to VISIBLE. All actions are consumed by the overlay instead of the views beneath it effectively locking the user out and you would avoid a whole extra activity.
Related
I have two apps and when i switch from one app to another a black screen is displayed for a while and then the 2nd application starts, can we stop this from happening?
One of the simplest way is to move all the expensive (time-consuming) processing from your activity's onCreate and onStart method to onResume method. By this, your newly launched activity will be visible right after its launched but then will take a little extra to make it available for user to interact. Further, I would suggest you to move all the heavy lifting in AsyncTask for smoother UI experience.
You can also try this theme for your Activity
<resources>
<!-- Base application theme is the default theme. -->
<style name="Theme" parent="android:style/Theme" />
<style name="Theme.MyAppTheme" parent="Theme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowBackground">#drawable/my_app_background</item>
</style>
</resources>
If you switching between fragments through screen manager kind of class, which uses enums and fragment transaction to switch between fragments; make sure you put a break statement, after each enum case. This solved my issue. Hope it helps!
I put together a very simple app that uses shared element transitions when starting an activity with Dialog theme (source code on github).
I got the following result:
As you can see there are 2 problems with the transition/animation:
The animation is only visible in the area of the dialog activity so it clips and looks ugly.
There is no transition/animation when I tap outside the activity to
go back.
How can I fix these problems? Any help would be appreciated.
EDIT: After Quanturium's answer I did the following things to get it working:
Use the following theme instead of a Dialog theme:
<style name="AppTheme.Transparent" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
Use a CardView as the background for Dialog look and for rounded corners and shadows.
Call finishAfterTransition(); when user taps outside the CardView.
Now it looks like this (code), the CardView needs refining to better match the Dialog, but it's working at least.:
An activity transition works like this. When you start your second activity, it is displayed on top of your first one with a transparent background. The shared elements are positioned the same way they are on the first activity and then animated to the correct position specified on the second activity.
In your case you are using android:theme="#style/Theme.AppCompat.Dialog" which mean the size of the second activity's drawing area is smaller than the one from the first activity. This explains the clipping and the no transition when clicking outside.
What you want to do is get rid of that theme, and implement your own layout with a dark background / shadow in order to be able to execute your smooth transition.
I have a theme to show my activities as dialogs, making the window background translucent and dim, and no window title, and etc. all these items are essential for my activities appearance. The problem is when i need to show an activity that describes some aspects form another activity in the background, the result is just an activity shown at the time.
Each activity in my app has the same dialog theme, when i start an activity B from and activity A, the activity A hides and activity B shows, when the activity B should show over the activity A due to the dialog theme. This occur only in android 4.4.2.
I have tested diferents combinations of the items in the theme declaration but nothing changed, even i have tried with the intents flags when i start the activity B, making the intent FLAG_ACTIVITY_NEW_TASK, and others i believe could work but nothing again.
In one the test that i have made, if the activity B is started from an activity A, but the activity A is not a dialog activity then the activity B shows fine over the activity A. My problem is how to start dialog activities form another dialog activities without hiding.
My dialog theme decalration:
<style name="DialogStyle" parent="#android:style/Theme.DeviceDefault.Dialog.NoActionBar">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
Every activity declaration in the manifiest has this theme in the android:theme.
Thanks in advance, and sorry about my bad english.
Finally i have solved my problem...
As i said in the question above, if the activity B is started from an activity A, but the activity A is not a dialog activity, then the activity B shows fine over the activity A. So i did a search in the #android:style/Theme.*, to find one that allows me to show an activity as a dialog without be a real dialog theme, and then apply this theme to my launch activity and all the remaining activities form here will be shown fine with my DialogStyle. So this is the theme that i found:
<style name="CompatibleDialogStyle" parent="#android:style/Theme.Holo.Wallpaper.NoTitleBar">
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowAnimationStyle">#android:style/Animation.InputMethod</item>
</style>
In my application I have a main activity with a GoogleMap fragment inside it. The map often moves its camera and draws markers and polylines without a direct user interaction (i.e to follow a target).
The problem occurs when I start other translucent/transparent activities on top of that main one. I cannot use dialogs, views of fragments, unfortunately I have to use only activities. So I declared their style as:
<style name="AppTheme.Transparent" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:background">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">#null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
These activities have some views placed on top of a semi-transparent black background, so one can see the map behind them. The problem is that the map drawing is not updated at all while behind these activities, despite the fact that the code that, for example, move the camera actually runs (I can see it from logs or debugging). The map drawing is updated correctly only after (and immediately) the overlay translucent activity is closed. The strange fact is that other views placed on the main activity (for example, text views showing target coordinates) are correctly updated while behind the translucent activity, also if they are placed on top of the maps.
Is there someone who knows why is this happening, and if there is a way to force map redrawing while host activity is not in the foreground?
Whenever i launch my app, a white screen appears in the beginning with the title bar. I don't want this screen to be appear in my app. I have read previous questions, but answers are not clear to me.
I'm also using splash screen, but white screen appears before that.
I don't want to change the theme style, because it either increases the minimum sdkVersion or changes the style of edittext, buttons, checkboxes etc
Please help me to keep me out of this.
Thank you.
Preface: For questions like this you should post your starting activities xml and the onCreate() and associated methods.
When android starts your application it will typically use a black view to indicate that it is launching, this my change to white with your theme/style selected. If you are loading the view correctly then you should only see this blank (white or black) page for 50-200 ms (I can't find the google document for this right now). If you are doing a lot of work in your onCreate method then it will take longer.
Typically to make my views display faster I will simply do the majority of the linking work after it has loaded. ex:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.initial_activity_layout);
//We use a handler so that the activity starts very fast
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
delayedInit();
}
}, 100);
}
Additionally, mobile applications should typically not have a splash screen unless they take quite a while to load the contents (e.g. games, first time launch files, etc.) and should not be used just to brand your application, or display your company name.
Update (July 31, 2015)
Google apps are now moving in the direction of having splash screens (see drive, GMail, etc.)
Additionally, You shouldn't be doing any work other than de-referencing views in the onCreate() method. Any long running operations such as retrieving information from memory (database, prefs, etc.) should be done in an AsyncTaskLoader or AsyncTask.
If you are using AppCompatActivity then create below theme in style.xml :
<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
And in manifest file for SplashActivity add theme :
android:theme="#style/Theme.Transparent"
Add below line in your Theme of splash screen as you wrote you are using splash screen
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowIsTranslucent">true</item>
1- Make windowDisablePreview false in your style.xml
<item name="android:windowDisablePreview">false</item>
2- Add windowBackground in your style.xml.
<item name="android:windowBackground">#drawable/your_background</item>