How to change styles dynamically in android - android

I would like to change myTheme color dynamically. I need to replace the color #FF0000 with my dynamically generated color.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme">
<item name="android:textColor">#FF0000</item>
</style>
</resources>

Related

Force style layout properties to be set by programmatically assigning parent beforehand

I have a style with specified margins that are not applied in a button because at the moment of creating the button it is not included in layout yet:
Custom attribute:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myButtonStyle" format="reference"/>
</resources>
Custom Style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="btn_program_style"/>
<style name="ProgrammaticallyStyle" parent="Widget.MaterialComponents.Button">
<item name="android:id">#id/btn_program_style</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_margin">5dp</item>
</style>
</resources>
Attribute+Style assignation to theme:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.ProgrammaticallyMaterialButtonApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="myButtonStyle">#style/ProgrammaticallyStyle</item>
</style>
</resources>
Code:
btnStyleButton = MaterialButton(this, null, R.attr.myButtonStyle)
linearlayoutButtons.addView(btnStyleButton)
How can I assign beforehand that btnStyleButton will be included in linearlayoutButtons so its margin definitions will be set? Instancing button with different context? Could inflator work here somehow?
I know I can assign btnStyleButton.layoutParams = customLayoutParams after creating the button instance, but I want it to be taken directly from style.

white background and black text color on android wear app

in my android wear app i need to change the default black background to white and the text color to black. in order to not set those colors each time i create a new layout file, i created a theme that defines the background and text color and applied it to the main layoutfile
the layout file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:roundLayout="#layout/round_activity_wear"
app:rectLayout="#layout/rect_activity_wear"
tools:context="com.example.wear.WearActivity"
tools:deviceIds="wear"
style="#style/AppTheme">
</android.support.wearable.view.WatchViewStub>
the style file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="android:background">#FFFFFF</item>
<item name="android:text">#000000</item>
<item name="android:color">#000000</item>
<item name="android:colorForeground">#000000</item>
<item name="android:textColor">#000000</item>
<item name="android:textColorPrimary">#000000</item>
<item name="android:textColorSecondary">#000000</item>
<item name="android:textAppearance">#style/WearTextAppearance</item>
</style>
<style name="WearTextAppearance" parent="#android:style/TextAppearance.Medium">
<item name="android:color">#000000</item>
<item name="android:colorForeground">#000000</item>
</style>
</resources>
after i attached it, the background changed to white, but the text color remained white. what did i do wrong? why is my text color not black as i would expect it?
it worked after i set my theme inside the application tag of the manifest.

Make TabView background fill whole tab

Here is where I am right now: screenshot of problem.
Ignoring the tab indicator (which I will figure out later) the problem I'm having is the background I set for the selected tab seems to only be filling the text of the tab.
I would like for the tab selected background to fill the selected tab, and not just the text.
Here's what I've done so far:
res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyActionBar"
parent="#android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#drawable/bg_action_bar</item>
</style>
<style name="LoginActionBar"
parent="#style/MyActionBar">
<item name="android:actionBarTabStyle">#style/LoginActionBarTabs</item>
</style>
<style name="LoginActionBarTabs"
parent="#android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">#drawable/login_actionbar_tab_indicator</item>
<item name="android:padding">0dp</item>
</style>
</resources>
res/drawable/login_actionbar_tab_indicator.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="false"
android:drawable="#color/loginTab" />
<item android:state_selected="true"
android:drawable="#color/loginTabSelected" />
</selector>
res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="loginTabSelected">#FFFFFF</color>
<color name="loginTab">#999999</color>
</resources>
You can put the TextView as matchparent for height and width and use your selector for its background.

In Android, can apply different themes in a single XML layout's TextView at runtime without creating a custom widget?

I've seen similar questions here before, but none of them had a satisfactory answer. Basically, I want to have one layout instead of multiple ones and be able to apply themes at runtime. For example, let's take this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SAMPLE HEADING"
style="#style/Heading" />
</LinearLayout>
And the themes and styles are set up as follows:
<style name="AppTheme.Dark" parent="AppTheme">
<item name="android:radioButtonStyle">#style/radioButton.Dark</item>
<item name="android:checkboxStyle">#style/checkbox.Dark</item>
</style>
<style name="AppTheme.Light" parent="AppTheme">
<item name="android:radioButtonStyle">#style/radioButton.Ios</item>
<item name="android:checkboxStyle">#style/checkbox.Ios</item>
</style>
<style name="Heading">
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
</style>
<style name="Heading.Dark" parent="Heading">
<item name="android:textColor">#color/red</item>
<item name="android:background">#drawable/dark_bg</item>
<item name="android:textSize">16dip</item>
</style>
<style name="Heading.Light" parent="Heading">
<item name="android:textColor">#color/black</item>
<item name="android:background">#drawable/light_bg</item>
<item name="android:textSize">17dip</item>
</style>
So, I want to be able to apply the dark and light Heading styles to that TextView by simply applying the dark or light AppTheme. And I don't want to apply those styles to all TextViews, but only specific ones. I also don't want to do this programmatically because there are way too many TextViews that would need this done.
Is there a way to do that, or do i have to create two identical XML layouts, where one uses the Heading.Light style and the other uses Heading.Dark?
First, your use of parent="..." property is incorrect.
As official docs state:
"If you want to inherit from styles that you've defined yourself, you do not have to use the parent attribute. Instead, just prefix the name of the style you want to inherit to the name of your new style, separated by a period."
So, declaring your style name as Heading.Light is enough to specify that it's parent style is Heading.
Now to your question. Create a res/values/attrs.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myTextViewColor" format="reference|color" />
</resources>
Then in your styles.xml you would declare your theme as follows:
<style name="AppTheme">
<!--parent style. could be overriden by Dark and Light theme -->
</style>
<style name="AppTheme.Dark">
...
<item name="myTextViewColor">#color/red</item>
</style>
<style name="AppTheme.Light">
...
<item name="myTextViewColor">#color/black</item>
</style>
<style name="Heading">
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">16dip</item>
</style>
Now when you apply
<TextView ... style="#style/Heading" android:textColor="?myTextViewColor />
everything should work just fine. Just make sure you apply AppTheme.Light or AppTheme.Dark theme in your app (as AppTheme parent theme would not know the value of your custom attribute).
Edit: Also, as user496854 suggested, there's another simple workaround.
Declare headingStyle attr as a reference:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="headingStyle" format="reference" />
</resources>
Then in our AppTheme.Dark and AppTheme.Light styles we would point to a corresponding heading style:
<style name="AppTheme.Dark">
...
<item name="headingStyle">#style/Heading.Dark</item>
</style>
<style name="AppTheme.Light">
...
<item name="headingStyle">#style/Heading.Light</item>
</style>
I would suggest you to crate a class that extends TextView and apply your style in it. Use this textView where you want textview with this them and simple TextView where you don't need.

Switching Styles

Let's say I have multiple styles.xml files (with different names of course) for themes. Is it possible to choose which file the app should pull from?
White style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mybutton">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:textColor">#202020</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#drawable/white_btnbg</item>
</style>
...
Black style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mybutton">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#drawable/black_btnbg</item>
</style>
...
So then, in my layout xml all my button's styles would be set to "mybutton" and depending which theme the user chose it would pull from the coordinating file.
Since it isn't possible to change a view's style at runtime is it possible to do this? Or is there a better way (i'm sure there is) to change styles?
Use multiple styles with different names. Then you can set the backGround programmatically:
Button b = new Button(this);
b.setBackgroundResource(R.drawable.blabla);

Categories

Resources