eg:- Samsung Galaxy S III (1280 x 720) and Samsung Galaxy S 4 (1920 x 1080) uses resources from xhdpi. I'm hvaing 3 icons in a row aligned left, centre and right with size of (256 x 256) but it gets overlapped on SIII and on s4 their is a wide gap between icons.
What should be the size of icon to fit it as 1/3 of screen's width or is there any workaround to do so?
here is sample snapshot of layout after following mentioned solutions.
http://postimg.org/image/97aabr2wd/
its getting scaled properly but leaves space on top and bottom. I want result similar to snapshot in this image http://postimg.org/image/r6ico4vil/
where 1, 2 and 3 should be of same height. Its just a space after 3 consecutive red, green and blue images. how to achieve this? thanks in advance.
The samsung Galaxy S4 is XXHDPI, and not XHDPI.
Here is a way to check for the device density :
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int density = dm.densityDpi;
switch(density)
{
case DisplayMetrics.DENSITY_LOW:
Toast.makeText(context, "ldpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_MEDIUM:
Toast.makeText(context, "mdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_HIGH:
Toast.makeText(context, "hdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_XHIGH:
Toast.makeText(context, "xhdpi", Toast.LENGTH_SHORT).show();
break;
case DisplayMetrics.DENSITY_XXHIGH:
Toast.makeText(context, "xxhdpi", Toast.LENGTH_SHORT).show();
break;
}
I took if from this answer.
About having 3 images filling the whole screen width you can use a linear layout with layout weight.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="9" >
<ImageView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="3" />
<ImageView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="3" />
<ImageView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="3" />
</LinearLayout>
In android-
px = dp * (dpi / 160)
1.So in your first question 960dp x 720dp at 320dpi means 1920px x 1440px for xlarge screen in landscape mode using above formula.
2.640dp x 480dp at 240dpi means 960px x 720px for large screen in landscape mode.
enter link description here
You can't guaranty a 1/3 of the screen with just an image. even if two devices have the same dpi (or XHdpi) it doesn't mean they have the same size.
The only way to do that is with code or in the layout xml.
Try use wights.
android:layout_width="0dp"
android:layout_weight="0.33"
with this code you guaranty that the view will be a 1/3 of the screen if width.
Related
I have an activity with three rectangle CardViews. I have set the size constraints such that they change according to the screen resolution.
Please view my constraints here.
The problem is that the CardViews are not changing their size proportionally. For example, when I run my application on a Nexus 5 (1080 x 1920), the bottom component gets cut in half, where as if I run on a Pixel (also 1080 x 1920), the bottom component is the desired size.
Although I will try to make the post as clear as possible, the pictures definitely help understand the problem I am facing, so please view them.
..
Why is the bottom component changing so drastically when the screen sizes are very similar? How can I modify the components so that they are the desired size for these different screen sizes?
I know that you are able to create small, normal, large, and xlarge layouts, and I have but I don't think this is what the problem is.
Code for the 3 CardViews:
Top left
<android.support.v7.widget.CardView
android:id="#+id/capture_receipt_cardview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="#dimen/margin_width_normal"
android:layout_marginEnd="#dimen/button_gap_normal"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
app:layout_constraintBottom_toBottomOf="#+id/create_invoice_cardview"
app:layout_constraintEnd_toStartOf="#+id/create_invoice_cardview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/create_invoice_cardview">
</android.support.v7.widget.CardView>
Top Right:
<android.support.v7.widget.CardView
android:id="#+id/create_invoice_cardview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="#dimen/button_gap_normal"
android:layout_marginTop="185dp"
android:layout_marginEnd="#dimen/margin_width_normal"
android:layout_marginBottom="#dimen/button_gap_normal"
app:layout_constraintBottom_toTopOf="#+id/add_single_cardview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/capture_receipt_cardview"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.CardView>
Bottom Horizontal:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/add_single_cardview"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="400dp"
android:layout_marginBottom="68dp"
app:layout_constraintBottom_toTopOf="#+id/navigation"
app:layout_constraintEnd_toEndOf="#+id/create_invoice_cardview"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="#+id/capture_receipt_cardview"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:layout_constraintVertical_weight="0">
</android.support.v7.widget.CardView>
What you are experiencing is brought by the difference in the idea of screen resolution vs pixel density. As mentioned here:
The pixel density is the number of pixels within a physical area of the screen and is referred to as dpi (dots per inch). This is different from the resolution, which is the total number of pixels on a screen.
In your case, Pixel has higher pixel density compared to that of Nexus 5.
To show you the difference, take this formula:
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Given your android:layout_marginBottom="68dp"
Number of pixels in your Nexus 5 phone:
102 = 68 * (240 / 160); // I am assuming the DPI is HIGH
Number of pixels in your Pixel phone:
136 = 68 * (320 / 160); // I am assuming the DPI is XHIGH
Understanding this concept can go a long way in your Android programming career.
I am using Picasso to load the background images and I am using relative layout. The background images are taking time to load and some are even not loading. My piece of code is,
final int k = random.nextInt(20);
ImageView imageView= (ImageView)findViewById(R.id.backgrd);
TypedArray imgb = getResources().obtainTypedArray(R.array.backg);
int resourceId = imgb.getResourceId(k, 0);
Picasso.with(getApplicationContext()).
load(resourceId).
fit().
noPlaceholder().
into(imageView);
I tried to use resize() Picasso Taking time to load images also, but it is not working.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative1"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/backgrd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
/>
<ImageView
android:id="#+id/img1"
android:paddingTop="90dp"
android:layout_width="wrap_content"
android:layout_height="400dp"
/>
Check size and resolution of image drawable you are using to load.
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
Generalised Dpi values for screens:
ldpi Resources for low-density (ldpi) screens (~120dpi)
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
Therefore generalised size of your resources (assuming they are full screen):
ldpi
Vertical = 426 * 120 / 160 = 319.5px
Horizontal = 320 * 120 / 160 = 240px
mdpi
Vertical = 470 * 160 / 160 = 470px
Horizontal = 320 * 160 / 160 = 320px
hdpi
Vertical = 640 * 240 / 160 = 960px
Horizontal = 480 * 240 / 160 = 720px
xhdpi
Vertical = 960 * 320 / 160 = 1920px
Horizontal = 720 * 320 / 160 = 1440px
px = dp*dpi/160
https://stackoverflow.com/a/16352208/5567283
From your above comment it is clear that you are using Picasso to load the images and your images are stored locally
So according to above scenario here is the solution
First of all stop using Picasso, b'se when ever the images are local there is no need to use 3rd party library to load them.
Second, in your code instead to Relative Layout use CardView as Main layout Like --
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/VechicleCardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="#dimen/margin_small_five"
app:cardElevation="#dimen/card_elevation_two"
app:cardUseCompatPadding="true">
</android.support.v7.widget.CardView>
After cardview put your imageVIew "#+id/backgrd" as the first child as below
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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="200dp"
app:cardCornerRadius="4dp"
app:cardElevation="0dp"
app:cardMaxElevation="0dp">
<ImageView
android:src="#drawable/your_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
<... your layout
.../>
</android.support.v7.widget.CardView>
Now set the Background of the imageView from the Class file
Hope this work for u !!
Happy Coding ;)
I am having an image in imageview of size 5.64mm.
As android having different resolution,image is varying for different devices.
In my case image should not vary at any device.
please help me with some code for drawing the image or setting the imageview Fixed size.
you have to create the same image for different resolutions and put those images in the hdpi,xhdpi etc folders.
Lets assume your image is 100 x 100 in pixel size, so a device with 320 x 480 pixel will show it big but a device with 1280 x 800 will display your picture smaller.
In other words the more pixels a device has in its per square inch space the smaller space your icon will take.
so you have to create multiple versions of your image so that it size remains relatively same.
Do this way. Use dp unit to specify height and width.
<ImageView
android:id="#+id/ImageThumb"
android:layout_width="55dp"
android:layout_height="60dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="10dp"
android:background="#color/icms_white"
android:padding="1dp"
android:scaleType="fitXY" />
use
android:layout_width="5.64mm"
android:layout_width="6.15mm"
I am developing a program on android version2.2. I have read many documentation on supporting multiple screen sizes but still confused. I designed a layout file, that supports for large and normal screens, when am trying it with small screen it is not adjusting the layout to fit the screen. I used this code in the manifest also.
<supports-screens
android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true"
/>
The image for the small screen is here.
How can I set the screen that compatible with small screen? Somewhere I found by using the folder "layout-small" but if I use this, the project size is increasing, I don't want that, so can any one suggest me the best way to do this?
Solution for all screen and support all layout.
Icons:
mdpi hdpi xhdpi xxhdpi xxxhdpi
Launcher Icons (App Icons) 48 x 48 72 x 72 96 x 96 144 x 144 192 x 192
Action Bar,Toolbar,Tab Icons 24 x 24 36 x 36 48 x 48 72 x 72 96 x 96
Notification Icons 24 x 24 36 x 36 48 x 48 72 x 72 96 x 96
Background Image Resolution:
ldpi: Portrait: 240 X 320px. Landscape: 320 X 240px.
mdpi: Portrait: 320 X 480px. Landscape: 480 X 320px.
hdpi: Portrait: 480 X 800px. Landscape: 800 X 480px.
xhdpi: Portrait: 640 X 960px. Landscape: 960 X 640px.
xxhdpi: Portrait: 960 X 1600px. Landscape: 1600 X 960px.
xxxhdpi: Portrait: 1280 X 1920px. Landscape: 1920 X 1280px.
Drawable Folder:
res/drawable (default)
res/drawable-ldpi/ (240x320 and nearer resolution)
res/drawable-mdpi/ (320x480 and nearer resolution)
res/drawable-hdpi/ (480x800, 540x960 and nearer resolution)
res/drawable-xhdpi/ (720x1280 - Samsung S3, Micromax Canvas HD etc)
res/drawable-xxhdpi/ (1080x1920 - Samsung S4, HTC one, Nexus 5, etc)
res/drawable-xxxhdpi/ (1440X2560 - Nexus 6,Samsung S6edge).
ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
Layout:
Portrait:
res/layout/main_activity.xml # For handsets (smaller than 600dp available width)
res/layout-large/main_activity.xml # For small tablets (640dp x 480dp and bigger)
res/layout-xlarge/main_activity.xml # For large tablets (960dp x 720dp and bigger)
res/layout-w600dp/main_activity.xml # For 7” tablets or any screen with 600dp
# available width (possibly landscape handsets)
Landscape:
res/layout-land/main_activity.xml # For handsets in landscape
res/layout-sw600dp-land/main_activity.xml # For 7” tablets in landscape
Refer links:
Different resolution support android
https://developer.android.com/guide/practices/screens_support.html
https://design.google.com/devices/
Is there a list of screen resolutions for all Android based phones and tablets?
http://www.emirweb.com/ScreenDeviceStatistics.php
Most popular screen sizes/resolutions on Android phones
Please go through the following links. These might help you:
Supporting Different Screen Sizes
Supporting Multiple Screens
Supporting Different Densities
Supporting Tablets and Handsets
AFAIK, the only way to support all screens is by doing that folder bifurcation. Every XML file goes up to a few kilo bytes. So, size shouldn't be too much of an issue as such.
Yes i have got the cure to your problem, you are right i personally think that making layouts for every screen resolution is time taking and making your project size go big.
To make a layout that fits across all screen resolution i have implemented my own technique i.e setting width and height in terms of percentage
The Problem occurs when we set Views/Layouts with some constant width or height value lets say 100dp.
Solution is quite simple try to use match_parent so that the view fill up empty space or use weight and define every View relative to other Views this will help your layout to look good in almost every screen resolutions and at run time set LayoutParams of only those Views/Layouts that has some constant width or height in terms of Percentage.
<?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" >
<LinearLayout
android:id="#+id/mLayout"
android:layout_width="280px"
android:layout_height="300px" />
</RelativeLayout>
Notice: I have used px for fixed sized layout's width/height because in LayoutParams layoutParams = new LayoutParams(int width, int height); the width and height take value as pixels
Here is an example code
final ViewTreeObserver mLayoutObserver = mLayout.getViewTreeObserver();
mLayoutObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
DisplayMetrics metrics = getResources().getDisplayMetrics();
int deviceWidth = metrics.widthPixels;
int deviceHeight = metrics.heightPixels;
float widthInPercentage = ( (float) 280 / 320 ) * 100; // 280 is the width of my LinearLayout and 320 is device screen width as i know my current device resolution are 320 x 480 so i'm calculating how much space (in percentage my layout is covering so that it should cover same area (in percentage) on any other device having different resolution
float heightInPercentage = ( (float) 300 / 480 ) * 100; // same procedure 300 is the height of the LinearLayout and i'm converting it into percentage
int mLayoutWidth = (int) ( (widthInPercentage * deviceWidth) / 100 );
int mLayoutHeight = (int) ( (heightInPercentage * deviceHeight) / 100 );
LayoutParams layoutParams = new LayoutParams(mLayoutWidth, mLayoutHeight);
mLayout.setLayoutParams(layoutParams);
}
});
I guess the code is pretty much self explanatory if any one still need help you can ask right away
Conclusion: If you need to set some constant width/height for your Views/Layouts always set value in px in layout file (i.e xml) and then programmatically set LayoutParams.
Suggestion: I think Google Android Guys should seriously think of replacing the dp/dip units to percentage.
Now to support different screen size is more easy! Use new size unit SDP.
SDP - a scalable size unit
An android SDK that provides a new size unit - sdp (scalable dp). This size unit scales with the screen size. It can help Android developers with supporting multiple screens.
for text views please refer to ssp which is based on the sp size unit for texts.
https://github.com/intuit/sdp
Scalable DP (sdp) is the best solution to use. It will resize the widgets depends on the screen size. We can also apply this for text for different text sizes.
To add sdp to your project (Using Android Studio and Gradle):
add implementation 'com.intuit.sdp:sdp-android:1.0.5' to your build.gradle dependencies block.
for example:
dependencies {'com.intuit.sdp:sdp-android:1.0.5' }
try this one
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/myimage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
Try this library is awesome
implementation 'com.intuit.ssp:ssp-android:1.0.6'
Example
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sign up"
android:textSize="#dimen/_16ssp" />
I'm not sure that the solution but I want sharing with you will work everywhere, it covers most of the area.
I've solve this problem by partitioning a screen by used LinearLayout and define its orientation (horizontal or vertical), layout_weightsum = 3 (3 is to divide a screen into 3 parts).
Then inside that Root Linear layout, I again take LinearLayout with layout_height = "0dp" (if you want vertical partition only otherwise layout_height = "wrap_content" and if you need horizontal then make layout_width = "0dp" and layout_weight =1 (1 is for 1 part of the screen you can also put the value in float like 1.2).
Can try this it helps me, maybe and hope will help you.
I have a banner which is 320dp wide but it is filling the entire width of a 480x800 android emulator.
Here is the XML for the banner:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/add_banner"
android:layout_width="320dip"
android:layout_height="50dip"
>
<ImageView android:id="#+id/add_image"
android:layout_width="320dip"
android:layout_height="50dip"
android:src="#drawable/your_ad_here"
/>
<Button android:id="#+id/btn_addclose"
android:layout_width="25dip"
android:layout_height="25dip"
android:gravity="center"
android:layout_alignTop="#id/add_image"
android:layout_alignRight="#id/add_image"
android:text="x"
/>
</RelativeLayout>
I have included it in my main.xml file as :
<include android:id="#+id/add_banner"
layout="#layout/tlp_add_banner"
android:layout_width="320dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
To make sure that my emulator is 480x800, I even logged the metrics on runtime. It is 480x800. Then why is the banner taking up the entire width?
dip means density-independent pixels. Your 480x800 emulator is most probably HDPI (high density, or high dots per inch), which means that 320dp will translate to 320*1.5 actual pixels (which is 480). Only on an MDPI (medium density) screen, where the scale factor is 1 will you actually get 320 pixels.
You can get the scale factor for the current screen like this:
float scale = getResuorces().getDisplayMetrics().density;
If you really want it to be 320 pixels wide, regardless of the screen density (this is not recommended at all), you can just specify:
android:layout_width="320px"
dip aren't physical pixels but a made up number that depends on the display density. More info here:
http://developer.android.com/guide/practices/screens_support.html