I'm creating a custom view in android that needs to get the fontFamily when its overridden in a custom app theme like so:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">#font/raleway_semibold</item>
</style>
I want to have a way of getting this value, whilst also defaulting to the system default fontFamily if this custom override wasn't there.
I know I could provide a styleable attribute on the custom view but i wanna make use of the app theme so it stays consistent throughout the app.
Hope that makes sense
Thanks!
I managed to solve this by doing this:
final TypedArray typedArray = theme.obtainStyledAttributes(new int[] {
R.attr.fontFamily
});
Typeface font = typedArray.getFont(0);
if(font == null)
font = Typeface.DEFAULT;
and changing the xml value slightly to 'fontFamily':
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="fontFamily">#font/raleway_semibold</item>
</style>
So I have a problem with my app's status bar not changing its icons to dark when I'm forcing my app into a Light Theme.
I've discovered the root of the issue, which is that the icons in the status bar don't want to change dark when I have the SYSTEM_UI flags LAYOUT_STABLE and LAYOUT_FULLSCREEN applied to the Activity. When I remove these 2 flags, the icons in the status bar are properly dark.
But my problem with this "solution" above is that I am using the 2 SYSTEM_UI flags in order to have my Activity's content scroll below the status bar, which I have made semi-transparent. I have not figured out another way to make my status bar accept transparency and have content scroll below it other than using the 2 SYSTEM_UI flags I currently have for this Activity, which are, again SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN.
Does anyone have an idea as to how I can get around this issue?
Perhaps someone can show me a reliable way to have my status bar accept transparency and have content seen scrolling below it without having to use the SYSTEM_UI flags? That would likely solve my problem, I think...
The only code I could think would be relevant to share is this:
In my MainActivity.java, I have this set:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);`
And in my styles.xml, I have this theme set for the Light Theme:
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/pure_white_transparent</item>
<item name="colorPrimaryDark">#color/pure_white_transparent</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/pure_white_transparent</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:navigationBarColor">#color/pure_white</item>
<item name="android:windowLightNavigationBar">true</item>
</style>
Any ideas?
Okay, so I figured it out on my own. It looks like I probably was needing to set the SYSTEM_UI flags before calling setContentView. Though, it could be a combination of these changes that made it work for me - I'm not entirely sure.
What I changed was using these flags before calling setContentView:
if (lightMode) {
setTheme(R.style.AppTheme_Light_NoActionBar);
getWindow().getDecorView().setSystemUiVisibility
(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
lightMode above is a SharedPreference boolean I have set if the user has selected the Change theme button in my app's toolbar (works the same way for the dark mode/theme).
And finally, for my MainActivity's theme, I have this style set in my styles.xml (for API 27 and above - looks a bit different for lower Android APIs' styles.xml):
<!-- Toolbar/NoActionBar variant of default Light Theme -->
<style name="AppTheme_Light_NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/pure_white_transparent</item>
<item name="colorPrimaryDark">#color/pure_white_transparent</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#color/pure_white_transparent</item>
<item name="android:navigationBarColor">#color/pure_white_transparent</item>
</style>
Because it would appear to me that setting the SYSTEM_UI flags to LAYOUT_FULLSCREEN and LAYOUT_STABLE makes the toolbar sit underneath the statusbar, I've set some appropriate padding by way of:
int statusBarHeight = getStatusBarHeight(this);
Where getStatusBarHeight is a method used to account for the possibly varying sizes of statusbars on different Android devices (such as the Pixel 3XL's larger statusbar).
I got this working method from elsewhere on StackOverflow, but forgot where, so if anyone knows, feel free to link it - method below:
// Gets the StatusBar's height of the particular display.
public static int getStatusBarHeight(final Context context) {
final Resources resources = context.getResources();
final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (int) Math.ceil(24 * resources.getDisplayMetrics().density);
} else {
return (int) Math.ceil(25 * resources.getDisplayMetrics().density);
}
}
}
I've then taken the value of int statusBarHeight and used it as the top margin for my toolbar programatically:
// Setup the values for the toolbar's layout parameters.
CoordinatorLayout.LayoutParams toolbarParams = new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.MATCH_PARENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT
);
toolbarParams.setMargins(0, statusBarHeight, 0, 0);
// Find, Assign, and Setup the Toolbar to take place of the Actionbar.
// Then inflate the proper menu to be used on-top of it, and set its layout parameters
// which have been set in the code above.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_main);
getSupportActionBar().setDisplayShowTitleEnabled(true);
toolbar.setLayoutParams(toolbarParams);
Finally, I've made sure my app's RecyclerView is properly sitting below both the statusbar and the toolbar, which I have accomplished by setting the appropriate padding to it, also programatically:
// Get and set the values for the OffsetPadding for the RecyclerView to int.
int itemOffsetPaddingSide = (int) getResources().getDimension(R.dimen.item_offset);
int actionBarSize = (int) getResources().getDimension(R.dimen.actionbarSizeWithExtraPadding);
int itemOffsetPaddingTop = actionBarSize + statusBarHeight;
// Set all the OffsetPadding values to the RecyclerView programmatically, so that
// all the UI elements are padding properly, taking into account the devices screen
// density/size/resolution!
mRecyclerView.setPadding(itemOffsetPaddingSide, itemOffsetPaddingTop, itemOffsetPaddingSide, itemOffsetPaddingSide);
The value of int itemOffsetPaddingSide is 4dp, for int actionBarSize it's 60dp and for int itemOffsetPaddingTop, by combining both actionBarSize and statusBarHeight, we get 56dp plus however tall the statusBar for the particular device is (because of the values retrieved and assigned to statusBarHeight in the code further up the post).
This all allows for my RecyclerView's content to sit comfortably below the statusbar and toolbar and also to be visible while scrolling underneath both of them, due to both bars having 90% opacity.
I've been studying Java programming and Android app development for nearly 2 years now independently, and while I'm proud of where I've come in this time, I'm also not sure this is the most elegant way to accomplish this effect in my app. But either way, it works, and if you find it useful for your app too, let me know!
I learned how to color an Android activity status bar thanks to this solution: How to change status bar color to match app in Lollipop? [Android]
However it doesn't say how to make this for the entire app (all activities).
i don't want to duplicate those 4 lines of code into each Activity, and if I make a Java class for Utils, I can't reach my colors by using R.color.blue or getResources(....).
Is there a way to do this through the Manifest, perhaps? Or any other way?
Thank you!
You should create your own style in values/styles.xml. Then make your own theme with such parameters. Loock code below
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/color_primary</item>
<item name="colorPrimaryDark">#color/color_secondary</item>
<item name="colorAccent">#color/color_accent</item>
<item name="android:statusBarColor">#color/color_primary</item><!--this is what you need-->
</style>
Or just use method (for Lolipop):
public abstract void setStatusBarColor (int color)
I want to set different colors to text of MenuItem that are in action bar and in different configurations - landscape and portrait.
I figured one way to that was have different colors set in Color and Color-land.I've made a custom theme in styles as follows
<style name="MyAppTheme" parent="#android:style/Theme.DeviceDefault.Light">
<item name="android:actionMenuTextAppearance">#style/MyActionBar.MenuTextStyle</item>
</style>
<style name="MyActionBar.MenuTextStyle"
parent="android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Menu">
<item name="android:textColor" >#color/button_color</item>
</style>
and then set the color black in color resource and white in color-land resource.
This would work as the activity will be created when the configuration changes.
However in my activity when the activity is created first an AlertDialog appears which leads to a REST api call and a ProgressDialog follows while the data is fetched from the server.
The problem lies in here when i would change the configuration the activity will be recreated and i will get the AlertDialog again.
if i set in the manifest <activity android:configChanges="orientation" /> the color of the menu item won't change because the activity is never created again but it will avoid the AlertDialog and would maintain the activity state.
I am looking for a way to change the MenuItem Text color in the onConfigurationChanged event. is there some way to do it?
I'm developing an android application and I cannot remove the title bar permanently. A solution posted here: How to hide the title bar for an Activity in XML with existing custom theme
(the 600 upvoted one, the others didn't work as described below) worked in general, but it maintained the title bar for a brief millisecond when initially launching the app.
I've tried various solutions throughout stackoverflow and other sites modifying the android theme in the manifest xml and style file(s). However, all of these solutions have all crashed the application before it began. The message in LogCat being that I must use an AppCompact theme. My main activity extends the ActionBarActivity class, and I have tried switching it to just Activity while also removing the :
if (savedInstanceState == null) {getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
that is generated. However, when I do so, all of the views on the main activity disappear and it becomes completely white with nothing else. Is there a way to completely remove the actionbar while extending ActionBarActivity? If not, how can I switch to extending Activity or some other class while maintaining no other errors?
on styles.xml you should make that
parent="Theme.AppCompat.NoActionBar"
Do you use custom view for the ActionBar? if yes, then maybe you'll find the approach I use acceptable. I just set text color for Title and Subtitle the same as background color in my app's theme.
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">#style/ActionBar</item>
</style>
<style name="ActionBar" parent="#android:style/Widget.ActionBar">
<item name="android:titleTextStyle">#style/ActionBar.Title</item>
<item name="android:subtitleTextStyle">#style/ActionBar.Subtitle</item>
<item name="android:background">#color/my_color</item>
<item name="android:backgroundStacked">#color/my_color</item>
<item name="android:backgroundSplit">#color/my_color</item>
</style>
<style name="ActionBar.Title">
<item name="android:textColor">#color/my_color</item>
</style>
<style name="ActionBar.Subtitle">
<item name="android:textColor">#color/my_color</item>
</style>
Then I inflate and apply custom ActionBar view in onCreate and set custom title