I've been searching the solution for hours: how to apply a simple theme or style to an application, an activity or just a view? It seems super easy but my styles always get ignored.
Here is the code in style.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="master" parent ="#android:style/Theme.NoTitleBar">
<item name="android:typeface">serif</item>
<item name="android:textColor">#8b8378</item>
</style>
</resources>
and here is the code in AndroidManifest.xml:
<application android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/master">
and code in a ListView
<ListView android:layout_height="wrap_content"
style="#style/master"
android:id="#+id/list"
android:layout_width="fill_parent">
</ListView>
NOTHING ever happens. Font style, color all remain the default. Only by declare the attributes explicitly like
<TextView android:gravity="center" android:typeface="serif" android:textColor="#8b7d6b" android:textAppearance="?android:attr/textAppearanceSmall" android:id="#+id/text_intro" android:layout_height="wrap_content" android:text="#string/welcome_text" android:layout_width="wrap_content" android:padding="20sp" android:layout_weight="0"></TextView>
will work. I know eclipse doesn't support preview of theme and style, but they don't work on emulator as well.
Help please! I can't believe I have been stuck with this tiny issue for a week... Thank you in advance!
There are a few things about Android styles and resources at work here.
Android styles are an extremely general facility, and the result is that some configurations are possible but invalid and will be ignored. You've run across a few. :)
When applied to a view, a style will be equivalent to setting those same attributes on that view. Styles do not cascade to child views. typeface and textColor aren't valid on a ListView, so they are ignored. They also aren't going to work on a theme that way, since themes provide default styles for different kinds of views. (Why are invalid attributes silently ignored instead of generating an error? Because as new attributes are added in later platform revisions, older devices should ignore extra attributes that they don't know how to parse for compatibility.)
The best way to accomplish what you're trying to do is likely to be:
Create a style for TextViews. (This shouldn't have a parent that is a theme like your pasted code does.)
Apply that style to the TextView in your list item layout using the style= syntax.
Related
How to change custom fonts in android studio? It seems like there is no easy way to do such a simple thing. I see that you can change the font of TextView but to change the font for a particular element, drawer or globally I can't seem to find an explenation.
Just Like #tycj said in the comments, unfortunately there is no way to set global fonts to the Textviews. But you can set custom type-styles and apply them as "textAppearance" to the TextViews.
For instance: Assume you have such a style in your project
<style name="MyAPP.TextAppearance.Headline1" parent="TextAppearance.MaterialComponents.Headline1">
<item name="fontFamily">#font/your_font</item>
<item name="android:textSize">48sp</item>
</style>
Then , you simply apply this to your theme.Like this :
<item name="textAppearanceHeadline1">#style/MyAPP.TextAppearance.Headline1</item>
Now you can free to use this in a TextView but as the name of the style suggest, it is better to use this for the hearder TextViews in your app.
<TextView
...
android:textAppearance="?attr/textAppearanceHeadline1" />
the good thing is that you can override these attributes
<TextView
...
android:textAppearance="?attr/textAppearanceHeadline1"
android:textSize="36sp" />
To get further information, you can check here. Also I suggest checking this sample project as well
I want to style all my ImageButtons in a theme. After searching for quite some time I found the solution to my problem. But I don't know why it works like it does.
My main layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<ImageButton
android:id="#+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#mipmap/ic_launcher_foreground" />
</LinearLayout>
This is my original theme that didn't work. It styles my TextView but ignores the ImageButton. The result is shown in the screenshot below.
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:imageButtonStyle">#style/redBackground</item>
<item name="android:textViewStyle">#style/redBackground</item>
</style>
<style name="redBackground">
<item name="android:background">#FF0000</item>
</style>
</resources>
And here's the theme that works:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="imageButtonStyle">#style/redBackground</item>
<item name="android:textViewStyle">#style/redBackground</item>
</style>
<style name="redBackground">
<item name="android:background">#FF0000</item>
</style>
</resources>
The only difference is the missing 'android:' prefix in front of the 'imageButtonStyle' attribute.
So my questions are:
What is the difference between imageButtonStyle and android:imageButtonStyle?
Why does android:textViewStyle work but not android:imageButtonStyle? They are both defined the plattforms 'attrs.xml'.
Why is there no textViewStyle (without android prefix)? Removing the prefix yields an error.
Where are the attributes defined that have no prefix? Apparently not in the plattforms 'attrs.xml'.
Where can I find proper documentation for the whole style stuff? Of course I halve already read the respective Google docs (https://developer.android.com/guide/topics/ui/look-and-feel/themes.html). But still i have basic questions like this one.
Interestingly, it seems like the 'android:imageButtonStyle' version has worked some years ago: How to apply an style to all ImageButtons in Android?. I haven't tested that myself, though.
And here's the post that proposed removing the android prefix. Including unanswered comments that ask why it works: buttonStyle not working for 22.1.1
android tag that you use is used for attribute coming from Android SDK.
app tag is used if you are using the support library.app is just a namespace for any custom parameters for a custom View.
This can be anything but if you see the root element there's probably a line xmlns:app="http://schemas.android.com/apk/res-auto" that assigns the namespace
You may also see other namespaces if you are using custom views (of your own or form a library).
In case that anyone else stumbles across the question: I've found the answer in this Droidcon talk: https://youtu.be/Jr8hJdVGHAk?t=21m12s
The topic is handled in a minute starting at 21:12.
As I understand it, specifying no namespace results in the global namespace being searched which seems to include the support libraries attributes. And indeed both, the SDK's R.attr as well as the support library's R.attr define the imageButtonStyle attribute (with slightly different descriptions). However, the support library does not define a textViewStyle attribute. So that explains why you can't omit it's android: prefix.
To answer my last question concerning the documentation: Despite the Google guide and the R.attr classes' documentation, the video mentioned above and this Google I/O talk are quite informative: https://www.youtube.com/watch?v=TIHXGwRTMWI
So the only question that is left open is why the SDK's imageButtonStyle does not work.
I've been recently looking into supporting RTL text and layouts. According to this post android will natively support and switch layoutDirection automatically for API-17, which is why the Start and End gravities were added. The issue now is how to support this in a similar way for pre API-17.
This question has been asked many times before, with the general solution being to inspect the locale or text, then set gravity as needed. At least it would require less effort than a solution like this.
The reason I'm revisiting this question now is because I have noticed an update to support-v7-appcompat which now contains classes such as AppCompatTextView and LinearLayoutCompat. As far as I know, the point of these support libraries is to mimic the default behavior of later Android releases.
I created a layout to test this.
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80ccffee">
<android.support.v7.widget.AppCompatTextView
android:id="#+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
When I give textview an arabic string, it is correctly detected as RTL text and automatically right-aligned on an API-17 device, where as the same does not happen on an API-10 device. It's possible that I misunderstood the purpose of AppCompatTextView, but the presence of GravityCompat.START suggests to me that its intended as a workaround.
I then wrapped the textview in a LinearLayoutCompat instead in the hopes that the layout's direction will influence it, but no luck.
So my question is: is there a mechanism in the new AppCompat update which can be used to support RTL without having to set each TextView's gravity in code?
Yes, there is!
You can achieve what you want by overriding default attributes of theme as described below:
Go to res -> values -> styles.xml
override attributes like this:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="android:textDirection">rtl</item>
<item name="android:gravity">start</item>
</style>
I'm trying to build an Android UI via layouts. I start with the following:
<TextView
android:id="#+id/..."
android:layout_marginTop="8dip"
android:text="..."
style="?android:attr/listSeparatorTextViewStyle"/>
And that looks good (all caps, smaller font, dividing bar underneath it). Now I want to extend the style, so I change it to the following:
<TextView
android:id="#+id/..."
android:layout_marginTop="8dip"
android:text="..."
style="#style/section_title"/>
With a style of:
<style name="section_title" parent="#android:attr/listSeparatorTextViewStyle">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
And that doesn't work (font is correct, but the divider line is gone).
How come... that?
When you're using:
style="?android:attr/listSeparatorTextViewStyle"
you're using the style pointed by this attribute(listSeparatorTextViewStyle). If you look in the platform themes.xml you'll see that the style that is actually used for this attribute is Widget.TextView.ListSeparator.White. So this is the style you should extend in your custom style.
Unfortunately that style is private and you can't extend it, or you shouldn't extend it(for reference, see this bug report from google). Your best option would be to copy that entire style, Widget.TextView.ListSeparator.White(Widget.TextView.ListSeparator isn't public as well so would have to also copy that), in your custom style and use that instead of extending the style from the android platform(see this response from the link above).
I want to set the text appearance in my theme to be TextAppearnance.Large.
Here is what I am doing in my styles.xml (my application is pointing to this theme in my manifest)
<style name="myTheme" parent="android:Theme.NoTitleBar.Fullscreen">
<item name="android:textAppearance">#android:style/TextAppearance.Large</item>
</style>
Problem:
My text is still being displayed small.
Question(s):
What am I doing wrong in trying to use a predefined TextAppearance in my activity? i.e. How do specify this TextAppearance correctly?
Where are the TextSizes for TextAppearance.Large/Medium/Small defined?
First, declare the attribute as
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
But declaring text appearance or text color in a theme only affects text that has absolutely no style or attribute anywhere, including system-defined ones. If you add a
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text" />
without even the android:textAppearance="?android:attr/textAppearanceMedium" line that Eclipse throws in, it will be affected by this theme, but buttons and the like never will.
themes and styles are defined in the themes.xml and styles.xml files of the sdk implementations in your environment (distinct ones for different android versions or sdk levels).
search your computer for themes.xml (you will probably find multiple instances of it in the "program files/android" folder on a windows 32-bit machine, for example).
this post explains how to customize these attributes.
you can also set explicit size attributes in your xml layout file, by modifying the TextView tag attributes:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="15sp is the 'normal' size."
android:textSize="15sp"
/>
this post explains how to customize android fonts (including fontType, fontColor, shadow, bold, italic) directly in xml layout file.