How to change style from code? Want to achieve skins - android

How to change a style from code?
I got a style used all across my app, for all buttons. If the user changes the skin of the app, the background of this style should change.
<style name="ActionBtn">
<item name="android:layout_width">#dimen/action_btn_width</item>
<item name="android:layout_height">#dimen/action_btn_height</item>
<item name="android:background">#drawable/btn_frame_bgstate</item>
<item name="android:padding">#dimen/action_btn_padding</item>
<item name="android:layout_margin">#dimen/action_btn_margin</item>
</style>
So far the only idea I got is to make a custom button that itself chooses its background on creation.
I have not found any good, generic way for skinning android apps yet, but if I could change styles from code, that would do the trick.
All suggestions welcome!

1) Create different themes for your skins.
2) Set those themes programatically using following code in your onCreate method.
setTheme(resid);
resid is the id of your theme.

Related

How come the color I set for cardBackgroundColor isn't exactly the one that gets shown?

Background
I'm trying to prepare dark theme for an app, and one of the requirements is to have a specific color for cards and dialogs : #ff3c454c
The problem
Whether I set it by force ( app:cardBackgroundColor="#3c454c") , by reference ( app:cardBackgroundColor="#color/...) or just in the theme - in all cases I don't get the color I've set. Instead I get the color of #525A61.
I've tested just a red color (#f00) just to be sure it affects the card, and it does, and for this color it indeed gets to be fine. But for the color I've set, it doesn't.
What I've tried
As I wrote, I tried multiple ways to set the color. In the beginning I wanted to use just the theme itself, so I've set it as such:
styles.xml
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
...
<item name="colorBackgroundFloating">#color/colorBackgroundFloating</item>
<item name="colorSurface">#color/colorBackgroundFloating</item>
</style>
res/values-night/colors.xml
<color name="colorBackgroundFloating">#ff3c454c</color>
Later I tried to use the color directly and even set it as hard coded. Still got the incorrect color when it gets shown.
Seeing this could be a bug on the library itself, I've reported about this here (include a sample project, if you wish to check it out).
I've noticed the exact same issue occurs for BottomNavigationView and probably other similar cases.
The question
Why does it occur?
Is there any workaround for this?
Something that will fix it globally for all views that use these attributes ?
What you are seeing is the elevation overlay that they introduced to make elevation more noticeable while in Dark Theme, where shadows are not so visible. You can read about it here : https://material.io/develop/android/theming/dark/ in the section "Elevation Overlays"
The simple solution if you don't want this behavior is to add this to your theme.
<item name="elevationOverlayEnabled">false</item>
And you can also adjust it to another color or even a more subtle version of the overlay by changing the alpha:
<item name="elevationOverlayColor">#80FFFFFF</item>
EDIT with more info from https://github.com/material-components/material-components-android/issues/1133
If you want to disable it for only one component or widget, you can define a style for it with a theme overlay and use it in a specific layout:
<style name="ThemeOverlay.MyApp.ElevationOverlayDisabled" parent="">
<item name="elevationOverlayEnabled">false</item>
</style>
<style name="Widget.MyApp.CardView" parent="Widget.MaterialComponents.CardView">
<item name="materialThemeOverlay">#style/ThemeOverlay.MyApp.ElevationOverlayDisabled</item>
</style>
And if you want to disable it for all cards in your app but keep it in other components you can set that style as the default style for material card views:
# Set in your app theme
<item name="materialCardViewStyle">#style/Widget.MyApp.CardView</item>

How to change Background color of menuItem in android?

I am working on programmatically add a menu-Item into menu. I want to add background color on selection to particular Item. How can I add background to menuItem?
Your answer would be appreciated.
While other answers provide change style (which will affect all menu items, and, as I understand, need is to change one menu item),I propose you to use android:actionLayout attribute to implement your custom layour for menu item.
See documentation for it (search actionLayout there, it's very simple actually).
Also I think there is a possibility to make a selector as your layout and use it.
Update. Sorry, I mislead you :(
All of this will work only if MenuItem is shown as Action (not when pressing on three dots).
Seems like guys given other answers were right - the only way to customize this is changing themes.
But please check this and this - it might help you to provide selector for your purpose.
Also you can create PopupMenu or even PopupWindow, last one is fully customizable.
The last option is to create custom Spinner, check this.
Hope something from this will help you. Thanks.
Firstly You need to create an Style for popmenu as you want refer below sample for that
<style name="MyApp.PopupMenu" parent="android:Widget.Holo.Light.ListPopupWindow">
<item name="android:textStyle">#style/commonEditTextTheme</item>
<item name="android:popupBackground">#drawable/pop_up_menu_bg_with_shadow</item>
</style>
Place of drawable you can also replace with color as you needed or make XML Drawable into your drawable folder
<style name="commonEditTextTheme" parent="#android:style/TextAppearance.Medium">
<item name="android:fontFamily">sans-serif-light</item>
</style>
this pop menu theme add in your main application or activity theme like below
<!--My Theme-->
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
......
<item name="android:popupMenuStyle">#style/MyApp.PopupMenu</item>
</style>

Change font/typeface when button is pressed

I already how to change the style of an element with selector but I found nothing about the typeface...
Is it possible to do with ? Or is there another way?
Sadly, right now it is not possible.
There is a ticket for that in the Android code repo :
https://code.google.com/p/android/issues/detail?id=8941
Your best option is to manage it yourself in ontouch listeners (and yes this is ugly) or implement these new selectors yourself.
Typeface can easily be an element of your style... If you're using default android styles, then the idea would be to extend whatever style you're implementing and just change the elements you need. like the following style element, taken from the android styles and themes documentation:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
Then apply this style in your selector, just like you already know how to do.
The other option is, of course, to do it in code, but the selector is much cleaner
When button is clicked,Use below code to change font of the text(custom typeface).
Put your font under main->assets->fonts directory.
//change font when button pressed
val typeFace = Typeface.createFromAsset(activity!!.assets,"fonts/sf_semi_bold.ttf")
buttonAbout.setTypeface(typeFace)
TextView.setTypeFace() Use Ctrl+Space to show a giant list of classes for TextView or anything in general on.

Android - Make a custom titlebar that uses the device's current titlebar theme

I'm trying to make a custom titlebar for my first Android application.
While I can find lots on the web about how to make them so you can change colours etc, I want my titlebar to look the same as the "standard" titlebar, but with a button that I can configure. This means copying the device's currently active themes to be able to style it in exactly the same way.
Not all devices simply use a gradient in the titlebar style, so adding a gradient (as suggested in other SO questions) doesn't really make sense.
Does anyone have any pointers how to read the style information?
try to extend an existing theme e.g.
create your own style which can ofcourse extend from existing from an existing theme. change the windowNoTitle to true.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="noTitleBarStyle" parent="android:Theme.Black">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#color/darkGrey</item>
<item name="android:colorForeground">#ff3333</item>
</style></resources>
or try to do it runtime as discussed here
Android - change custom title view at run time
I hope this helps.

How to set the background screen as Wallpaper all the time?

Currently, I'm using this to show my application background as phone wallpaper.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER,
WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
But for some reason when I start my application by pressing the icon. It just shows the activity screen with the icons on the home screen. I didn't use dialog but it looks like a dialog because layout is just set that way. So I just want to show the wallpaper whenever this activity is running. But it only shows the wallpaper only after the next event occurs such as switching to different activity. I already put that code on onCreate() and whenever I do setContentView()..... Is there way to do such thing or there is just no way?
For users of AppCompat, just use the following in your styles.xml, no need for code:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">#null</item>
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
After long search and trial and error. I've found the solution to what I wanted. It was just creating separate themes.xml file and just tweak the Theme.Dialog which is already defined in default android themes.xml. All I did was change the Animation part. Originally in android themes.xml the line looks like this.
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
but since modifying in android themes.xml doesn't take the effect. I just created my own themes.xml as I said above and just set parent as android:Theme.Dialog. And added a line like this.
<item name="android:windowAnimationStyle">#android:style/Animation</item>
Thanks for the help and I hope this solution helps others.
Use following code -
rl = (RelativeLayout)findViewById(R.id.someid);
//relative layout is my root node in main.xml (yours may be linearlayout)
WallpaperManager wm = WallpaperManager.getInstance(this);
Drawable d = wm.peekDrawable();
rl.setBackgroundDrawable(d);// You can also use rl.setBackgroundDrawable(getWallpaper);

Categories

Resources