Styling CardView groups - android

For a small tool, I have to write an Android app. There are no requirements on portability, it's sufficient when the app only runs on android version 6 or later.
I would love to group dialog elements into CardViews and I would love to have some reasonable layout (spacing, colors, etc). Is there a way to use a theme, standard layout, style, etc. that I could use without the need to apply "android:padding", "card_view:cardElevation", ect. attribute to every CardView?
If it's not possible to use some already existing defaults, I could use styles. When I use styles (following Google's "Styles and Themes" API Guide), I get error messages, when I move some attributes from the CardView definition from the layout xml to the style xml. For attributes that I move to the style xml, that begin with "android:", there is no error. For other attributes, I get an `No resource found that matches the given name-error.
<style name="CardGroups">
<item name="xmlns:card_view">"http://schemas.android.com/apk/res-auto"</item>
<item name="card_view:cardElevation">3dp</item>
<item name="android:layout_margin">3dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
results in: Error:(20, 5) No resource found that matches the given name: attr 'card_view:cardElevation'.

You are correct that styles are the way to go to provide a common set of attributes to multiple Views.
You should not use custom namespaces in your style definitions. For custom attributes provided by libraries (such as cardElevation), you simply do not provide a namespace.
Thus your style should look like this:
<style name="CardGroups">
<item name="cardElevation">3dp</item>
<item name="android:layout_margin">3dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>

Related

How to define textAppearence value in android layout

In my layout, I am using falling for predefined values for android:textAppearence. But, there are, as I found, at least 2 ways to define them, which yields a very different result (like, different font size and alpha and weight value):
android:textAppearance:="#style/TextAppearance.MaterialComponents.Caption". This #style/... values are defined in (in my case) in a file
~/.gradle/caches/transforms-2/files-2.1/11ab83d2971a1126be493aa33fdd0f6e/material-1.1.0/res/values. This, for example, is defined as:
<style name="TextAppearance.MaterialComponents.Caption" parent="TextAppearance.AppCompat.Caption">
<item name="fontFamily">sans-serif</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">12sp</item>
<item name="android:letterSpacing">0.0333333333</item>
</style>
android:textAppearance="#android:style/TextAppearance.Material.Menu". This is defined in
/home/rudra/.Android/Sdk/platforms/android-29/data/res/values/styles_material.xml. This is defined as:
<style name="TextAppearance.Material.Menu">
<item name="textSize">#dimen/text_size_menu_material</item>
<item name="fontFamily">#string/font_family_menu_material</item>
</style>
The main problem to me is, I am not sure which one to use for more consistent user experience. I am sure, the file for case 2 will not be shipped with my app, but maybe the user will have styles_material for his android-xx. But by realizing how values have changed with material-1.0.0 and 1.1.0, I am a bit sKeptic to depend on these values, but I am not sure.
On the other hand, this is a considerable work to redefine textAppearance for all possible scenarios.
So, I am looking for suggestions on how to define the textAppearence, and among case 1 and case 2, which should I use for more consistent result across devices
If you want to define a custom textAppearance, you can define as follow. I use material-components-android.
In style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/primaryColor</item>
<item name="colorPrimaryDark">#color/primaryDarkColor</item>
<item name="colorPrimaryVariant">#color/primaryLightColor</item>
<item name="colorOnPrimary">#color/primaryTextColor</item>
<item name="colorSecondary">#color/secondaryColor</item>
<item name="colorSecondaryVariant">#color/secondaryDarkColor</item>
<item name="colorOnSecondary">#color/secondaryTextColor</item>
<!-- This line is important -->
<item name="textAppearanceHeadline3">#style/TextAppearance.Headline3</item>
</style>
<style name="TextAppearance.Headline3" parent="TextAppearance.MaterialComponents.Headline3">
<!-- Define your custom appearance here. -->
<item name="fontFamily">#font/work_sans_black</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">#dimen/text_size</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/primaryTextColor</item>
</style>
You can use this-TextAppearance.Headline3 in layout as follow.
<TextView
android:id="#+id/tvAppName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textAppearance="?attr/textAppearanceHeadline3"
/>
This is my usage for custom text appearance. You can define as you like.
If you want to customize theme or style, you have to know common attributes. You can see it at this article.
I hope this will be helpful for you.
Looking at TextView.java, there don't appear to be any attributes that are defined by android:textAppearance that are not able to be set on a TextView directly. So there doesn't appear to be any technical reason that one needs to use them over defining attributes in styles directly, at least in one's ability to configure how a TextView looks.
This means that you can avoid using it in your layouts as well as your styles without any adverse effects, provided that you override all the associated attributes. The base theme defines many different standard android:textAppearances for the various widgets, so you should check that all the widgets are properly overridden.
Based on my experience, android:textAppearance is most useful if you wish your app to appear to integrate into the rest of the device. So if you need big text, you can use android:textAppearance="?android:attr/textAppearanceLarge" and now your text is large! No need to know how many sp that means for the given device/screen size/etc..
However if your app is highly styled and you'd otherwise be overriding all the text sizes anyhow, the value-add of android:textAppearance diminishes. You can certainly use it as referenced in the posts above, but if that doesn't fit into your styling system, then feel free to omit it. It's just another tool to help you get a good-looking app across all devices.
I would also recommend making extra-sure that you try your app across a variety of devices if you choose not to use it, just to make sure that you didn't neglect to override a default android:textAppearance.

Styling ActionBar Tabs

I'm attempting to change the colors on my ActionBar Tabs to match the colors used in my app. I've been following the blog post here: http://blog.alwold.com/2013/08/28/styling-tabs-in-the-android-action-bar/ which is very helpful. However when setting up the theme in Step 1 I can't find the correct value for the parent attribute. The website lists "Theme.Sherlock", but I'm not using ActionBarSherlock, so that doesn't apply.
My XML is as follows:
<style name="PropertyApp" parent="#style/Widget.Holo.ActionBar.TabView">
<item name="android:actionBarTabStyle">#style/PropertyApp.ActionBar.Tab</item>
<item name="actionBarTabStyle">#style/FindMyTrain.ActionBar.Tab</item>
</style>
<style name="PropertyApp.ActionBar.Tab">
<item name="android:background">#drawable/tab_bar_background</item>
</style>
No matter what I use for the parent style in the top style definition, I get an error that "No resource found that matches the given name: attr 'actionBarTabStyle'". Also, I'm told that the symbol "PropertyApp.ActionBar.Tab" cannot be resolved.
Your issue is that you are specifying the Widget.Holo.ActionBar.TabView parent style for your main PropertyApp style.
You will need to put that in your PropertyApp.ActionBar.Tab style.
Then put the main parent theme for PropertyApp like Theme.Holo.
<style name="PropertyApp" parent="android:style/Theme.Holo">
<item name="android:actionBarTabStyle">#style/PropertyApp.ActionBar.Tab</item>
</style>
<style name="PropertyApp.ActionBar.Tab" parent="android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">#drawable/tab_bar_background</item>
</style>
The naming of the parent styles will also depend on which API levels you are targeting. AppCompat for example if you are using that.
You can refer to the documentation on changing the tab backgrounds.

Android cascading layouts?

Is there a way to specify different styles for different elements of a view group within one style?
For example, I have a list where each item has a title, details and separator. I would like to be able to have one style tag in my styles.xml that applies side padding to the text but only top/bottom padding to the separator.
I realise my thinking could be influenced by css, I was just wondering if there was an elegant solution in android for it.
A style can have a parent, with the resulting view applying attributes "top-down", i.e. the child styles will override conflicting parent style attributes.
Code I ended up using (I have a list with multiple separators, I wanted padding only on the last one):
<style name="ListItemSeparator">
<item name="android:background">android:attr/listDivider</item>
<item name="android:layout_height">1px</item>
</style>
<style name="LastListItemSeparator" parent="ListItemSeparator">
<item name="android:layout_marginBottom">20dp</item>
</style>
More info can be found here
If it's just your own styles you want to extend, then you can use the dot notation, as mentioned in the Android docs, i.e. you could do:
<style name="ListItemSeparator">
<item name="android:background">?android:attr/listDivider</item>
<item name="android:layout_height">1px</item>
</style>
<style name="ListItemSeparator.LastListItemSeparator">
<item name="android:layout_marginBottom">20dp</item>
</style>
Then reference the style like:
<View style="#style/ListItemSeparator.LastListItemSeparator"/>
You can subclass a View in java and then refer to it in your xml.
Then, you can subclass your custom View to create views that inherit from it.

Android private styles using

Trying to inherit Widget.TextView.ListSeparator style, but now aapt doesn´t allow to do this:
No resource found that matches the given name
'Widget.TextView.ListSeparator
because google made it private. But how can I combine two styles : ListSeparator and margins?
Style 1
<style name="settings_plain_text">
<item name="android:layout_marginTop"> 10sp </item>
<item name="android:layout_marginBottom"> 10sp </item>
<item name="android:textSize"> 18sp </item>
Style 2
style="?android:attr/listSeparatorTextViewStyle"
I copy the answer from this link:
Hello all. I did some investigating with the frameworks team who's in charge of aapt.
What is happening is that some styles, like WindowTitle are not public (you won't find them in android.R.style). You should not be extending non public resources. aapt used to let you do that but it was a bug which was fixed in platform-tools r6.
The issue is that once compiled, resources are assigned an integer. In this case your custom style is assigned an integer and its parent is referenced through the parent integer.
For the framework, only public resources are guaranteed to only have the same integer, build after build. The integer of private resources integer will change from build to build.
This means that your custom style is referencing a parent that will not be valid once installed on a device. It'll referenced either another resources or none at all, and it won't do what you want.
If you wish to reuse a style that is private, you should copy the content of that style into your own instead of extending it.
The style I have found googling is that one:
<style name="Widget.TextView.ListSeparator">
<item name="android:background">#android:drawable/dark_header_dither</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">?textColorSecondary</item>
<item name="android:textSize">14sp</item>
<item name="android:gravity">center_vertical</item>
<item name="android:paddingStart">8dip</item>
</style>
From that you can modify margins.

How do I employ basic styles in Android?

I'm having difficulty getting Android Styles to work.
As a test, I created an EditText control and associated it with a Style called "CodeFont" like such:
EditText et = new EditText(this, null, Resource.Style.CodeFont);
Next, I defined a style which inherits from a standard style and changes the text color to red like such:
<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">#FF0000</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
What am I doing wrong? When the EditText appears, it no longer features the orange border on focus. This makes me think that the styling is working. However, the text color remains black.
Unless you need your EditText to be dynamically generated you should use XML and then define the style via XML. This is separates your GUI from your code which can have many benefits.
Like this you can simply specify the style like so:
style="#style/CodeFont"
See the Android developers' website for more information.
The border isn't showing up since you're using "#android:style/TextAppearance.Medium" as your parent style. TextAppearance.Medium is a textAppearance attribute style, not a widget style. If you want the orange border and everything to still show up but have a medium text size then you'd want to do something like this:
<style name="CodeFont" parent="#android:style/Widget.EditText">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#FF0000</item>
<item name="android:textAppearance">#android:style/TextAppearance.Medium</item>
<item name="android:typeface">monospace</item>
</style>
Ok. I finally found the solution. I had to piece it together from a few resources.
In Android 4.0 (Ice Cream Sandwich), there is a known problem with specifying the theme name in the attribute section of the activity: Cannot Resolve #style/Theme.Sherlock. If you use the attribute to set the theme then the compiler will return "No resource found that matches the given name (at 'theme' with value '#style/blah-blah'". So you want to set theme using the SetTheme( ) API within the Activity's OnCreate( ).
When you create your style, the style needs to be part of a theme which you referenced in Step 1. Make sure you group your styles within your theme (you can inherit from the standard Android themes if you like). For each of your style names, you will need to create an attribute reference as described in the link in Step 1. The following link is the "correct" way to define a style name resource attribute: How do I create my own resource names?
You need to reference your style from your theme via the attribute you defined in Step 2. For example:
EditText et1 = new EditText(this, null, Resource.Attribute.CodeFontRef);

Categories

Resources