Reopen Activity with Fade In and Fade Out Animation in Android - android

WHAT I HAVE
I have an app with dynamic theming support. Everything works very well, but now while changing the themes I want to give it a fade-in and fade-out effect to make the theme changing transition look seamless.
WHAT I HAV TRIED
1) I have tried to recreate() the activity, but that doesn't apply any animations.
2) I have added a window animations, like this,
<style name="WindowFadeTransition">
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#android:anim/fade_in</item>
<item name="android:windowExitAnimation">#android:anim/fade_out</item>
</style>
And I have applied the style in my activity.
I re-open the activity using,
Intent intent = new Intent(getActivity(), SettingsThemeActivity.class);
getActivity().startActivity(intent);
getActivity().finish();
The animation works really well, but there is a problem.
THE BUG
As I have applied the window animation to the activity itself, whenever I open and close the activity, the animation triggers, which is not what I want. I want the animation to work only when I am changing theme and calling the above lines of code to re-open the activity.
I know it's kind of tricky. How to fix this issue? Any ideas?

Try this After startActivity(); call overridePendingTransition(R.anim.fade_in,R.anim.fade_out);

Related

Activity Dialog with black screen around

I have a problem with closing my Activity. I'm want to start activity by alarm. I've done that alarm start my activity, but I want to make it a dialog, so I set theme of that activity to android:Theme.Holo.Dialog.NoActionBar but I looks like this:
http://i.stack.imgur.com/rlfx1.png
I've also tried adding:
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Translucent</item>
<item name="android:windowBackground">#android:color/transparent</item>
But I makes transparent not elements that I want to, it looks like that
http://i.stack.imgur.com/BfvDL.png
Is there way to fix this, or do you have any diferent ideas to make this heppen.
Thanks

Android activity transition animation inconsistent

In my one activity page, there are many item.
One of items, use startActivity() go to an android system settings activity,
And its activity transition animation is slide_out_left.
The other items use startActivity() go to my own activity.
and activity transition animation is fade_out(defined in my style.xml).
I think that is a reason, but I don't know why?
Why my style.xml changed all activity transition animation except one.
or its there something I didn't notice?
And how can I consistent all activity transition animation in XML file?
(I know overridePendingTransition() can change the animation, but I want to modify in .xml file, not in java code, to stay my java code easy readable in the future.)
Please have a look at this answer and see whether it solves your issue or not: Start Activity with an animation
In short:
<style name="AppTheme">
<item name="android:windowAnimationStyle">#style/MyAnimation</item>
</style>
<style name="MyAnimation" parent="android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">#anim/open_enter</item>
<item name="android:activityOpenExitAnimation">#anim/open_exit</item>
<item name="android:activityCloseEnterAnimation">#anim/close_enter</item>
<item name="android:activityCloseExitAnimation">#anim/close_exit</item>
</style>
If you think this answers your question, please go to that original link that put in the answer and give the original author credit :)

How to switch themes (night mode) without restarting the activity?

I have made a few apps that support multiple themes, but I always had to restart the app when user switches theme, because setTheme() needs to be called before setContentView().
I was okay with it, until I discovered this app. It can seamlessly switch between two themes, and with transitions/animations too!
Please give me some hints on how this was implemented (and animations too). Thanks!
#Alexander Hanssen's answer basically has answered this...
Don't know why it was not accepted... Maybe because of the finish()/startActivity().
I voted for it and I tried to comment but cannot...
Anyway, I would do exactly what he described in terms of styles.
<style name="AppThemeLight" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#android:anim/fade_in</item>
<item name="android:windowExitAnimation">#android:anim/fade_out</item>
</style>
But instead of finish/start with new intent:
Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();
I would do:
#Override
protected void onCreate(Bundle savedInstanceState) {
// MUST do this before super call or setContentView(...)
// pick which theme DAY or NIGHT from settings
setTheme(someSettings.get(PREFFERED_THEME) ? R.style.AppThemeLight : R.style.AppThemeDark);
super.onCreate(savedInstanceState);
}
// Somewhere in your activity where the button switches the theme
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// decide which theme to use DAY or NIGHT and save it
someSettings.save(PREFFERED_THEME, isDay());
Activity.this.recreate();
}
});
The effect is as shown in the video...
The transition/animation makes the theme change seamless when you restart the activity, and this can be done by adding the items "android:windowanimationStyle" to your themes, and then referencing a style where you specifiy how the Activity should animate when it enters and exits.
Note that this makes the animation apply on all activities with that theme.
<style name="AppThemeLight" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
</style>
<!-- This will set the fade in animation on all your activities by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#android:anim/fade_in</item>
<item name="android:windowExitAnimation">#android:anim/fade_out</item>
</style>
Then, when you want to change theme you could do this when clicking a button:
AppSettings settings = AppSettings.getInstance(this);
settings.set(AppSettings.Key.USE_DARK_THEME,
!settings.getBoolean(AppSettings.Key.USE_DARK_THEME));
Intent intent = new Intent(this, <yourclass>.class);
startActivity(intent);
finish();
Then in your onCreate method, use the setTheme() to apply the theme that is currently set in AppSettings like this:
AppSettings settings = AppSettings.getInstance(this);
setTheme(settings.getBoolean(AppSettings.Key.USE_DARK_THEME) ? R.style.AppThemeDark : R.style.AppThemeLight);
super.onCreate(savedInstanceState);
setContentView(<yourlayouthere>);
Check out this gist for reference: https://gist.github.com/alphamu/f2469c28e17b24114fe5
for those who are trying to find solution for android version 10 or updated.
to set dark/light mode use this:
AppCompatDelegate.setDefaultNightMode(state) //state can be AppCompatDelegate.MODE_NIGHT_YES or AppCompatDelegate.MODE_NIGHT_NO
it will change the display of your app but with a flicker
to avoid the activity recreation flicker (for smooth transition), in your activity add the below method
#Override
public void recreate() {
finish();
overridePendingTransition(R.anim.anime_fade_in,
R.anim.anime_fade_out);
startActivity(getIntent());
overridePendingTransition(R.anim.anime_fade_in,
R.anim.anime_fade_out);
}
setTheme() before super.onCreate(savedInstanceState) in GKA answer is perfect approach and work well, thanks to GKA.
but it creates new instances for all resources again, including activities, fragments, and recycler views. I think it may be heavy work and cause to loss of some saved data like local variables.
accourding to google document: https://developer.android.com/reference/android/app/Activity#recreate()
Cause this Activity to be recreated with a new instance. This results
in essentially the same flow as when the Activity is created due to a
configuration change -- the current instance will go through its
lifecycle to onDestroy() and a new instance then created after it.
there is another approach that you can change the theme programmatically with code (Java or Kotlin), in this approach you don't need to recreate all resources, and also you can use custom animation like ripple.
check my GitHub library:
https://github.com/imandolatkia/Android-Animated-Theme-Manager
in this library, you can create your custom themes and change them dynamically with ripple animation without recreating any resources.
Simply efficient one liner in fragment:
requireActivity().recreate();
For activity:
recreate();
There isn't anything preventing you from calling setTheme() and then setContentView() again. You'll just need to restructure your app a bit so that, if you change the theme, you need to reinitialize any member variables you might have that are holding references to View objects.

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

Categories

Resources