Resize text on tablets - android

With the use of weight my layouts are really perfect on every screen size and density. Every view is perfectly scaled.
Unfortunately there is still a big problem with characters size: no matter if I define text size with sp or dp, it still resizes based on density and not on size of the screen, so on tablets text is microtiny!!
What's the best solution for this problem?
Shall I define different layouts for tablets? And in that case, how can I do it?
Is there a way to auto-size the text, in xml or by code (I don't care much which one, if it works)?
Thank you very much.

You can create separate styles for different screen size qualifiers small, normal, large, xlarge, and a bunch of new sw<N>dp, h<N>dp, w<N>dp
Supporting Multiple Screens

Solution 1
use different layouts for different screen size
Solution 2
Use customView and change the text size dynamically. For example
public class CustomView extends TextView{
....................
#Override
protected void onDraw(Canvas canvas) {
calculate the view size and change the text size
}
}
UPDATE
To measure the size you can use following
float size = getHeight() * .8; // getheight will return view's height
setTextSize(TypedValue.COMPLEX_UNIT_PX, size);

You can make use of dimens.xml which you need to create in your values folder and create values folder as values-large values-small values-xlarge etc.....

Related

Text sizes, different density devices and material design

I'm trying my best to follow the material design guidelines when it comes to fonts as I can, but I'm struggling to fix an issue I'm having without using dimens dependant on density. My issue is;
I'm using styles for my fonts so an example of this;
<style name="Text.MyApp.Heading3" parent="TextAppearance.MaterialComponents.Headline3">
<item name="android:fontFamily">?attr/RegularFont</item>
<item name="fontFamily">?attr/RegularFont</item>
<item name="android:textSize">?attr/TextSizeHeadingThree</item>
</style>
And applying this as the style of the text, my font size comes from the material guidelines so for Heading 4 I have
<dimen name="text_size_heading_three">48sp</dimen>
My problem is, I've got a view where there's two numbers using Heading3 in a row on the screen, This may look like +£100.00 | -£200.00, these are constrained to a separator view in the middle.
Where my issue lies is on a Pixel 4 XL (xx-hdpi) this looks fine, but bringing this down onto a Nexus S (hdpi) the text squashes together, overlaps the separator in the centre and comes off the end of the screen slightly.
It was to my understanding of the use of SP is that it would scale this text size which doesn't appear to be happening, a worry also arises that SP takes from the users text size preferences so increasing the text size of the device will likely also break this.
Just short of changing the font size for hdpi to a smaller text size for this text view, is there a way I can make this style scale with the screen?
sp actually scales in regard to the screen pixel density and the selected font size of the system.
The issue you are facing is related to the screen's actual width instead.
To achieve what you want, you can try either of the following two:
Have different sp values for your dimen for each screen width. You can do this by creating additional resource files that would contain your dimen values and will be screen width dependant. You can read more about this here:
https://developer.android.com/training/multiscreen/screensizes#TaskUseSWQuali
Use an autosizing TextView. You can find more information here:
https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview
sp units are literally about the user's choice of text size:
Scale-independent Pixels - This is like the dp unit, but it is also scaled by the user's font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user's preference.
Basically users can choose the general size of text on their device, and that multiplies dp values by a specific factor (Normal is * 1.0, I think Huge is * 2.0) and that's what the sp value is. When you specify sizes in sp, you're allowing the system to scale that text up so it's readable for everyone.
So you need to be mindful of that when designing - it's always worth having an emulator with a small screen (limited space) and the text size set to the largest setting, just to make sure everything still fits in those extreme cases.
You have four options I think:
reduce your font's sp size in the layout, so it always fits
make different layouts for different configs, and tweak that (more work for you)
use autosizing TextViews like #kandrit mentions - set the space you want to fill, and it will scale the text size to fit it (this sounds like what you were expecting, and you can tweak things like having a fixed set of possible sizes)
don't use sp, use dp instead (won't scale according to the user's preference - but above a certain size, it doesn't need to because it will be readable)
You'll get a warning about the last one, but in my opinion it's completely fine and the right thing to do in some cases. Think about an app with a clock in the middle of the screen - it's a fixed size, designed and laid out a certain way, and it's large enough to be easily read. It's meant to look a specific way, take up a specific area of the screen, and there's no need for it to change size - so it makes sense to define it in dp like any other visual element. Maybe that works for what you're doing!
Problem is not with your text size, it is with your layout design
I also had the similar problem I solved it by giving a margin to views which was placed inside constraint layout so in a case of large screen it will use constraints and ignore the value of margin and in case of small screen it use the value of margin to keep views separate
If you are using a Linear Layout then set layout_weight to 1 and give margins to views then it will work same as with constraint layout

Same text size but it larger on other devices

