Android TextView fontFamily not working when set via TextAppearance - android

I am having issues when using android:fontFamily when set via TextAppearance styles.
Setting global font through android:fontFamily in theme works
Setting android:fontFamily directly on TextViews works (I am using AppCompat and it correctly inflates the AppCompatTextView during inflation from xml, so no issues here)
When setting the font via styles, it just does not work. Any help will be much appreciated. I am thinking that this has to do with how AppCompatTextView processes the style attributes, but have not had much luck in finding the exact root cause.
<style name="TextAppearance.Header">
<item name="android:fontFamily">#font/headerfont</item>
</style>
<TextView
android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.Header" />

Try this...hope it will work.
<style name="TextAppearance.Header">
<item name="android:fontFamily">#font/headerfont</item>
</style>
<TextView
android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/TextAppearance.Header" />

Related

Android Studio design preview not applying style?

I have a very simple <style> in styles.xml:
<style name="roundActionButton">
<item name="background">#drawable/action_button_background</item>
</style>
I'm applying this style to a FrameLayout in one of my activities:
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="#id/okButton"
app:layout_constraintBottom_toBottomOf="#id/okButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintDimensionRatio="1"
style="#style/roundActionButton"
android:padding="7dp"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:layout_marginStart="25dp"
android:layout_marginLeft="25dp">
The FrameLayout is visible, but the style is not applied in the Android Studio design preview, no matter how much I rebuild the project or force refresh the layout. However, if I set the background directly in the FrameLayout, it is displayed as expected in the design preview as well:
<FrameLayout
...
android:background="#drawable/action_button_background">
The theme in the design preview is set to AppTheme (I've tried others too but no change). Shouldn't the style be visible in the design preview?
You are missing android: in style...
<style name="roundActionButton">
<item name="android:background">#drawable/action_button_background</item>
</style>

android:lineSpacingMultiplier doesn't work in android:textAppearance

I'm trying to add android:lineSpacingMultiplier in my textAppearance style (android:textAppearance), and it's not working. Am I doing something wrong?
TextAppearance style:
<style name="TextAppearance.Body1" parent="TextAppearance.AppCompat.Body1">
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
Use of style:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is body 1\nThis is body 1"
android:textAppearance="TextAppearance.Body1"
/>
For whatever reason android:lineSpacingMultiplier doesn't work as an item within your textAppearance. You'll either have to set it directly as a TextView attribute (using android:lineSpacingMultiplier), or create a regular style which "wraps" setting the textAppearance and lineSpacingMultiplier
Create a style
<style name="TextBody1">
<item name="android:textAppearance">#style/TextAppearance.AppCompat.Body1</item>
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
or
<style name="TextBody1" parent="TextAppearance.AppCompat.Body1">
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
and then apply via style instead of android:textAppearance
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is body 1\nThis is body 1"
style="#style/TextBody1"
/>
lineSpacingMultiplier as well as lineSpacingExtra you can apply only in style.
But as an alternative, you can use lineHeight attribute, which can be applied to the MaterialTextView using textAppearance.
Interesting note, that if you use a fully Material theme (not Bridge) all your TextView will auto-inflate to MaterialTextView, otherwise, you will need to specify <com.google.android.material.textview in your xml.
I was able to solve the issue by simply applying the style to the TextView itself instead of the textAppearance (similar to the accepted answer, but with a bit less code).
Here is a sample:
Style:
<style name="TextBody1" parent="TextAppearance.AppCompat.Body1">
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
or simpler if you don't care about the parent:
<style name="TextBody1">
<item name="android:lineSpacingMultiplier">1.25</item>
</style>
Then in your View:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is body 1\nThis is body 1"
style="#style/TextBody1"
/>
I am not sure why applying android:textAppearance to a TextView with a given style that defines android:lineSpacingMultiplier does not work (I would speculate that it may be due to the fact that the line spacing is on the style View itself instead of the textAppearance of the View) but this is a bit simpler than the accepted answer if you don't care about the parent.

AppCompatButton and buttonStyle

I am trying to get some buttons to be use the Material Design style (in particular accentColor tinting) for Android 4.4 devices using the AppCompat library. I have had success with the following:
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/continue_button"
android:id="#+id/continue_button"
android:layout_gravity="center_horizontal|bottom"
style="#style/CompatButton"
android:theme="#style/ThemeOverlay.AppCompat.Dark"/>
where "#style/CompatButton" has "Widget.AppCompat.Button.Colored" for a parent. However some of my buttons are the same but instead of declaring the style in the element, I attach the style as the default "buttonStyle" in the theme being used:
<style name="AppTheme">
...
<item name="android:buttonStyle">#style/CompatButton</item>
<item name="colorAccent">#color/flow_accent</item>
...
</style>
and
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/continue_button"
android:id="#+id/continue_button"
android:layout_gravity="center_horizontal|bottom"
android:theme="#style/ThemeOverlay.AppCompat.Dark"/>
These buttons are showing up with the default, non-Material stylings. This also seems to happen with ProgressBar. Can anyone see what's wrong with this and if there's a workaround without having to explicitly define the button style?
Oops, that was dumb. Obviously ThemeOverlay wipes out the previous theme, including the buttonStyle definition. For it to work we have to add the buttonStyle back in:
<style name="FlowOverlay" parent="ThemeOverlay.AppCompat.Dark">
<item name="android:buttonStyle">#style/CompatButton</item>
</style>
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/continue_button"
android:id="#+id/continue_button"
android:layout_gravity="center_horizontal|bottom"
android:theme="#style/FlowOverlay"/>
though that loses much of the convenience we wanted from default button styles in the first place.

Typeface monospace ignored on lollipop

Am trying to set monospace typeface to a listview in my layout but it seems lollipop ignores the set typeface. Other api versions below lollipop works just fine displaying my desired result.
Ps:
Am not trying to set a global font, I just want a monospace texttypeface for my listview for api >21.
Any help will be appreciated.Thanks
EDIT
<ListView
android:layout_gravity="start"
android:id="#+id/List"
android:tag="toggle"
android:background="#99111111"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollingCache="false"
android:typeface="monospace "
android:dividerHeight="0.0dip" />
The Material text appearances specify the android:fontFamily attribute rather than android:typeface.
Try this for global styling,
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:textViewStyle">#style/MonospaceTextViewStyle</item>
</style>
<style name="MonospaceTextViewStyle" parent="android:Widget.TextView">
<item name="android:fontFamily">monospace</item>
</style>
Now simply add the theme to your activity,
<application
android:theme="#style/AppTheme" >
</application>
If your ListView is created with a custom adapter, you may also add the attribute directly inside a TextView,
<TextView
.....
android:fontFamily="monospace"
.....
/>

Referencing specific attribute in another style

I'm trying to find the best way to match the text size of a label next to an EditText using xml.
I would prefer not to inherit the EditText style directly, since that would bring in a bunch of attributes I'm not interested in.
<EditText
android:id="#+id/editQuantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textUnit"
style="#style/FontMatchingEditText"
android:text="units"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Is there some way to refer to a specific attribute in another style?
Otherwise, would it make more sense make my own style for EditText to make sure it stays consistent with the label?
Edit
I was hoping there might be a theme independent way of doing it, semantically something like this:
<item name="android:textSize">#android:style/Widget.EditText.textAppearance.textSize</item>
But I'm probably overcomplicating it.
Thanks!
Assuming your parent theme is android:Theme.Holo.Light.
From \android-sdk\platforms\android-X\data\res\values\themes.xml:
<style name="Theme.Holo.Light" parent="Theme.Light">
...
<!-- Widget styles -->
<item name="editTextStyle">#android:style/Widget.Holo.EditText</item>
From \android-sdk\platforms\android-X\data\res\values\styles.xml:
<style name="Widget.Holo.EditText" parent="Widget.EditText">
</style>
<style name="Widget.EditText">
...
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">?android:attr/editTextColor</item>
</style>
Now you can just reuse theme attributes used for EditText for your TextView:
<TextView
android:id="#+id/textUnit"
android:textColor="?android:attr/editTextColor"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:text="units"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

Categories

Resources