I have a login screen that is branded differently for different builds of my application. I need the background image to be different in the layout file for this screen, so I want to point to a different style for the top level container. I'm a bit at a loss at how to do this.
I have declared a styleable something like:
<resources>
<declare-styleable name="ThemeBase">
<attr name="loginPageContainerStyle" format="reference" />
</declare-styleable>
</resources>
I have several different themes for the application, as such:
<resources>
<style name="ThemeBase" parent="android:style/Theme.Light" />
<style name="ThemeOne" parent="ThemeBase">
<item name="loginPageContainerStyle">#style/loginPageContainerThemeOne</item>
</style>
<style name="ThemeTwo" parent="ThemeBase">
<item name="loginPageContainerStyle">#style/loginPageContainerThemeTwo</item>
</style>
</resources>
And I have defined the following styles:
<resources>
<style name="loginPageContainerThemeOne">
<item name="android:background">#drawable/background_theme_one</item>
</style>
<style name="loginPageContainerThemeTwo">
<item name="android:background">#drawable/background_theme_two</item>
</style>
</resources>
And finally a login.xml file something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loginRoot"
style= [ ? WHAT GOES HERE ? ]
android:gravity="center_horizontal"
android:orientation="horizontal">
[ LAYOUT STUFF ... ]
</LinearLayout>
Am I doing anything wrong? Can this be done this way?
Ok I figured it out, the style reference should be:
style="?attr/loginPageContainerStyle"
Figured I would share.
Related
We developing home screen widgets in 2021 and I tried to implement dark theme support.
According to https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#widgets
"... use appropriate theme attributes instead of hardcoded colors."
So as I understand I can use custom attributes and I added attrs.xml in values folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="customBackgroundColor" format="color" />
</resources>
After that I added my custom attribute to light/dark theme
values/themes.xml
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="customBackgroundColor">#color/white</item>
</style>
</resources>
And also for dark
values-night/themes.xml
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents">
<item name="customBackgroundColor">#color/black</item>
</style>
</resources>
Here is my widget layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/customBackgroundColor" />
When I placing widget on home screen I got "Problem loading widget" message.
When I tried to hardcode colors for layouts, everything works as expected.
I also tried using default attributes "colorPrimary" and there was no error message but widget not changing color according to theme I switched.
Do I missing something or information in official docs is incorrect?
I'm trying to develop two themes for my app, and depending on the theme, I need a View to use a different selector. Though when I create a reference which determines the correct selector to use, I get an InflationException error.
Here's my attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ReditrTheme">
<attr name="downvoteArrow" format="reference" />
<attr name="upvoteArrow" format="reference" />
</declare-styleable>
<declare-styleable name="VoteState">
<attr name="enabled" format="boolean" />
</declare-styleable>
</resources>
Here's my themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DarkTheme" parent="#android:style/Theme.Holo">
<item name="upvoteArrow">#drawable/upvote_states</item>
<item name="downvoteArrow">#drawable/downvote_states</item>
</style>
<style name="LightTheme" parent="#android:style/Theme.Holo.Light">
<item name="upvoteArrow">#drawable/upvote_states_l</item>
<item name="downvoteArrow">#drawable/downvote_states_l</item>
</style>
</resources>
Here's my upvote_states.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top" app:enabled="false"/>
</selector>
Here's my upvotes_states_l.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top_l" app:enabled="false"/>
</selector>
downvotes_states.xml and downvotes_states_l.xml are identical to the ones above, they just use ic_action_arrow_bottom instead.
Finally, here's my View that I'm trying to apply the reference to:
<com.example.views.UpvoteView
android:id="#+id/upvote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:scaleType="fitCenter"
android:src="?attr/upvoteArrow" />
I tried a few solutions online but they were always a bit slightly different to my issue and didn't fix my problem.
Thanks in advance!
Just realized the mistake I made. In my states.xml files, I used the style attribute for some reason, it should have been android:drawable.
I'm implementing and app with a custom list adapter. When I inflate each list item which have a defined style the style doesn't seem to work.
I call the inflate doing this:
convertView = inflater.inflate(R.layout.widget,null);
The layout is this one:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?widgetWrapperStyle">
<LinearLayout
style="#style/stat" />
<RelativeLayout
style="?widgetStyle"
android:layout_below="#+id/widgetStat" >
<TextView
android:id="#+id/head"/>
<LinearLayout
android:id="#+id/body" />
</RelativeLayout>
My attrs.xml and style.xml are:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="widgetWrapper">
<attr name="widgetWrapperStyle" format="reference" />
</declare-styleable>
<declare-styleable name="widget">
<attr name="widgetStyle" format="reference" />
</declare-styleable>
</resources>
<style name="AppThemeDark" parent="AppBaseThemeDark">
<item name="widgetWrapperStyle">#style/widgetWrapperDark</item>
<item name="widgetStyle">#style/widget</item>
</style>
<style name="widgetWrapperDark" parent="widgetWrapper">
<item name="android:background">#color/list_item_background_dark</item>
</style>
<style name="widget">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">#dimen/widget_padding</item>
</style>
Non of the 'style="?xxxx"' seems to be working. When the view gets inflate the background color is not the correct one.
When inflating layouts, it is important to use a properly-configured LayoutInflater. In particular, it needs to be created from an Activity, ideally by just calling getLayoutInflater() (or getSupportLayoutInflater() for a SherlockActivity and kin, IIRC).
Dave Smith has an excellent blog post reviewing the various types of Context, including covering the issues regarding themes and layout inflation.
I have a simple problem. I'd like to provide multiple themes for my UI that a user can switch between
The problem is that I can use a theme that styles primitive UI classes, or I can use a style directly on an XML layout element, but I can't define a style that will then change based on the theme I have applied. Not all of the styling I want to do is based on the primitive type.
I would say that what I want to do is similar to using a CSS selector to style a class or ID, but themes only allow you to style an element name.
The best I can do right now is have a base style that inherits from EITHER of the actual styles I've built, as below:
My res/values/style.xml
// All styles have to be subclassed here to be made generic, and only one
// can be displayed at a time. Essentially, I'm doing the same thing as setting
// a theme does, but for styles. If I have 50 styles, I have to have 50 of
// these for each theme, and that's not DRY at all!
<style name="MyHeaderStyle" parent="MyHeaderStyle.Default"/>
<!--
<style name="MyHeaderStyle" parent="MyHeaderStyle.Textures"/>
-->
<style name="MyHeaderStyle.Default">
<item name="android:background">#android:color/background_dark</item>
</style>
<style name="MyHeaderStyle.Textures">
<item name="android:background">#drawable/header_texture</item>
</style>
Usage in my layout.xml:
<!-- Note that I can't use a theme here, because I only want to style a
SPECIFIC element -->
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/MyHeaderStyle"
android:gravity="center">
</LinearLayout>
Try this method:
1) Define your own res/values/attrs.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AppTheme">
<attr name="myLinearLayoutStyle" format="reference" />
</declare-styleable>
</resources>
2) Assign the above attr to you LinearLayout
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?attr/myLinearLayoutStyle"
android:gravity="center">
</LinearLayout>
3) Assign a concrete style to this attr:
<style name="AppLightTheme" parent="android:Theme.Holo.Light">
<item name="#attr/myLinearLayoutStyle">#style/lightBackground</item>
</style>
<style name="AppTheme" parent="android:Theme.Holo">
<item name="#attr/myLinearLayoutStyle">#style/darkBackground</item>
</style>
<style name="lightBackground">
<item name="android:background">#D1CBF5</item>
</style>
<style name="darkBackground">
<item name="android:background">#351BE0</item>
</style>
Hope I understood correctly your question.
I want to separate the usage of my application on xlarge devices and usage on other devices to restrict layout_width parameter by 720dp for xlarge. For this purpose I create values/attrs.xml:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<attr name="layoutWidth" format="reference|dimension" />
</resources>
with custom parameter layoutWidth to set it in
android:layout_width="?layoutWidth"
Furtner, I need to specify two themes.xml files for xlarge and ordinary devices in values-xlarge and values directories:
values-xlarge/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">720dp</item>
</style>
</resources>
values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">What should I write here!?</item>
</style>
</resources>
So, how can I make a reference on Android "fill_parent" parameter at this place? It seems like #android:layout_width/fill_parent, but I have compiling Error:
No resource found that matches the given name (at 'layoutWidth' with value '#android:layout_width/fill_parent').
I have found a solution by means of changing values/attrs.xml to:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<attr name="layoutWidth" format="dimension">
<enum name="fill_parent" value="-1" />
<enum name="match_parent" value="-1" />
<enum name="wrap_content" value="-2" />
</attr>
</resources>
Now, I can write in values/themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">match_parent</item>
</style>
<resources>
But the question still remain: Is it possible to refer to Android layout_width parameter from this place?
You should create attrs.xml file inside values folder and then add the below code in it:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="custom_match_parent" type="dimen">-1</item>
<item name="custom_wrap_content" type="dimen">-2</item>
</resources>
To access the above created attrs.xml add the below line inside your dimens.xml file as follows:
<dimen name="max_layout_width">#dimen/custom_match_parent</dimen>
Now to access that from a layout file you must do something like
<FrameLayout
android:layout_width="#dimen/max_layout_width"
android:layout_height="match_parent">
<!--Do what you like to do here-->
</FrameLayout>
Hope this helps! :-)
Well, this is a late response...but, for posterity and sanity, the answer can be found below and more info can be found at http://developer.android.com/guide/topics/ui/themes.html
styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="YourStyle" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>
This should work for any parent style that uses android:layout_width, such as parent="#android:style/Widget.TextView"
Not sure if you can add this attribute somewhere in your resources or style tags, but it may help (if its legal)
xmlns:android="http://schemas.android.com/apk/res/android"
This specifies the namespace where layout_width and layout_height are defined (as well as the constants fill_parent and wrap_content).