I have an Android app that needs some adjustment if the user sets their font size to extra large (via Settings -> Display -> Font size in 4.0 and higher).
Is there a simple way for me to tell what the user's font size preference is
Updated:
in my layout.xml I have lines similar to to setup a button
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:typeface="sans"
Notice that I'm not setting the font size directly. This layout works and looks good in all cases, except for the Extra Large setting. In that case, due to space limitations, it causes the button's text to wrap to 2 lines.
My goal is to make a slight wording change in the case of Extra Large so that it doesn't wrap
There's a FONT_SCALE parameter you should be able to query the system for. I haven't used it myself, but I imagine retrieving its value would look somewhat like this:
float fontScale = Settings.System.getFloat(context.getContentResolver(), Settings.System.FONT_SCALE)
However, I'd also like to point out that usually you shouldn't be dealing with this value directly. In stead, use sp units for textual content so that you don't have to worry about adjusting to user-preferred font sizes yourself, but rather let the system handle that.
Also refer to: Why should we use sp for font sizes in Android?
Related
So I have read possibly everything about the difference between sp and dp. I can say that I do understand why sp is better than dp regarding text size. One thing I don't understand and want some help with is how do I make the text look the same with every possible font size the user has selected for their phone? Is it that bad to use dp for text size? (I know that the app won't take the user's phone font size into consideration but at least it will look the same across the board.) Any advice would be appreciated.
To make the text look the same irrespective of the users' choice, use dp. To change the text size according to users' choice use sp. So, if you have a constraint that the text size should remain the same use dp.
Is not bad at all to use DP as text size. It just won't follow the users preferences regarding text size. We have to use the tools we have, to best fit our needs. I always use DP in elements wich i need to maintain the layout. If you don't want the text size to change, use DP. Some times i use textAutosizing When the text changes. And often i use sp, when dealing with "content" text, wich can grow and scroll, shrink and fit.
In my app, i need to keep an action to change the font size. I am trying to keep three set of values for text sizes (small,medium and large). How should i switch between them? My idea is to use one set of font resource at a time.
For more clarification:
In Theme.AppCompat.DayNight.DarkActionBar, to shift between night mode on and off in i can call
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
and
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
Here, each will use different set of resource values for night mode on and off. I am looking for somewhat such a method to shift between different font sizes. Any help is appreciated.
There's something like that built into the operating system. If you go to Settings > Accessibility you'll find a Large text toggle or a slider to make text bigger (depending on phone). This will work in your app as long as you use sp for your font sizes (for example android:textSize="16sp").
If you're going to use that, you'll have to remember that the setting is in the phone settings, I don't think there's a way for you to change it from your app. And it applies to all the apps, not just to yours, so everything in the system would get bigger. Which might be not what you require.
Otherwise you can try to do this manually in your app. One way would be to create three themes that have your different font sizes. Then you would set an appropriate theme on the context in your Activity.onCreate() based the setting you saved somewhere (in SharedPreference for example).
But I don't think you can just keep different font sizes in different resource subdirectories. The list of resource qualifiers is predefined and I don't think there's something for switching font sizes in there.
I am writing an app about eye test. It is necessary to set the standard text size. I used the following code but it showed what I did not expect.
Typeface type=Typeface.createFromAsset(getAssets(),"Optotypes.ttf");
textView2.setTypeface(type);
textView2.setTextSize(TypedValue.COMPLEX_UNIT_MM,25);
textView2.setText(randomLetter);
I expected the textview show a 2.5cm letter but it is not the exact length/height still.
This situation appear also on different device.
The next problem is that the size is different between the original font and ttf I added. (the original font didn't show the text with 2.5cm also.
Is my code wrong or anything else i missed ? Thanks guys . it is important to me.
I think you're missing how Android handles text sizes.
In Android, you should specify text size in SP units, so Android can scale it accordingly to the user's font size preferences. Never specify hardcoded pixels or centimeters.
Check this references for documentation on the subject:
http://developer.android.com/guide/topics/resources/more-resources.html#Dimension
http://developer.android.com/reference/android/widget/TextView.html#attr_android:textSize
What is the difference between "px", "dp", "dip" and "sp" on Android?
If you want to set the text size in SP programatically, you can do this
// same as android:textSize="15sp" in XML
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
-- EDIT
Keep in mind that by just setting a certain text size it doesn't mean that every letter will be of that size. Remember that there are multiple letters with multiple sizes. For instance, with a size of 20mm, this is what you get
Because Android needs to accommodate every possible character in a textview with the size you provided. That being said, textSize is not 100% accurate to what you provide to it.
If this is not enough for you, please provide more details of the problem you have at hands.
I am working on android application where I am using TextView to display the text on screens.
I am using this property for the TextView to set the size of the text android:textAppearance="?android:attr/textAppearanceMedium".
Do I need to set the size of that text also or it does automatically manage by Android OS ?
Thanks in advance.
Yes, the resizing is done automatically in the background.
While using attributes like android:textAppearance it directly uses the predefined specific sp values for the textSize as:
android:textAppearance="?android:textAppearanceSmall" => 14sp
android:textAppearance="?android:textAppearanceMedium" => 18sp
android:textAppearance="?android:textAppearanceLarge" => 22sp
Thus it adjusts the values automatically based on the screen density and the user's preference in such a way that it seems equal on all the devices say for example formula for dp values:
px = dp * (dpi/160)
The similar case is for the sp values used only for fonts, it utilizes the same concept only difference being it may vary due to user's fontSize preference as set in settings.
I haven't used that :attr/ type as it may or may not be used and serves the same purpose because the system resource tool knows that an attribute resource is expected in this context, you do not need to explicitly state the type.
Do I need to set the size of that text also or it does automatically manage by Android OS ?
Nope, Using android:textAppearance="?android:attr/textAppearanceMedium will make all of the text in medium size on different devices. So that means your app text on different devices will have the same size and weight.
Setting the size of each text would require calculation to be able to achieve same size and weight.
In Android text elements there is a default which is applied first (similar to webpages). If you wish to override those and define your own, then you must explicitly set them. android:textAppearance is one such override, but there are other attributes you can override individually (as opposed to as an aggregate)... you'll want to see the documentation for that.
So we know from many other posts that we should use sp rather than dp for text in Android, and we know the reason for this is to respect a 'user's preferences'.
But precisely what are these preferences?
How might a user change this setting?
I cannot find any reference through the settings on my phone (I would have expected something in 'Accessibility' or 'Display'). So what is a user setting? Is it only done through the likes of an app such as 'Big Font'?
Assuming that it is (set by something like big font) - I have played with Google Docs and some other Google apps with the font set to 130%. While most layout stays fine, some gets a bit cut off and can't be read (and that is on a big screened SGS2). So, what is the approach to developing apps with text sizes using 'sp'? Do we make sure it works on 100% scaling and then ignore other settings - call it a special case that the user can worry about, or do we go out of our way to make sure things expand or are scrollable, in case the text overflows?
One argument is that we should use 'dp' to guarantee a user has a chance of seeing the text (even if they have to use a magnifying glass)
Thoughts/comments?
It is exposed in the settings menu on some Android devices (manufacturer dependent). It may also be altered by some accessibility options (device-dependent).
In general, you should always used scale-independent pixels, especially for a large body of text.
However if your text has to fit into a bounding-box of known size then you should use density independent pixels in order to ensure that the text always fits properly and that all characters are visible regardless of the users' setting.
In a nutshell: would increasing the text-size by around 5sp result in the text being unreadable or mangle your UI? If so use density-independent pixels. If not, use scale-independent pixels. However you should generally aim to use scale-independent pixels wherever possible, which means designing a UI that can accommodate different text sizes.
Using the sp unit is recommended for text because in ICS and above (could be Honeycomb too, correct me if I'm wrong), there is a preference for a user's font size. So, if you're using Gingerbread or lower, you won't be able to find this setting.
The preference is under Settings, Display, Font Size. There's also an option under Settings, Accessibility, Large text, too.
To address your question about how to go about using sp, note that by default, without changing any of the font size preferences, 1sp is equivalent to 1dp (also, they are equivalent before the preference was introduced). Like you've noted, designing for the case where a user has huge text would probably require you to assume things are going to need to scroll where you might otherwise not expect them to.
The answer lies in looking at this particular issue holistically.
The motivation for using "sp" for font sizes lies in giving the developer power to control their layout in the face of user changing the font size on their device.
Example:
Lets look at 2 extreme cases:
1) User selects font size "small"
This is what my layout looks like:
http://postimg.org/image/kiyqeo2bh/
Here is the layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="0"
android:text="Material-Design ist die Scheiße"
android:textSize="18sp"
android:background="#ffff0000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="0"
android:layout_column="0"
android:text="Material-Design ist die Scheiße"
android:textSize="25sp"
android:background="#ffff0000" />
2) If the user selects font size "huge":
This i what my layout looks like:
http://postimg.org/image/d7rax9wob/
My layout xml is same as above in case 1).
So, as you can see what happened here is the top TextView has sort of perfect font-size in sp because it does not wrap for the entirety of the range of font sizes (small to huge). But the bottom TextView completely messes up your layout/design in case 2).
So you as a developer can iterate and decide what size in sp works for your design and android will draw it for you.