The Problem
I have an Activity called Activity A which has the following transitions defined.
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void slideAnimation(Window window) {
//runs when the activity is being entered
//runs in reverse when the activity is being destroyed
Slide slideEnter = new Slide();
slideEnter.setDuration(mShortAnimationDuration);
slideEnter.excludeTarget(android.R.id.statusBarBackground, true);
slideEnter.excludeTarget(R.id.app_bar_layout, false);
window.setEnterTransition(slideEnter);
//runs when the calling activity is exiting
// runs in reverse when the activity is reentering
Slide slideExit = new Slide();
slideExit.setDuration(mShortAnimationDuration);
slideExit.excludeTarget(android.R.id.statusBarBackground, true);
slideExit.excludeTarget(R.id.app_bar_layout, false);
window.setExitTransition(slideExit);
}
When I invoke Activity A everything works normal. The statusbar remains where it is but the appbar is animated into the screen. However when I run Activity B via A , the slideexit transition doesn't honor the statusbar. The status bar goes away however the appbar remains fixed (it is properly excluded from the animation).
What I have tried
If I comment out the code for slideexit and only keep the enter transition in A, the statusbar remains fixed during transition from A to B. This proves that the issue comes before B has been invoked. The issue is with the exittransition of A.
A's exit transition doesn't exclude the status bar and takes it off screen. B merely slides it back.
This is my styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
This is how I invoke my activity
void transitionTo(Intent i) {
ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(this), null);
getActivity(this).startActivity(i, transitionActivityOptions.toBundle());
}
I am using nouget 7.0 on an HTC 10 with the support library version 24.2.1.
I strongly believe that it is some framework issue as I clearly remember this working last year maybe 3 months ago or so.
Or am I doing something wrong?
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 implemented an image transition between two activities using the new shared elements from lollipop. It's working but I get a weird white blinking on the entire screen during the transition and I can't find how to get rid of it. Here is an example:
Here is how the second activity is launched
public static void launch(
#NonNull Activity activity, #NonNull View transitionView, Game game) {
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(
activity, transitionView, game.gameFullId);
Intent intent = new Intent(activity, ListImportationLoginActivity.class);
intent.putExtra(INTENT_EXTRA_GAME, retailer);
ActivityCompat.startActivity(activity, intent, options.toBundle());
}
Then in onCreate:
ViewCompat.setTransitionName(mLogoView, mGame.gameFullId);
And the theme file:
<resources>
<style name="Theme.MyApp.NoActionBar" parent="Theme.MyApp.NoActionBar.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">#android:transition/move</item>
<item name="android:windowSharedElementExitTransition">#android:transition/move</item>
</style>
</resources>
Thanks for your help
On the exiting activity, call
getWindow().setExitTransition(null);
On the entering activity, call
getWindow().setEnterTransition(null);
It will prevent the fade out of the exiting activity and the fade in of the entering activity, which removes the apparent blinking effect.
I solved this issue by changing background color of my default theme, hope this is still can help to someone save the time.
<item name="android:windowBackground">#color/black</item>
<item name="android:colorBackground">#color/black</item>
The "white blinking" you are seeing is the result of the two activities alpha-animating in and out during the transition: when activity A starts activity B, activity A fades out and activity B fades in.
If you want to prevent the status bar and/or navigation bar from fading during the transition (and thus reducing the "blinking" effect a bit), you can look at this post.
Make some method in helper like
public static Transition makeEnterTransition() {
Transition fade = new Fade();
fade.excludeTarget(android.R.id.navigationBarBackground, true);
fade.excludeTarget(android.R.id.statusBarBackground, true);
return fade;
}
Execute it in the activity that you are starting like this
getWindow().setEnterTransition(TransitionUtils.makeEnterTransition());
Source
https://github.com/alexjlockwood/custom-lollipop-transitions/
I have had similar blinking issues and tried many of the examples mentioned here but for me it didn't solve the issues. What did work for me was changing the window background for the second activity theme to transparent. (#Webdma used black, but in my case that made the screen flash black instead of white)
<item name="android:windowBackground">#android:color/transparent</item>
<!-- edit in your theme -->
<item name="android:windowEnterTransition">#android:transition/no_transition</item>
<item name="android:windowExitTransition">#android:transition/no_transition</item>
I had a similar problem.
I solved the blinking status bar and navigation bar issues by excluding them from the transition as per #Alex's suggestion, but the screen was still blinking when switching between the activities. When I removed the
"finish();" statement after startActivity(); the screen stopped blinking.
May it was due to the closing of calling activity.
Hope this helps someone.
Some useful answers above.
As far as I understand this is caused by activity transition overlap. To overcome this issue I have used the following values in the onCreate() methods of both activities:
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
Add this in your style.xml. This prevents the screen from Blinking
<item name="android:windowIsTranslucent">true</item>
In my situation, the second activity did not have a status bar which was defined in the activity theme with this tag.
<item name="android:windowFullscreen">true</item>
Since it was not mandatory to hide the status bar in portrait mode, I removed this tag and manually hide/show the status bar when needed and the blinking is gone.
Add these codes inside onCreate of both Activities where you doing Transition elements
Fade fade = new Fade();
View decor = getWindow().getDecorView();
fade.excludeTarget(decor.findViewById(R.id.action_bar_container),true);
fade.excludeTarget(android.R.id.statusBarBackground,true);
fade.excludeTarget(android.R.id.navigationBarBackground,true);
getWindow().setEnterTransition(fade);
getWindow().setExitTransition(fade);
This will exclude the animation from the navigation and status bar, So no more blinking
Elements fade in and out, unless you specify explicitly they are the same on both activities. That includes status and navigation bar.
In your particular case, I would add the toolbar and these two views to the shared elements list:
List<Pair> viewPairs = new ArrayList<>();
viewPairs.add(Pair.create(findViewById(android.R.id.statusBarBackground), Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
viewPairs.add(Pair.create(findViewById(android.R.id.navigationBarBackground), Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
// Add your views...
Pair[] array = new Pair[viewPairs.size()];
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), viewPairs.toArray(array)).toBundle();
// ...
ActivityCompat.startActivity(activity, intent, options.toBundle());
In Java, add the below line in the parent activity after ActivityCompat.startActivity(activity, intent, options.toBundle());
getWindow().setExitTransition(null);
and add the below line in onCreate method of child activity
getWindow().setEnterTransition(null);
In Kotlin, add the below line in the parent activity
window.setExitTransition = null
and add the below line in onCreate method of child activity
window.setEnterTransition = null
Is there a way to animate PopupWindow when issuing update() method? I'm changing my popup's position there, so it would be nice if I could smoothly slide the popup to its destination instead of just "jumping". I know I can easily animate the PopupWindow's entering and exiting via adding these items to its style:
<style name="MyPopup">
<item name="#android:windowEnterAnimation">#anim/slide_in_right</item>
<item name="#android:windowExitAnimation">#anim/slide_out_to_right</item>
</style>
But I'm interested in its position updating animation.
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>