How do smallest width for layouts work with this example? - android

I have read the officel documentation but still dosn't understand it!
I'm playing and experimenting with the smallest-width layouts in Android and it dosn't give any sense to me.
I have created these layouts: sw-300dp/350dp/360dp/400dp/450dp/500dp/
But my Galaxy S7 use the sw-360dp layout. But 360dp is far from any of the numbers provedid by getDisplayMetrics(); or the numbers of the screen I got from GSMArena. So why do Galaxy S7 use 360dp and not 500dp since the xdpi is 580dp and closer to 500dp?
Test Phone: Samsung Galaxy S7
Screen Size: 5.1"
Resolution: 1440x 2560 (577 ppi)
From det Logcat I retrived the following screen values of the phone:
getDisplayMetrics().densityDpi: 640
getDisplayMetrics().xdpi: 580
getDisplayMetrics().ydpi: 575:
getDisplayMetrics().widthPixels: 1440

The density of the screen on the S7 is 4.0
That means that there are 4 pixels per dp, therefore the screen is 1440 / 4 = 360dp wide.
I use the following methods frequently:
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

Related

Android dp units not matching up to real world

I'm testing on a Samsung Galaxy Note 3 which according to the docs is 1080 x 1920 pixels (~386 ppi pixel density). I want to figure out what the screen width in dp is so I can properly apply and check the new size qualifiers.
I've measured the screen width (in portrait) with a good 'ole ruler = 71mm = 2.8 inches
1080 / 2.8 = 386 ppi. Great, this matches the stated density.
I'm trying to figure out how many dp units the screen is wide.
dp = px / (dpi / 160) from here
= 1080 / (386 / 160) = 1080 /
2.4125 = 447.7 dp
So if I do this:
<TextView
android:id="#+id/density_test"
android:layout_width="447dp"
android:layout_height="wrap_content"
android:background="#ffff0000"
android:text="DENSITY TEST 447dp" />
then on my Galaxy Note 3 this view should be almost exactly the width of the screen. But it isn't, it's way wider.
So I set the above view to layout_width="300dp", measured how wide it was with my ruler and extrapolated the actual screen width in dp, based on this test:
300dp = 59mm
Total screen width is 71mm
so extrapolating screen width in dp = (71 / 59) * 300 = 361dp
361dp != 447.7dp
What is going on here? I feel like I must be doing something dumb.
Edit: I tried putting the layout file inside /res/layout-xhdpi but it had no effect. I thought maybe it was scaling it by xhdpi / mdpi since I had the xml in the default /res/layout dir.
The actual pixel size is calculated based on dp, but not as accurate as the formula dp = px / (dpi / 160) does. Indeed, it first determines the screen density (ldpp, mdph, hdpi, xhdpi, xxhdpi, xxxhdpi) and using that density to get one ratio from {0.75, 1.0, 1.5, 2.0, 3.0, (4.0)}.
In you case, the system deems 386dpi as xxhdpi, so it calculates the value by multiplying 3.0, and 360dp would exactly fill the width of your screen (1080p)

Conversion from px to dp for Google nexus 7

