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 ;)
Related
I have two images I want to display within my app.
The first image is to be full screen (as a background for the app). I have read the 'Supporting Multiple Screens' article on developers.android.com multiple times but, I am still at a loss as to what size the image should be for each dpi category. I have attempted what I thought to be the correct sizes but, when viewing the app on larger screens (ie. 1280x800#mdpi), I find that the background appears pixelated. This is understandable since my image for mpdi is 320x480px. How can I correct this? What size image should I use?
The second image is a button. Currently I have the image at a very high resolution but, the app scales this down so it looks fine. However, I do not wish for it to be this way when the app is released. For this image, I need to know what size in pixels the image should be. Currently, it is 60dp x 50dp within the app. What would this convert to in pixels? I know to use the formula px = dp * (dpi / 160) but, what would the dpi be in this case? I cannot use a NinePatch PNG for this image.
I do not understand what size (in pixels) to make my images to begin with so that they appear correctly on Android devices. Does dp = px if you are on a mdpi device?
UPDATE:
After hours of banging my head around, I have came up with the following:
drawable-xlarge-xhdpi 2560x1920px
drawable-large-xhdpi 1920x1440px
drawable-normal-xhdpi 1280x960px
drawable-xlarge-hdpi 1920x1440px
drawable-large-hdpi 1440x1080px
drawable-normal-hdpi 960x720px
drawable-xlarge-mdpi 1280x960px
drawable-large-mdpi 960x720px
drawable-normal-mdpi 640x480px
drawable-xlarge-ldpi 960x720px
drawable-large-ldpi 720x540px
drawable-normal-ldpi 480x360px
These will be my drawable directories and the maximum resolution I expect for each one (I've decided not to support small screens). Therefore, my images will be these sizes.
It looks great on my phone. I see no artifacts. It also appears to work on the emulator for a screen with 1280x800#mpdi so hopefully it will work on all devices...
Does anyone see a problem with doing it this way? Is there a better way to do this? Do my calculations look correct?
here you go, i got it off here, im just passing it along
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
Use method in JRowan's answer and you can add desired images for "special" screens to res folders like here:
res/drawable-xlarge-mdpi/background.png
or
res/drawable-sw600dp-mdpi/background.png
...
I'm building an app with one image file that is used throughout the apps views. I'm a little confused about the information in android.developers in regards to scaling images to the different screen densities in Android: ldpi = 0.75; mdpi = 1.0; hdpi = 1.5; xhdpi = 2.0.
My first thought was that all I had to do was insert the image file to the appropriate density files, and Android would take care of the scaling thereafter; but I don't feel this is correct. My question is:
If I'm wrong, and I have to scale the image to the appropriate densities myself, and then save them to the different density files, how would I do this? Would I be able to do this in Photoshop? I'm thinking yes, but I'm not sure. If so, how would I scale an image? Thanks for any help!
Here you go, this might help, I got it off of here, it comes in handy sometimes:
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
Formula used:
px = dp*dpi/160
If you want to let Android scale (which I don't recommend) you can simply place one image only in the appropriate density folder (preferably the highest you support -- xhdpi probably for now) and Android will scale it.
Preferably yes, you should rescale them beforehand in Photoshop/GIMP/editor of choice.
1st Image: Default Normal Screen
2nd Image: Galaxy Nexus 4.65" (Eventhough it looks larger, it is under normal screen)
3rd Image: Large Screen
how to design for particular screen size? I mean both 1st and 2nd image comes under 'normal screen'. Suppose If I create new layout folder for Galaxy Nexus (4.65",720x1280) and i was working on it, it affects default layout folder.
if above solution does not work.try this ,it will surely work ,i have tested this. if you want your app work on different different version of OS.
Use these three layout's.
For
tablet>3.2 and up verion
1-layout-sw600dp
For
tablet<3.2 and lower version
1-layout-xlarge
For
Smart phone
1-layout
Here's my general guide on how to design for different screens:
https://stackoverflow.com/a/12739568/1369222
If you are looking to target only the samsung galaxy nexus, see here:
https://stackoverflow.com/a/9212675/1369222
use this link http://developer.android.com/training/multiscreen/screendensities.html
here they provide drawable (if you want to use image) for each screen with the same image ,your device automatically choose their own pic according to their density.
res/
drawable-xhdpi/
awesomeimage.png
drawable-hdpi/
awesomeimage.png
drawable-mdpi/
awesomeimage.png
drawable-ldpi/
awesomeimage.png
and this is for layout ,make new folder in your res folder and give name it layout-large and put same xml file in this i.e main.xml.
res/
layout/
main.xml
layout-large/
main.xml
Here you go if your looking for something like this, idk, im trying to get some votes im kicked off questions and im stuck, gota get back on this thing
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
I use a button with an image as its background, this image has a size of 30x29, but it's resized and enlarged x2 (I think). Here is the XML code of my button :
<Button
android:id="#+id/buttonBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="10dp"
android:background="#drawable/bouton_back"
android:maxHeight="30dp"
android:maxWidth="30dp" />
And in Java :
backButton = (Button) findViewById(R.id.buttonBack);
What is wrong with that ? I do the same with other buttons and there is no problem... thank you.
Are you supplying bouton_back in your resources using multiple densities? Using dp units to size your button isn't sufficient; you must also provide multiple sizes of your images:
ldpi: 120dpi
mdpi: 160dpi
hdpi: 240dpi
xhdpi: 320dpi
The conversion formula is as follows:
px = dp * (dpi / 160)
Where px is the final image size in pixels, dp is the desired size in density-independent units, and dpi is the target density.
Simplifying this formula, using the size in pixels of your mdpi images as the baseline:
ldpi = mdpi * 0.75
hdpi = mdpi * 1.5
xhdpi = mdpi * 2.0
Going back to your sample code, if you want a button that is 30dp by 30dp, you should be providing images for each density:
ldpi: 23px x 23px
mdpi: 30px x 30px
hdpi: 45px x 45px
xhdpi: 60px x 60px
I think that may be folder issue. Where have you put the image file? (possibly there would not be a problem if You have it in drawable-hdpi)
EDIT
ps - there is also a dp unit thing, which is pixel-independent.
you are using the background property, android will stretch your image depending on the device resoulution in dpi (ldpi, mdpi, hdpi and xhdpi screens), if you put your image in drawable-mdpi folder, your image will stretch according to this coefficient
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.