I've tried to match as exactly as possible the tablet this is being designed for, a Samsung Tab S2 - 9.7" screen size, 2048x1536 - I've created an AVD to match that.
I've lined up the images as shown here:
But when I deploy it, they jump around, as shown here:
They get even worse depending on other tablets, but I'm just trying one for now. I'm using a full screen relative layout with DP for the dimensions and margins, so why do they jump around so much? Shouldn't it always be the same distance from the top/sides? How come even though the dimensions and pixels match exactly in the AVD and the tablet, it moves around?
I'm completely lost, I've read everything I can from setting margins in code to absolute layouts (no longer supported). Everything points back to DP, but even using an exact match tablet and designer, they change location and size.
<FrameLayout 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:background="#drawable/background_buttons"
tools:context="com.cimulus.samocoseat.MainMenu">
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_content_controls_a"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="UselessParent">
<ImageView
android:id="#+id/seatView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/seat"
android:layout_marginTop="60dp"
android:layout_marginBottom="60dp"
android:layout_marginLeft="245dp"
/>
<ImageButton
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/seatBackForward"
android:background="#drawable/left_inactive"
android:layout_marginTop="266dp"
android:layout_marginStart="38dp" />
<Button
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/legRightExtension"
android:background="#drawable/left_inactive"
android:layout_marginTop="142dp"
android:layout_marginLeft="100dp" />
</RelativeLayout>
</FrameLayout>
Any help is greatly appreciated.
Edit: I've also tried the relative layout existing on it's own, which gives me the same results overall:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_content_controls_a"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_buttons">
<ImageView
android:id="#+id/seatView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/seat"
android:layout_marginTop="60dp"
android:layout_marginBottom="60dp"
android:layout_marginLeft="245dp"
/>
<ImageButton
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/seatBackForward"
android:background="#drawable/left_inactive"
android:layout_marginTop="266dp"
android:layout_marginStart="38dp" />
<Button
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/legRightExtension"
android:background="#drawable/left_inactive"
android:layout_marginTop="142dp"
android:layout_marginLeft="100dp" />
</RelativeLayout>
I had a similar problem and someone suggested using this library - https://github.com/intuit/sdp . It provides units, that are automatically scaled across devices with different screen characteristics. Hope it helps :)
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.
Acc to the definition of a dp, 10dp should be same on devices having same dimensions irrespective of density. Then why is the layout preview in Android Studio not matching with the layout when I am running it in my mobile? I am using pixel XL in Android Studio preview and I am running it on Samsung J7 prime. Both are 5.5" diagonally but with different densities.Layout code:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/re/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal|center"
tools:layout_editor_absoluteY="25dp"
tools:layout_editor_absoluteX="0dp">
<ProgressBar
android:id="#+id/progressBar2"
style="?android:attr/progressBarStyle"
android:layout_width="147dp"
android:layout_height="173dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="454dp"
android:layout_marginStart="248dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="122dp"
android:layout_height="116dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#android:color/black"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/progressBar2"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="494dp"
app:layout_constraintHorizontal_bias="0.518" />
<RatingBar
android:id="#+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="9dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:background="#android:color/holo_purple"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.75" />
</android.support.constraint.ConstraintLayout>
The screenshot of the app:
Here is the picture of preview:
My guess, is that since you used percentage for the positioning of the views, yet the normal size of them (wrap_content, or fixed sizes you used), the result would be different across different device displays.
On some cases, they would overlap, and on some, they won't.
I suggest you to try to run it on multiple displays, to confirm this. Try to change orientation and try on various emulator configurations, for example.
To solve this issue, there are multiple solutions, depends on your needs:
size and position must match : either both are percentage, or both are fixed sizes.
create better relations between the views, that will always work
It is the problem of the IDE that shows you this error, what you do is everytime you use widget, in that always use the width as wrap_content or match_parent it is because the Preview which your getting is slightly different from what the natural phone looks like.
For height you can give you own height. The width of the screen creates an issue.
If in wrap_content if you find the issue in size then you can follow like this in order to get the desired result.
<ProgressBar
android:width="match_parent"
android:height="115dp"
android:marginLeft="20dp"
androidMarginRight="20dp">
You can achieve the desired width, you can adjust the value of the margin nothing else.
The benefit of doing thing like will give you the desired result in the phone as it will take up the full space of the width of the phone (Real One) and now adjust the margin according to it.
Try it and then tell me whether you are getting some result or not.
EDITS
Do like this in your layout in order to adjust
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="25dp"
android:layout_weight="1">
<RelativeLayout
android:layout_width="170dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:layout_marginRight="20dp">
<Button
android:id="#+id/facebookButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="11dp"
android:layout_marginTop="4dp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="170dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1">
<Button
android:id="#+id/googleButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
</LinearLayout>
Do like this for your problem.
Okay!
I am developing android application right now, but I want to know how I can fit all the layoutouts to the a multiple device screens.
* I did made multiple screen folders.
res/layout-small/main.xml
res/layout-normal/main.xml
res/layout-large/main.xml
res/layout-xlarge/main.xml
* Here is an example of my code.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="120dp"
android:layout_height="70dp"
android:text="#sting/button1" >
<Button
android:layout_width="120dp"
android:layout_height="70dp"
android:text="#sting/button2" >
<Button
android:layout_width="120dp"
android:layout_height="70dp"
android:text="#sting/button3" >
<Button
android:layout_width="120dp"
android:layout_height="70dp"
android:text="#sting/button3" >
</LinearLayout>
</LinearLayout>
As you can see, I used 120dp for every buttons.
When I ran in the virtual device machine, the screen is fit. (Because I used 480dp width screen in virtual device machine.)
However, when I ran in real cell phone devices (Mine: SamSung Galaxy Note 1(Korean version), my dad's: SamSung Galaxy S2(Korean version), and my mom's: SamSung Galaxy S(Canadian version)), even though I created different screen size of folders, I can see the (width) of the button is go too far from the device's screen layout.
Can anyone tell me how I can fit to all the device screen?
Can I still use dp in this case? (Please give me an example too!)
You need to read up on using LinearLayout and RelativeLayout (and other layouts). You're not using their layout parameters at all. You shouldn't need to specify any specific size (like 120dp) to support multiple screen sizes for your situation.
http://developer.android.com/guide/topics/ui/declaring-layout.html
Here's what you should do:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#sting/button1"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#sting/button2"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#sting/button3"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#sting/button4"
android:layout_weight="1" />
</LinearLayout>
I'm new to Android development and I'm trying to achieve a layout for my app that is capable of handling different screen resolutions/ratios.
I've been reading a lot of the documentation and questions on this site to try to understand the basics and concepts.
First I went through:
developer.android.com/guide/practices/screens_support.html
And questions like:
stackoverflow.com/questions/6403619/how-to-support-all-the-different-resolutions-of-android-products
I've got a pretty basic idea on how to handle things out. But still, its pretty difficult for a starter to get going, and I found myself stucked trying to achieve the solution I came up with.
I designed my app to a target resolution of 480x800, and set it up to always show in portrait mode.
This is how it looks like and how I understand it should work (I used Waldo for the sake of example haha):
(sorry for the link, I need 10 rep to post images)
http://i.imgur.com/KXTAXir.jpg
My root Layout is a LinearLayout, wich contains 3 other Layouts being A and C set up to a weight of 0.8 while B is at 8.4. This is all fine, but the contents of B are set up to DP units at the moment just to be able to test.
B consists of a frame Layout who has 3 other Layouts inside, where 2 of them are working fine, and shown only when needed. The problem is that I need B to be able to adapt based on the contents of it first child: a LinearLayout wich contains 2 ImageView and 1 ProgressBar. I need that those ImageView always keep their ratio.
Here is an example of how it should work:
http://i.imgur.com/cH7fUze.jpg
Imagine those 4 are real screens, wich vary in ratio and size. So my app should only adapt B (from my first image) to keep the images original ratio.
Here is the layout code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darkgray"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8"
android:background="#666666" >
<TextView
android:id="#+id/level_text_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="LEVEL"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/level_text_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="SCORE"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/level_text_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="01:59"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8.4" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:adjustViewBounds="true" />
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="1000"
android:progress="0" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="200dp"
android:adjustViewBounds="true" />
</LinearLayout>
<RelativeLayout
android:id="#+id/pauseMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:visibility="gone" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/gameoverMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:visibility="gone" >
</RelativeLayout>
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8"
android:background="#666666" >
<TextView
android:id="#+id/level_text_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="0/0"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="Button"
android:onClick="useHint" />
<Button
android:id="#+id/button2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/button1"
android:layout_centerVertical="true"
android:text="Button"
android:onClick="toggleSound" />
<Button
android:id="#+id/button3"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/button2"
android:layout_centerVertical="true"
android:text="Button"
android:onClick="togglePause" />
</RelativeLayout>
The last thing that stays unclear to me is how to handle the text and button sizes. Should I set them in DPs? How do I get them to scale accordingly like it can be seen on the bottom of my second picture.
Thank you for your help, I also want this to serve as an example to others that are having trouble to understand how to handle this kind of scenarios.
I'm not sure, if I got your question right.
However, you can specify different layouts for different screen sizes and orientations, as described here: http://developer.android.com/guide/practices/screens_support.html
Just give the respective suffix in the name of your layout XML file.
I ended up creating a custom View for my images. The view calculates the space thats left on its parent, scales the images manually and then resizes itself to the same size of the resulting image.
To resize the progress bar to have the same width as the images, I used a custom listener that gets triggered when my custom views get resized. Then I resize the progressbar to match their width.
With this I achieved what I wanted, a layout that will work perfectly in all screen sizes.
I am new to Android, but I still managed to design an app that runs just fine on my smartphone. I read the tutorial about Android support for different screen sizes and I thought: "Ok, that's great, Android itself will scale the app in order to fit other screen sizes. I just need to have different images for different resolutions so that they will look better."
Well, it seems I didn't understand how it works exactly. By using a Virtual Device within Android SDK, I run my app on a smaller screen size. Unfortunately, there was no automatic "scaling" and half of my app layout is not shown on the screen. An imageButton that on my smartphone was one sixth of the screen, it occupies maybe one third of this new smaller screen.
What did I forget? I read some explanations and other posts but the info I got seemed to indicate an automatic scaling that doesn't happen... Maybe I miss some basic rule?
Thank you
EDIT:
Here below I add a bit of my code as an example. How should I change it in order to make the ImageButtons fill the smartphone screen in the same way, even if the screen sizes change? (if it's possible).
<RelativeLayout 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:background="#drawable/greenbackground"
tools:context=".GameFrame" >
<ImageButton
android:id="#+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="27dp"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
<ImageButton
android:id="#+id/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/image1"
android:layout_alignTop="#+id/image1"
android:layout_marginLeft="16dp"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
<ImageButton
android:id="#+id/image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:layout_toRightOf="#+id/image2"
android:layout_alignTop="#+id/image2"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
</RelativeLayout>
You need to use a ScollView in order to display UI elements which aren't visible on the small screens. Keep in mind that a ScrollView can only have one child:
<ScollView
[...] >
<MyParentLayout
[...] >
<MyUiElements
[...] >
</MyParentLayout>
</ScollView>