I am new to tablet application development. I am having Google Nexus7 with screen resolution (600 * 960 dip) So I want to know is it fall in to mdip category?
According to that 1px = 1dp (baseline). But If I follow this its not looks good on tablet. I am creating separate layout folder for nexus7 -sw600dp and mention sizes according to mdip but it not working. My images also not looking good. What I want to know what is actual conversion rate for google nexus 7. Need help.
Formula: pixels = dips * (density / 160)
The Nexus 7 is 800x1280 with a 213 px density, which means it's resolution code is tvdpi (which means you can have a folder called drawable-tvdpi).
You can measure available screen size, minus window decorations, with:
this.getResources().getConfiguration().screenWidthDp;
this.getResources().getConfiguration().screenHeightDp;
On my N7, it returns 600 dp w, 888 dp h. Following the above formula, 888 dp height is 1280px - window decoration.
The Nexus7 is a unique device, with a somewhat strange dpi structure.
For nexus 7
layout-large-hdpi
Here is a very good explanation (from Dianne Hackborn - an Android engineer at Google): Dianne Hackborn explains the unique resolution of the Nexus7
Note: The app takes images from these folders only if you have not given higher precedence qualifiers. For example if you have given a layout folder like layout-sw360dp the app will take only the images from this folder even if you have given separate layouts like the one I said above. Because in android there is an order of precedence in which you have to give layouts.
Screen Density
Commonly referred to as dpi (dots per inch). Android groups all actual screen densities into four generalized densities: low (120), medium (160), high (240), and extra high (320). A device such as Galaxy Nexus has "extra high" screen density (more specifically, the dpi value is set at 320). The Nexus 7 uses "tvdpi" - i.e. 213 dpi.
Density Independent Pixel
Commonly referred to as dp. This is the virtual pixel unit used when displaying content. The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen. To calculate dp use the following formula:
px = dp * (dpi / 160)
or equivalently:
dp = (px / dpi) * 160
The reason Nexus 7 can show more content than the Galaxy Nexus despite having similar resolutions is this: the dpi of Nexus 7 is lower than Galaxy Nexus.
Galaxy Nexus (320 dpi, 720 pixels wide)
(720 / 320) * 160 = 360 dp
Nexus 7 (213 dpi, 800 pixels wide)
(800 / 213) * 160 = 600 dp
This means that when apps are rendering on the Galaxy Nexus, the width of the screen is actually 360 dp (rendered using 720 pixels). Whereas on the Nexus 7, the width of the screen is 600 dp (rendered using 800 pixels).
Try below code, give pixel value to below method it will give you result in dp.
public int convertSizeToDeviceDependent(int value) {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
return ((dm.densityDpi * value) / 160);
}

Bitmap size difference for devices with same density, inches and resolution

I have two tablet devices:
1) Asus Memo Pad 172V tablet
Specs given online as: 600 * 1024 pixels, 7.0 inches (~170 ppi pixel density) LINK
Specs through code: 1024 * 552 pixels, 7.0 inches (160 ppi pixel density)
2) MID 7510 tablet
Specs given online as: 800 * 480 pixels, 7.0 inches (no density mentioned anywhere) LINK
Specs through code: 1024 * 552 pixels, 7.0 inches (160 ppi pixel density)
My problem is:
- Both the tablets have the same density and resolutions (by code), so how can I distinguish between them in order to set the bitmap height (width is coming correct for both) as in case of MID7510, the bitmap height is extended slight down.
- Is there any other factors that are responsible for causing different bitmap sizes for both
tablets ?
- Why are specs coming different by code and are given different online ?
Code to get density and resolution:
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
// Display device dpi (density) value in pixels
int screenDPIy = (int)dm.ydpi;
I'll try to answer to each question but I'll start by the more important one:
- Why are specs coming different by code and are given different online?
Because you find online what material is used for the device, its usually the correct values. You find by code specifications that are set up by the constructor when they are building their android version for their devices. Meaning : it can be false! especially for devices from unknown constructor or Chinese low cost such as 'weisung'.
Given that, answers for the other questions:
- Is there any other factors that are responsible for causing different bitmap sizes for both
tablets?
I dont think so, they have got different screen size and density but system think they are the same... it explain the difference on the final bitmap size.
- How can I distinguish between them?
Definitively not from the screen specifications. If you really need to manage 'weisung' devices you can always check for manufacturer in the device configuration by code. (Assuming they have correctly set up their identification in the manufacturer field XD)
Check the constant value : android.os.Build.MANUFACTURER
I'm really interested to know more in this topic too so any more information is welcome.
The chart was on drawable-hdpi folder.
I was doing simply this:
img.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
The height was not proper in MID 7510 doing so.
Setting height like this worked for both the tablets:
static int imgHeight = 0;
Drawable d = (BitmapDrawable) getResources().getDrawable(R.drawable.chart);
imgHeight = d.getIntrinsicHeight();
final ImageView img = new ImageView(getActivity());
img.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (imgHeight * 1.5)));
This is because 1 hdpi= 1.5 mdpi. So total height should be 1.5 times of image height.