I have a TextView in which I programmatically setup the text size in 'SP'.
tv.setTextSize(spToPx(5, context));
public static int spToPx(float sp, Context context) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());
}
First screenshot shows how it should look (and how it looks on my Xiaomi Redmi and Doogee HT7
Second screenshot shows how it looks on other devices with higher or the same dpi.
Normally, if I understand correct, text with the same size in 'dp' or 'sp' should looks the same on other devices (with the same screen size) because it automatically converts 'dp' or 'sp' to the needed amount of pixels depending on dpi.
After reading Android Developer Guideline about devices with different density I was expecting that text would be smaller if I use the same text size on devices with higher dpi. But now I have a situation that I really don't understand.
If you are using values in sp and the user changes the default text size for his device from Settings--->Display---->TextSize, your TextViews will be affected. If on the other hand you use dp values, then no matter what text size the user sets as default, the TextViews in your app will remain the same. This is ofcourse discouraged by Google as bad practice, since the user should be able to change text sizes but it would be what you are looking for.
So, use (TypedValue.COMPLEX_UNIT_DIP,number of your choosing) instead of (TypedValue.COMPLEX_UNIT_SP, sp)
You can add dimens file to your resources . thats how I do it
heres the link where I got the answer
Try this, Add this property in your xml. It will change textsize based on all phone.
style="#android:style/TextAppearance.DeviceDefault.Medium" /*for normal text */
style="#android:style/TextAppearance.DeviceDefault.Small" /*for small text */
style="#android:style/TextAppearance.DeviceDefault.Large" /*for large text */
Hope your problem will solve.
The primary difference between an sp and a dp is that sp’s preserve a
user's font settings. Users who have larger text settings for
accessibility will see font sizes match their text size preferences.
so you could check the settings of two devices and see if there is a difference between them.
I still didn't find right explanation to this issue. The only theory I have is next:
There are density buckets (120 dpi, 160 dpi, 240 dpi, 320 dpi, 480 dpi, 640 dpi). Screen density of your device will be determinated as the closest bucket. For example, if your device has 401 dpi it will be counted as 480 dpi. So, when I create and add view with size of 20 dp it will convert into more pixels than needed. It the hardest for devices that have density right between two buckets. I also checked density of all devices that had wrong image display (like on image 2) and it was almost right between two buckets...
I still don't know why this happens only when I create and add view dynamycally, but the only way to solve this problem was the creating of separate layout with all presetted views instead of adding these views dynamically.

How to get same textSize across Android devices?

I my Android app I have a TextView with a width of 50% of the screen width, and a height of 10% of the screen height. I've set the textSize to 44sp, but on big devices (screen size) it renders the text too small, and too big on small devices. How can I solve this?
use folder like for dimens.xml file
values
values-sw600dp
values-sw720dp
I suggest you set both width and height of your TextView to wrap_content and use sp for your text size.
Setting your text size to 44sp with wrap_content should work pretty well for most devices.
If you still need to adjust certain devices (densities) you can extract your text size into its own dimen resource and override its value for default configurations, like shown here

larger imageview for large screen size

If I have an image that I want it to be medium on android medium screen and large on large screens. I know I have to put layouts in 2 different folders: medium and large layout.
But my question is, should I use one image (say the medium size) and stretch it for the alrge screen by putting min width, min hight and fitscaleXY.
OR
Should I create 2 images, one for medium sized screen and larger version for large screen?
Thanks
EDIT:
Really no answer yet to this? I am sure this is something people would do all the time. You want the image to be larger on large screens, how do I go about it? I was thinking of specifying width and hight for each screen layout size instead of wrap content.. You agree?
You dont have to make different layout xml files for each screen size, unless they really need a different layout, like how things are organised.
In Android you must specify the sizes in dp, and textsizes in sp, which is an equivalent to pixels, only they will be scaled automatically based on the screen density.
Measurement Units.
If you specify some size in dp, it may show up on a large device at for example 300 pixels, and on a smaller device 200 pixels (just an example).
I would Definatedly not hardcode the sizes per screen, since there are a lot of different screens around.

Android: Canvas.drawText() text size on different screen resolutions

For my Android game I have some calls to Canvas.drawText().
For testing, I use the standard font size which seems to be working fine.
However, when I bump up the resolution to a higher density, the larger images are automatically loaded but the text is now incredibly small.
Is there an easy way to calculate what size the text should be drawn at or am I bound to do this manually?
edit: What was the point of editing my post #Suragch ?
The easiest way is to define your font sizes in your resources with the units of scale-independent pixels (sp) -- this unit is like density independent pixels (dp or dip) in that it takes into account the screen density but it also takes into account the font-size setting of the user.
To add a new dimension create a dimens.xml file in your res/values folder and enter the following code to add a new dimension with the name myFontSize:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="myFontSize">20sp</dimen>
</resources>
You can then get the text size in your application using
int scaledSize = getResources().getDimensionPixelSize(R.dimen.myFontSize);
The resulting size will be correctly scaled to take into account the current screen density and font-size setting.
For more information see the Android Developers page on More Resources.
You can do it yourself using a simple math operation:
You need to calculate a relation that draws your text just the same size for any canvas size, so use the actual canvas size, like this:
double relation = Math.sqrt(canvas.getWidth() * canvas.getHeight());
But that number is just too big, so divide it by one that suits your needs, lets say 250:
relation = relation / 250;
Now you can set your text size like this:
paint.setTextSize((float) (myFontSize * relation));
You don't have to necessary divide relation by any number but in that case you will have to use very small font sizes for the variable myFontSize. For me 250 works just fine to use regular font sizes that will adjust to any screen size, since you are already taking in count the pixels dimension from your canvas.
The easiest way is to define your font size in your resources directory with the units of scale-independent pixel (sp) or the density-independent pixel (dp). Then get the text size using
int scaledSize = getResources().getDimensionPixelSize(R.dimen.font_size);
mTextView.setTextSize(scaledSize);
This will scale the text-size appropriately according to the current screen density/resolution and the user's font-size setting.
How to define font size in resource directory?
Create a file named dimens.xml in the folder res->values. Then copy the following code.
<resources>
<dimen name="font_size">25sp</dimen> // sp or dp accordingly
</resources>
The name attribute of the tag <dimen> will be used as resource ID.
When calling Canvas.drawText() the text size is first determined by the passed in Paint object, which can be set via Paint.setTextSize(). The text size is automatically scaled by Canvas based on the canvas density, which can be found using Canvas.getDensity().
When setting the text size on a paint object that will be drawn on Canvas, work with a unit value of dp or sp and let Canvas handle the scaling for you.

Categories

Resources