I believe you can set layout_width and layout_height to textview element dynamically using something like:
LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
centimeterLayout.addView(textview, lparams);
But - how do I set the layout width and height in other units - e.g. I want to set the layout width of my text view to 20 mm. How do I do that?
LayoutParams either take one of the constants (FILL_PARENT, WRAP_CONTENT) or a pixel value. Since you want to use millimeters, you have to convert a millimeter dimension to a pixel dimension. Doing so is pretty easy:
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 20,
r.getDisplayMetrics());
In this example, 20 mm are converted into a pixel dimension that you can use in your LayoutParams. You can use other dimensions too, such as TypedValue.COMPLEX_UNIT_DIP for dp/dip¹. Just change the constant in the arguments. The android doc has a list of useable dimensions.
¹ Density independend pixels, a highly recommended dimension that adjusts to the many different screen sizes and densities. Using mm isn't the best way to do things, since your text will probably look okay on a big screen and fill a big portion of a small screen, or the other way around - which is not ideal. I also recommend sp for font sizes. See the dimension list for details.
Related
How can I make the font size in a TextView a bit larger or smaller relative to the current font size?
I see many people using hard-coded font size values like 15sp but I'd like to avoid that because I want to be independent of the current font size. Instead, I was thinking of multiplying the font size by 1.2 to make it larger and by 0.8 to make it smaller, e.g. like this:
// make font larger
float size = textView.getTextSize()*1.2;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
Still, I'm wondering if this is the best way to do it because it looks a little awkward. That's why I'd like to ask if there's a more convenient way to make the default TextView a bit larger or smaller without hard-coding values like 15sp...
EDIT
I should add that I'm creating everything programmatically. I'm not using XML. So the TextView is created like this:
TextView tv = new TextView(context);
By doing it like this, tv will use Android's default font settings. Now I want to make the font in tv larger or smaller, programmatically in Java.
sp values are used for text. The SP stands for "scalable pixels". The benefit of using the sp is that it would scale according to the user's preferences.
I would suggest not do any calculations manually. The value that textView.getTextSize() will return will essentially be of a "density-independent pixels" (for textSize will be sp). That value will most probably come from your theme.
Using density-independent pixels is the proper way (or autosizing which still uses dp or sp). What you are trying to achieve will be messy and you will have no idea how it will scale on runtime. Using the "hardcoded" values such as 15sp it won't stop from the text from scaling according to the font size but on the contrary, it will be calculated accordingly. To give you an example, 15sp will translate as such:
For 100% font size:
ldpi 11.25px
mdpi 15.00px
hdpi 22.50px
xhdpi 30.00px
xxhdpi 45.00px
For 75% font size:
ldpi 8.44px
mdpi 11.25px
hdpi 16.88px
xhdpi 22.50px
xxhdpi 33.75px
What you can do is use Autosizing into Textview.
To use auto-sizing you will need to convert your textview from:
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp" />
To:
<TextView android:layout_width="match_parent"
android:layout_height="200dp"
app:autoSizeMaxTextSize="24sp"
app:autoSizeMinTextSize="16sp"
app:autoSizeStepGranularity="1sp"
app:autoSizeTextType="uniform" />
Programmatically:
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
textView,
16, // min
24, // max
1, //granularity step
TypedValue.COMPLEX_UNIT_SP
)
The above means that:
Minimum Text size is 16sp.
Maximum Text size is 24sp.
If the text size is not either of the max or min, then it will scale up or down by 1sp. So all the available values will be 16, 17, 18, 19, 20, 21, 22, 23, 24.
Note: To use AutoSize in TextView, ensure that you don't use wrap_content as it could lead to issues. I would suggest using a hardcoded value or if you are using ConstraintLayout to constraint it with percent, or actual constraints that restrict the size of the view.
Read more:
Support different pixel densities
Autosizing TextViews
Making the most of TextView auto-sizing on Android by Nick Rout
Calculator for DPI
Override attachBaseContext() of (base)activity and set there fontScale
override fun attachBaseContext(newBase: Context?) {
val config = Configuration()
config.setToDefaults();
config.fontScale = Random.nextFloat()*2; // Here Goes scale value for
val context = newBase?.createConfigurationContext(config);
super.attachBaseContext(context);
}
In the example I made it scale randomly every time, you can save somewhere needed scale value and set it here.
btnChangeSize.setOnClickListener {
recreate()
}
Will make this function call and all texts will be scaled as you wanted
I'm quite new with Android so I was wondering if it's a okay to give layout height or width in dp? Also if there is any other approach other than wrap_content/match_parent or dp than do tell. Thanks in advance.
Yes you can specify height and width in dp.
For conversions between px, dip, dp and sp please see stackoverflow question What is the difference between “px”, “dip”, “dp” and “sp”?
For layout I've found "match_parent" to be applicable in most cases. (To give you more context, "match_parent" used to be called "fill_parent" prior to API level 8). It basically means the view is as big as its parent, just without padding.
If your intention is the make the view just big enough for its content, then use "wrap_content".
Yes it is ok to give height & width in dp. You can also use fill_parent at place of match_parent.
Fill_parent was depreciated in API level 8. So if you are using API level 8 or above you must avoid using fill_parent.
For more information see this http://code2care.org/pages/fill_parent-vs-match_parent-vs-wrap_content/
You can give layout height and width in dp. Mostly used for custom size arrangement
Wrap content provides the view size, equal to the content size.
Match parent allows the view to be the same size, as the Relative or Linear layout.
Ofcourse not this is the not a best approach to give height and width in dps instead wrap_content and match_parent properties.
Documentation
The important thing is if you give width and heights in dp it is not in favour of supporting all different size of screens instead wrap_content and match_parent is much more favourable in adaptive designs and responsive designs where views get the provided space according to the need.
dp is defined as:
dp Density-independent Pixels - an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Note: The compiler accepts both "dip" and "dp", though "dp" is more consistent with "sp".
when declaring some element (let's say a Button) and giving it some width and height (let's say 200dp) from the XML file, I got certain result when running, although when make the same steps but Programmatically I got much smaller width and height, and this case happens only with me in Nexus tablets.
If you set the size of a View programmatically, many times pixels are taken as an argument. You will need to convert your desired size in DPs to pixels first, and use those to set the width or height of your element:
float dp = 200;
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
See the API-docs of the specific Views for infos about what kind of dimensions are taken as an argument.
I have an ImageView with matchParent property in width.
how can i know its runtime width on my device (using eclipse, without adding code programmatically)?
how can I know the conversion ratio between dpi to pxls in my device?
I have an ImageView ... how can i know its runtime width on my device
You can get the width when the ImageView is measured, i.e. later than the runtime. However you can get the screen's width and height like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
And if for example your ImageView takes up a specific portion of your screen you can measure it using the screen's width and height.
how can I know the conversion ratio between dpi to pxls in my device?
To convert say 20 pixels to DP do (adding to the above code):
int dp = 20 / metrics.density:
Extra: Here's a dpi to pixel calculator
If you don't want to use the TreeObserverListener way, you can try to get the View to measure itself and give you what the dimensions would be if it were calculated. In my experience, this has worked in most cases but not all; especially if the View is in some special dynamic layout or the ordering of the hierarchy prevents the dimensions from being calculated in the correct order. You might find luck in refering to this popular answer.
I have a button which on start is placed central and 50 pixels from the top of the layout using the following
android:layout_marginTop="50px"
I need to be able to change this margin depending on what background is being displayed to 100 pixels.
any ideas how i change this
There must be a one liner all the answers i can find involve a long layout params method
Any help is greatly appreciated
Mark
Option 1 - Relies on the surrounding/parent layout type, so if the parent layout type is a RelativeLayout, you should use RelativeLayout.LayoutParams instead of LinearLayout.LayoutParams:
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
params.setMargins(0, 100, 0, 0);
myButton.setLayoutParams(params);
//myButton.requestLayout();
Option 2 - Uses a generic method that doesn't rely on the surrounding/parent layout type:
public static void setMargins (View v, int left, int top, int right, int bottom) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(left, top, right, bottom);
v.requestLayout();
}
}
Usage:
setMargins(myButton, 0, 100, 0, 0);
this is for your reference...
i hope it will help full to you...
and the best use is dp supports for all device and its density pixels
px
Pixels - corresponds to actual pixels on the screen.
in
Inches - based on the physical size of the screen.
mm
Millimeters - based on the physical size of the screen.
pt
Points - 1/72 of an inch based on the physical size of the screen.
dp
Density-independent Pixels - an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion. Note: The compiler accepts both "dip" and "dp", though "dp" is more consistent with "sp".
sp
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 user's preference.