How to change UI widget dimension from iPhone 4 Retina to Android

Expected Result
I have a some UI widgets whose dimensions are design for iPhone 4 Retina device. The unit is in pixels, e.g. a button with 30 pixels wide by 30 pixels high. I wanna copy the design style into Android devices, say the previous 30 by 30 button, takes 30/640 = 4.6875% of the screen width in iPhone 4 Retina and 30/960 = 9.375% of the screen height, then I expect it also takes 4.6875% of the Android device screen width, 9.375% of the screen height.
Problem
Don't know the size scale factor of iPhone 4 Retina device which is used in the following code.
Code
/**
* Change dip value to pixel value using density of current device
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
Log.d("ch", "density of current device : " + scale);
return (int) (dpValue * scale + 0.5f);
}
/**
* Change pixel value to dip value using density of current device
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
Log.d("congliu", "density of current device : " + scale);
return (int) (pxValue / scale + 0.5f);
}
Reference
iPhone 4 Retina
ppi : 326
resolution : 640 by 960 pixels
size scale factor : Unknown
Samsung Galaxy S
ppi : 233
resolution : 480 by 800 pixels
size scale factor : 1.5
Samsung Galaxy Note
ppi : 285
resolution : 800 by 1280 pixels
size scale factor : 2.0
There are several perspectives you should consider.
But i just following a simple way:
px -> dp
My image resources are located in xhdpi folder, using images for retina iphone.
Suppose you have a pixel value in ios, for example, 10,
if you want to get pixel value for your android device:
DisplayMetrics dm = new DisplayMetrics();
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(dm);
SCREEN_DENSITY = dm.density;
SCREEN_WIDTH_DP = (int) (SCREEN_WIDTH_PIXELS / dm.density);
public static int getScaledWidthPixelsByDP(int desingDP) {
double v = desingDP / 320f * SCREEN_WIDTH_PIXELS;
return (int) v;
}
Assuming that iPhone 4 Retina version's size scale factor is 2.0 (xhdpi in Android), I did a very simple workaround by just give those pixels value a half of it with dp unit. So 30px by 30px button turns to be 15dp by 15dp in xml file. Looks good and works on Google Nexus, Samsung Galaxy S, S2, S4, Note, Note2. The dp2px and px2dp methods are not used.

Trying to define which layout should a device use

I'm trying to understand which layout uses which device.
For instance, I've different layouts:
layout
layout-sw600dp
layout-sw720dp
Nexus 7" (800x1280) uses layout-sw600dp
Samsung GTp3100 7" (600x1.024) uses layout-sw600dp
Samsung Tab 10.1 (1280x800) uses layout-sw720dp
Sony XPERIA S 4.3 (1280x720) uses layout
Can you guys explain "with your words" why isn't XPERIA S using sw600dp or sw720dp?
SW != smallest width? So smallest with from XPERIA S is 720. It should be using sw720 or sw600, right? Or am I wrong?
I've read tons of documentation, but can't understand why is this happening.
Thanks a lot.
The Smallest-Width qualifier refers primarily to screen size and not the physical pixels.
Using sw720dp for example means the device must have a minimum screen width of 720 dp (device-independent pixels) - this isn't about 720 physical pixels. From the documentation...
The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a "medium" density screen.
The physical width of the Sony XPERIA S 4.3 is 2.5" but I don't know how much of that is the actual width of the screen.
Let us pretend for the sake of calculations that the screen covers the full width...in this case to calculate dpi for width we simply use 720 / 2.5 = 288dpi.
From the documentation for dp...
The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160).
Rearranging the formula above to calculate dp we do this...
dp = px / (dpi / 160)
...this gives us the width in dp (and a necessary Smallest-width qualifier) of...
720 / (288 / 160) = 400dp
In short the answer is, the Sony XPERIA S 4.3 may have a high-density screen (for its size) but it isn't a large screen.

Categories

Resources