I'm targeting API level 14+, so I've used Activity.recreate() for theme switching in my app. It worked out nice, except a black screen will flash for about 0.5s.
I used to think it is impossible to provide a better experience here, until I saw a material designed app which successfully switched its theme with a crossfade. But unluckily I failed to recall its name since I uninstalled it from my phone some time ago.
I've tried Activity.overridePendingTransition(), it did not work, and I believe the reason is that the recreate() call is much like a configuration change so the mechanism is different from finishing and launching a brand new activity.
(And while trying to find that app I came across another magic theme switching app, even without calling recreate(). Hum... Anybody know how the trick is done?)
Theme switching on the fly GIF
Who said themes were immutable? Changing the primary and accent colors on…
EDIT:
I found that the GIF above is kind of a distraction from the original question, so I turned it into a link.
My original question is that, is there any method to change (switch) theme with an appropriate transition?
Changing all the things on screen by Brute force is not switching the app's theme; it just appear to be though, but it can lead to many problems.
Sad to find out the above GIF may only be a hacky brute force attack, but still thanks to #Emanuel Moecklin for pointing this out.
But I still hope a "(truly) switching theme with transition" solution can come up, or someone tell me that Activity.recreate() cannot be animated and no other ways can switch themes better.
After all these years I've learned an easy way.
Instead of Activity.recreate(), use the follwing code fragment:
finish();
startActivity(new Intent(this, getClass()));
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
And it will give you a nice animation between themes.
Bonus: You can manually save & restore instance state to preserve UI state, and ignore user input during restarting by overriding input related methods (dispatch*Event()) on Activity.
Check out this answer to a similar question:
https://stackoverflow.com/a/26511725/534471
What the app you mention in your question does, isn't changing the theme but changing the color of the status bar, the action bar and the navigation bar:
Status Bar:
getWindow().setStatusBarColor(colorStatus);
Action Bar:
ActionBar actionBar = getSupportActionBar();
actionBar.setBackgroundDrawable( new ColorDrawable( colorAction ) );
Navigation Bar:
getWindow().setNavigationBarColor(colorStatus);
My guess is that the accent color is changed by just setting the background color of the two visible elements (the floating action button and the tab navigation). Tab navigation colors can be changed like this:
ActionBar actionBar = getSupportActionBar();
actionBar.setStackedBackgroundDrawable( new ColorDrawable( accentColor ) );
Related
I'm having a "this can't be right moment" trying to learn Android app development. I want to add some buttons to the top bar (app bar, toolbar, action bar, etc) of my Activity. Apparently this thing is called the app bar. But when I read the docs, I feel like I'm taking crazy pills:
This class describes how to use the v7 appcompat support library's Toolbar widget as an app bar.
Why do I have to use something called "appcompat" to add a toolbar? I don't care about backwards compatibility right now, I'm just coding an app to learn. Normally backwards compatibility shims/layers are an optional thing. I just want to do this in the most straightforward way at the moment - it'll be easier for me to learn that way.
There are other ways to implement an app bar—for example, some themes set up an ActionBar as an app bar by default—but using the appcompat Toolbar makes it easy to set up an app bar that works on the widest range of devices, and also gives you room to customize your app bar later on as your app develops.
Again, this sounds like the docs are saying that the method they advocate is not the simplest and most basic way, and that there's another. Then one of the very first steps in the tutorial is:
In the app manifest, set the element to use one of appcompat's NoActionBar themes. Using one of these themes prevents the app from using the native ActionBar class to provide the app bar.
Huh? So the first step to getting a toolbar is to turn off the toolbar? At this point I feel like I can hear clown horns going off. Am I being pranked? I don't think Google realize how bonkers this all sounds to a complete beginner.
Is there a way to add buttons/actions to the default Material UI ActionBar in an Activity, without going through the appcompat package?
The inbox app features a navigation drawer. Upon clicking on any navigation drawer item a fragment is loaded (most probably) and during this transaction the app theme changes. Changing app theme requires setTheme() method to be called before setContentView(..) in the onCreate() method of the activity. The super fluid UI indicate the use of fragments so how is this achieved without recreating parent activity (otherwise there would have been a lag for sure).
The snooze fragment hase oragne like theme
The inbox fragment has blue like them
You can actually change the theme's style, but only before calling setContentView(#ResId int) method. Something like this perhaps?
getTheme().applyStyle(isDashUser ? R.style.redStatusBar : R.style.blackStatusBar, true);
setContentView(R.layout.my_activity);
If you look closely when changing the page there's a slight graduation between the two colours. This probably suggests they have a system separate from theming to re-colour all the UI elements.
One my apps has a very similar colour change feature, and I just have methods set up to manually re-apply the relevant colours to each UI element. Of course Google probably have some super slick way of doing it that they'll never share with anyone.
When opening my app for the first time, i can see a white screen for two or three seconds. After that, the first activity is shown.
¿How to avoid this annoying white screen? I'm pretty sure it's caused by the theme Theme.AppCompat.Light.DarkActionBar which I'm using.
I'm using this new theme because I'm using a NavigationView with a PagerTitleStrip and in the documentation of google they where using this theme to develop this kind of views.
How can i avoid that annoying white screen? If that screen can be for example black, it is munch better and munch less annoying. Can its color be changed? Has this theme a black version but without losing compatibility with a NavigationView with a PagerTitleStrip?
Thank you.
On your xml that you are using for your splashscreen add
android:opacity="opaque"
As cricket_007 tell in the comments, it is possible to get black color theme instead of Light simply using "Theme.AppCompat"
Also as CommonsWare tell us, too in the comments, it is a good practice to search if you are doing too much work in the main thread and use threads to get a fast ui load.
Thank you guys
I'm new to all of this so please bear with me.
A while back I created my first activity and have been working on it for a while now. Since then, I've created a theme and applied it to my application. The theme doesn't show up on my original activity.. it still looks default:
I just now created a new activity, and it seems to have picked up on my theme design and looks totally different. The font size is different in the action bar, and all the colors are different.
Why is this happening? The theme works on both when I actually run the app in the emulator.. but they look different in eclipse. How can I get my old activity to pick up on the theme?
Thanks!
There is an option on the layout design which you can choose which theme you want to be used on preview.
I'm developing an Android application which uses ActionBarSherlock (ABS) and needs to work in API >=8. The problem is that some transitions between activities aren't smooth enough.
For example: I have two activities, (A) one which is always fullscreen and (B) another one which isn't fullscreen (status bar and action bar are shown). The transition needed is always from A to B. When it occurs and B activity is loaded, all the content (included ABS) is shown as if the activity was fullscreen and then resizes when the status bar is loaded again.
In some devices this effect is insignificant but in other ones it becomes really annoying and even causes that the user touches the wrong section of the view.
Fullscreen declaration is made via Manifest activity's "theme" property (anything by code). For example:
<activity
android:name = "...."
android:screenOrientation = "portrait"
android:theme = "#android:style/Theme.NoTitleBar.Fullscreen">
</activity>
Searching on the Internet for some solution, I've found two main approaches:
1) To use the Android appcompat library and enabling action bar overlay as mentioned here: https://developer.android.com/training/basics/actionbar/overlaying.html#EnableOverlay.
The problem with this is that the app also uses the HoloEverywhere library and many errors appeared when using HoloEverywhere + appcompat. All this errors were related to duplicated XML elements. I've also checked android-support-v4 library in all projects to avoid errors.
2) Using WindowManager flags and applying top padding to the view: http://nubinewsblog.blogspot.com.es/2009/11/smooth-full-screen-transition.html.
With this approach the transition is perfect. The biggest problem - and the reason I need to ask this - is that I'm not able to apply a top margin to ABS and the status bar is shown over the action bar. I can move down all elements except ABS. I suppose it occurs because ABS uses many fixed dimensions and attributes.
I prefer to use the second way (2) but I can try everything needed to make the transition smoother. Any further implementation details needed can be asked and I'll try to answer ASAP. I'd be very grateful for any info or help provided :-)
Really thanks to all for your time.
PS: I'm currently using and Android 2.3.6 device for testing.
PS: when I say fullscreen I always refer to fullscreen + no status bar + no action bar.
I've solved my problem doing the following:
1.- I have to optimize all the screens where the AB was shown. In some cases I used ListViews which weren't correctly implemented and that caused a noticeable load time in the activity.
2.- I have shown the status bar BEFORE starting the new activity. I mean: I've shown the status bar in the fullscreen activity just before starting the non-fullscreen one. With that I achieved that the layout of the second activity (non-fullscreen) was never resized.
With this two little changes now the AB transition is much more smoother.
I close this question but, if someone has any doubt, I will be pleased to answer it. Last but not least, ¡thanks to all who tried to help with this problem!
the best solution is to clear full screen flags on onPause method of first (full screen) activity
#Override
protected void onPause(){
super.onPause();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}