How to remove the delay when opening an Activity with a DrawerLayout? - android

I have an activity with a DrawerLayout but whenever it opens there is a delay like a split-second where the screen is white then my screen is drawn.
This happens after the Transition finishes. So it sort of looks like the screen animation transition is jumping.
I tried putting this on my OnCreate after binding the views with ButterKnife but it did nothing.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
postponeEnterTransition();
drawerLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean onPreDraw() {
drawerLayout.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
Yes I am optimizing it for Lollipop, and for pre-Lollipop devices I am jsut using overridePendingTransitionsand it works fine. My problem is only on Lollipop devices.
Btw, my Enter and Exit transitions are both fade_in_outdefined in xml and specified in styles
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorAccent">#color/pink</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowContentTransitions">true</item>
<!-- specify enter and exit transitions -->
<!-- options are: explode, slide, fade -->
<item name="android:windowEnterTransition">#transition/fade_in_out_transition</item>
<item name="android:windowExitTransition">#transition/fade_in_out_transition</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">#transition/change_clip_bounds</item>
<item name="android:windowSharedElementExitTransition">#transition/change_clip_bounds</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden|adjustResize</item>
</style>

I finally found a solution to this. I don't know why or how it worked out but I just know that it removed the delay in the animations. I added a handler in the OnCreate of the activity that would run the other statements for setting up, i.e. adding the initial fragment into view, after 300ms
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
switchFragment();
}
}, 300);

Maybe its because lollipop has default layoutTransition on UI elements, have you tried?
drawerLayout.setLayoutTransition(null)

I would change your exit transition:
item name="android:windowExitTransition">#transition/fade_in_out_transition</item>
item
To window return:
name="android:windowReturnTransition">#transition/fade_in_out_transition</item>
When you are using window exit, the visibility of the window is changed to invisible briefly before your next transition starts.
Sets the Transition that will be used to move Views out of the scene
when the fragment is removed, hidden, or detached when not popping
the back stack. The exiting Views will be those that are regular
Views or ViewGroups that have isTransitionGroup() return true.
Typical Transitions will extend Visibility as exiting is governed by
changing visibility from VISIBLE to INVISIBLE. If transition is null,
the views will remain unaffected.
setExitTransition
Returning the transition handles the window closing, as opposed to exiting and does not affect the window visibility.
Reference to a Transition XML resource defining the desired
Transition used to move Views out of the scene when the Window is
preparing to close. Corresponds to
setReturnTransition(android.transition.Transition).
android:windowReturnTransition
I would also recommend using reenter to manage back presses.
Reference to a Transition XML resource defining the desired Transition
used to move Views in to the scene when returning from a
previously-started Activity. Corresponds to
setReenterTransition(android.transition.Transition).
android:windowReenterTransition
Understanding exit/reenter shared element transitions
You can also set a bool value that will allow the transitions to overlap, however the overlap may be too long
for what you want.
setAllowEnterTransitionOverlap(boolean)
Also I'd upgrade the lollipop to 5.0.1
There are bugs in 5.0.0 that have been fixed in 5.0.1
This blog by Linton Ye covers in detail the issues surrounding Lollipop transitions and bugs.
My Journey to Lollipop Transitions: part 1

Related

StatusBar flicker during activity transition android nouget

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?

Shared element transition with Dialog Activity

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.

Blinking screen on image transition between activities

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

PopupWindow update() animation

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.

How to remove white screen before loading of first activity in android?

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>

Categories

Resources