I have a listview layout with images
It looks like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="240dp"
android:adjustViewBounds="true"
android:id="#+id/listview_item_imageView"
android:layout_gravity="center_horizontal|top" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FAC308"
android:id="#+id/listview_item_title"
android:text="TITLE"
android:textSize="20sp"
android:paddingBottom="40dp"
android:layout_centerInParent="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:id="#+id/listview_item_subtitle"
android:paddingTop="40dp"
android:text="SUBTITLE"
android:textSize="20sp"
android:layout_centerInParent="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/orangeSeparator"
android:src="#drawable/orangeseparator"
android:layout_centerInParent="true" />
If I run it on device with 720x1280 240dpi it looks like this
If I run it on device with 720x1280 320dpi it looks like this
I get images from the internet, so I cant prepare different versions.
How to make it look similar across all the devices ?
You can use fitXY Android Developer,
android:scaleType="fitXY"
or you can also create different drawable resources from the original one, with Photoshop or any similar program
in your container you have
android:layout_height="match_parent"
and in the image:
android:layout_height="240dp"
you have to have the same height or 'wrap_content' for your container not to have those gaps.
you can also add to the imageview:
android:scaleType="centerCrop"
another thing is that you can use specific library to handle loading of network images.
You can look this article . Make your app supporting different dpi variations and different screen types: Supporting Different Screens
Related
I'm relatively new in the area of App Development and still cant get behind the proper way to set up an xml file (in this case for a normal layout) to fit every mobile device that uses this layout type.
For example: I have a Pixel 2 Emulator and a Nexus 5 Emulator (both use the normal layout). However the result on the screen looks different on the devices:
Pixel 2 (1080x1920 - 420dpi): https://i.stack.imgur.com/5zmZ3.png
Nexus 5 (1080x1920 - xxhdpi): https://i.stack.imgur.com/sSLtb.png
After some research in the Google developers section about Device compability I found out that it could be due to the different pixel densities, but I have no clue how to fix this.
The xml code of this layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:background="#drawable/mybackground"
tools:context=".Start">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="#00FFFFFF"
android:padding="5dp"
android:scrollbars="none"
android:layout_below="#id/name_add"
android:layout_marginTop="15dp"
android:layout_marginBottom="160dp"
android:layout_marginStart="200dp"
/>
<EditText
android:id="#+id/name_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="200dp"
android:width="180dp"
android:ems="10"
android:hint="Name"
android:importantForAutofill="no"
android:inputType="text"
android:singleLine="true"
android:textColor="#424242"
android:textColorHint="#424242"
app:backgroundTint="#585858" />
<ImageButton
android:id="#+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/name_add"
android:layout_marginBottom="11dp"
android:layout_toEndOf="#id/name_add"
android:layout_marginStart="9dp"
android:src="#drawable/ic_plus"
android:background="#android:color/transparent"
android:contentDescription="add"/>
<Button
android:id="#+id/goToSelection"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="520dp"
android:background="#drawable/play_btn"
android:fontFamily="sans-serif"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:text="#string/btn_play"
android:textAllCaps="false"
android:textSize="20sp"
/>
<Button
android:id="#+id/languagegbr"
android:layout_width="45dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="15dp"
android:layout_marginBottom="15dp"
android:background="#drawable/gbr"
/>
<Button
android:id="#+id/languagedr"
android:layout_width="45dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="15dp"
android:layout_marginBottom="55dp"
android:background="#drawable/germanyr"
android:visibility="gone"/>
</RelativeLayout>
All of the images will later be replaced by vector graphics.
My question now is, how I can make my layout on the Nexus 5 (and on any other mobile device with a resolution of 1080x1920 or that uses the normal layout in general) look the same as it looks on the Pixel 2?
I've struggled with this kind of issues for a long time.
This stuff happens when you mess too much with dp's in margins and paddings usually. Given that dp's stay almost equal between different phone sizes, you will get variations of your display, such as the one you're showing us.
The way I solved it is by using Constraint Layout. It's very simple to use, and it has a lot of advantages. If there's no particular reason why you're not using Constraint Layout I highly suggest you to start now.
In a Constraint Layout all you need to do for your error to be solved is set the horizontal constraints to the parent and that's it.
<androidx.constraintlayout.widget.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"
tools:context=".login.YourActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Just by saying you'll be attached to your parent's left and right, sets the view right in the middle of your screen. Of any screen actually.
I am working on a project and I am trying to make the layout of the login screen. Layout Image
and here's my xml code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.ngo.ravi.idi.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="30dp"
android:background="#color/colorPrimaryDark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35sp"
android:textColor="#FFF"
android:text="#string/welcome"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:fontFamily="#font/autour_one"
android:text="#string/descrip"
android:textColor="#fff"
android:textSize="15sp"/>
<Button
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="#string/learnMore"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:textColor="#fff"
android:background="#drawable/buttonstyle2"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:layout_width="300dp"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/email" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<EditText
android:layout_width="300dp"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/password" />
</android.support.design.widget.TextInputLayout>
<Button
android:layout_marginTop="20dp"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="#string/login"
android:background="#drawable/buttonstyle"/>
</LinearLayout>
I am facing a problem with its display. I am using emulator to check this app and I tried this in 4", 4.7", 5", 5.2", 6" display and it works fine with 5" and above but when I tried this with 4" and 4.7" I found that the text of this wouldn't scaling down. Is there any way to make this app to automatic scaling as per the device.
Thank in Advance
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.
in gradle past this library :
dependencies {
implementation 'com.intuit.sdp:sdp-android:1.0.5'
implementation 'com.intuit.ssp:ssp-android:1.0.5'
}
If you want to use height, width, margin, padding etc then you use #dimen/_20sdp. (Take Size as per your requirement).
If you want to use TextSize then use #diment/_12ssp. (Take Size as per your requirement).
Please have a look below sample code:
<ImageView
android:id="#+id/img_companies"
android:layout_width="#dimen/_20sdp"
android:layout_height="#dimen/_20sdp"
android:src="#drawable/ic_companies"
android:layout_gravity="center_vertical"
android:layout_weight="1"/>
this way u can use fix size of height and width both side
UPDATE
sdp is used for same UI in Tablet and Mobile devices.
ssp is used for same TextSize for Tablet and Mobile devices.
also u can see this link for another example: https://github.com/intuit/sdp
hope it's useful for u
You have to create multiple Screen layout.
Reference :
https://developer.android.com/guide/practices/screens_support.html
https://stackoverflow.com/a/8256573/8448886
you should create layout layout like, for supporting all screens.
res/layout-small
res/layout-normal
res/layout-large
res/layout-xlarge
You can create multiple dimen files in diffrent size folders like this:
res/values-sw400p
res/values-sw600p
res/values-sw800p
and create dimen.xml in each folder.
and then make dimen item name same in each file but you can assign its values diffrent as per your requirment
example:
sw400p/ dimen.xml
textview_margin=10dp
sw600p/ dimen.xml
textview_margin=16dp
sw800p/ dimen.xml
textview_margin=20dp
I am updating my Android app and realized that I have created a layout for every possible screen size (layout-small, layout-large, etc...) It would be a huge pain to go through every XML file and manually make a small change. I am attempting to create a single XML file to support all screen sizes. After reviewing the Android documentation and other questions on stackoverflow, it seems LinearLayout is the best choice as you can provide a weightSum and layout_weight for each item in the layout. This is not working as expected (see below code and images). I am doing this correctly? Do I have to go back to creating a RelativeLayout for every possible screen size?
My images are an a single drawable folder and my layouts are in a single layout folder.
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg"
android:gravity="center"
android:orientation="vertical"
android:weightSum="100" >
<ImageButton
android:id="#+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/image0"
android:background="#null"
android:layout_weight="30" />
<ImageButton
android:id="#+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/image1"
android:background="#null"
android:layout_weight="30" />
<ImageButton
android:id="#+id/key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="30"
android:background="#null"
android:src="#drawable/image0_key" />
<TextView
android:id="#+id/tvScore"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Score: 0"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="10"
android:layout_gravity="left" />
</LinearLayout>
Resulting View (overflow of items and layout not consistent for screen sizes)
Nexus One:
Tablet:
EDIT:
I have added the following drawable-____ folders. It produces the same result.
You might want to consider creating compatibility layout folders. :)
Yes we have a solution for the same by using android's percent layout we can now use app:layout_heightPercent and app:layout_widthPercent to fit all the screens using single layout.
compile 'com.android.support:percent:23.0.0'
Why use LinearLayout weight property now we have simpler solution.
Demo HERE !
GitHub project HERE !
Consider a simple sample
<android.support.percent.PercentRelativeLayout
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="match_parent">
<TextView
android:id="#+id/fifty_huntv"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff7acfff"
android:text="20% - 50%"
android:textColor="#android:color/white"
app:layout_heightPercent="20%"
app:layout_widthPercent="50%" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="#id/fifty_huntv"
android:background="#ffff5566"
android:text="80%-50%"
app:layout_heightPercent="80%"
app:layout_widthPercent="50%"
/>
</android.support.percent.PercentRelativeLayout>
Hope it's useful for someone :-)
Use Below layout for arranging your ImageButton and TextView. It works for all screen size Layouts.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="3" />
<ImageButton
android:id="#+id/imageBtn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/ic_launcher" />
<ImageButton
android:id="#+id/imageBtn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/ic_launcher" />
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Score: 0" />
</LinearLayout>
Never put an weight sum like hundred ,just try using single digits
DisplayMetric dm =new DisplayMetric();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int h= dm.heightPixels;
int w= dm.widthPixels;
h=h/10; // 10 is for example for 10% of display height
w=((w*20)/100); // 20%of display width
LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(w,h);
YourObject.setLayoutParams(params);
//(YourObject) can be everything such as button , image button, textview,...
There are two issues here, one is to fill the size of the screen and the other is supporting the various resolution sizes of mobiles. Even within xxxhdpi, there are variations as new flagship Samsung Mobiles are drifting to 19.5 x 16.
Linear layout along with weight attributes does give a good coverage but beware of the nested tags and performance. It worked out well for most of the scenarios I have handled.
In addition, as pointed out in other answers, different drawables/resources for the standard sizes helps maintaining similar view in all devices.
I'm novice in android development and still can't understand fully how sizing works with different layouts. I want to place a preview of the book into this template:
I've tried to implement it using FrameLayout. The idea is that the center of preview image will be exactly where the center of the png background is. Here is the code:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".5" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/book_frame" />
<ImageView
android:id="#+id/previewImage"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/abs__ab_bottom_solid_dark_holo" />
</FrameLayout>
The result in layout builder look exactly like I want it to be:
On real phone it is different:
I think on other resolutions it will also differ from both variants. So my question is how to synchronize these images so after any resizing and distortions the preview will fit the cover correctly?
Possible solution would be to remove border from image and place it on previewImage instead. But there are several similar usecases in application where the border can't be removed, so I'd like to find out a universal solution for all of them.
You have your answer in your question.
What happening in your case image size matter for different screen resolution.
Hard-coded things always gives weird result in your case
android:layout_width="83dp"
android:layout_height="83dp" this piece of code.
Check this link this will guide you to manage drawables for different screens.
and here is another link
So the suitable solution for me was to separate border of inner image into its own ImageView, insert it into layout over the photo and add 1dp padding to the photo.
The layout become like this:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".5" >
<ImageView
android:id="#+id/bookFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/book_frame" />
<ImageView
android:id="#+id/previewImage"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:padding="1dp"
android:scaleType="centerCrop"
android:src="#drawable/abs__ab_bottom_solid_dark_holo" />
<ImageView
android:id="#+id/previewBorder"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/preview_border" />
</FrameLayout>
I'm developing an Android 2.2.2 application which will support multiple screens sizes and all screens will be portrait. I won't support landscape.
I have test the following layout on an HTC Desire and on a Samsung Galaxy Tab 7.7.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/no_conectado"
android:orientation="vertical" >
<TextView
android:id="#+id/labelSelGateName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="80dp" />
<TextView
android:id="#+id/labelSelOpened"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<ProgressBar
android:id="#+id/indicatorActivityView"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="22dp"
android:layout_gravity="center_horizontal" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="110dp"
android:layout_marginTop="60dp"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/btnMyGates"
android:layout_width="50dp"
android:layout_height="110dp"
android:layout_marginLeft="20dp"
android:layout_weight=".33"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onGateClick" />
<LinearLayout
android:layout_width="90dp"
android:layout_height="110dp"
android:layout_weight=".33"
android:orientation="vertical" >
<ImageButton
android:id="#+id/btnOpen"
android:layout_width="90dp"
android:layout_height="55dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onOpenDoorClick" />
<ImageButton
android:id="#+id/btnClose"
android:layout_width="90dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onCloseDoorClick" />
</LinearLayout>
<ImageButton
android:id="#+id/btnOptions"
android:layout_width="50dp"
android:layout_height="110dp"
android:layout_marginRight="20dp"
android:layout_weight=".33"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onOptionClick" />
</LinearLayout>
<ImageButton
android:id="#+id/btnFaqs"
android:layout_width="110dp"
android:layout_height="60dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onFAQClick" />
<ImageButton
android:id="#+id/btnInfo"
android:layout_width="110dp"
android:layout_height="60dp"
android:layout_gravity="right"
android:layout_marginTop="20dp"
android:background="#null"
android:contentDescription="#string/layout_empty"
android:onClick="onInfoClick" />
</LinearLayout>
I have images for ldpi, mdpi, hdpi and x-hdpi.
Background image looks great, but all widgets (TextView, ProgressBar, ImageButton, etc) aren't in the right position when I test it on Samsung Galaxy Tab.
I have designed this layout on Eclipse using 'Nexus One` as a model.
Here people are recommend me that use only one layout for every screen size and densitiy, but it doesn't work. I'm using dp units and fill_parent, etc. but it is different on Galaxy Tab.
Do I need a layout for x-large screen sizes?
Indeed, the advice you received was good: it's possible to have only one layout file, but as it was already suggested in comments, it's not good to hardcode dimensions, even if you use dp or dip, specially when you are targeting all the screen sizes and densities available.
Instead, you should replace those values with links to dimensions values.
For example, instead of android:layout_marginLeft="10dp", you'll have something like
android:layout_marginLeft="#dimen/textview_margin_left"
where textview_margin_left is defined in the dimens.xml, having different values in different folders;
probably in folder values: <dimen name="textview_margin_left">10dp</dimen>,
in folder values-large: <dimen name="textview_margin_left">20dp</dimen>,
while in values-xlarge: <dimen name="textview_margin_left">30dp</dimen>
But this is just an example, you have to test on all dimensions and resolutions and find the best values for your layout. In Eclipse, in Graphical Layout mode, you can easily get an idea about how your layout looks on various devices, just by clicking on Nexus One, and choosing another model from the list, and the layout will automatically update.
Also, you can move in dimens.xml all the text sizes, and that will be very useful for x-large devices.
Using only one RelativeLayout instead many imbricated LinearLayouts might also be a good idea, and using relative positioning for your objects, instead some of the hardcoded values.
The Problem is following you use in your layout, static values (100dp, 60dp). Now the problem is on a higher resolution this dp isn't the same.
That means you should create a layout for x-large screens. Also I wouldn't use those static values. Than your application will behave good on many diffrent screensizes!
Have a great Day
safari