Design Android dev screen sizes - android-studio

Hi I need some advice/help
I am designing a app for educational purposes, but battling with different screen sizes.
I am using Android studio to create the screen layouts.
What I did so far works well up and until a point.
I have tried to use constraint layout / Linear layout and relative layout but all have the same issues.
I create my main layout as normal, and then I create new layout resource files with the same activity name but with different densities.
But for some odd reason some of my test phones picks up the certain density layout but is completely out of proportion, even though it looks correct on the layout on the IDE but the minute it is ported to the phone its out.
What would be the best way to create layouts that can cater for all layouts?
here is an example of the layout I have
<?xml version="1.0" encoding="utf-8"?>
<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.LoginActivity"
android:background="#drawable/background"
android:padding="10dp">
<TextView
android:id="#+id/tv_appName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="250dp"
android:layout_marginEnd="8dp"
android:text="#string/app_name"
android:textColor="#color/colorAccent"
style="#style/Base.TextAppearance.AppCompat.Headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textAlignment="center"
android:textStyle="bold"
android:textSize="28dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="50dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_appName"
android:background="#drawable/input_shape"
android:padding="15dp"
android:textColorHint="#color/colorAccent"
android:textColor="#color/colorAccent"
android:id="#+id/edittext1"
android:singleLine="true"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="50dp"
android:ems="10"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/edittext1"
android:background="#drawable/input_shape"
android:padding="15dp"
android:textColorHint="#color/colorAccent"
android:textColor="#color/colorAccent"
android:id="#+id/edittext2"
android:singleLine="true"/>
<Button
android:id="#+id/btn_button1"
android:layout_width="134dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="#+id/edittext2"
app:layout_constraintTop_toBottomOf="#+id/edittext2"
android:background="#drawable/btn_shape"
android:text="Button 1"/>
<Button
android:id="#+id/btn_button2"
android:layout_width="134dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="#+id/edittext2"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="#+id/btn_button1"
app:layout_constraintTop_toBottomOf="#+id/btn_button1"
android:background="#drawable/btn_shape"
android:text="Button 2"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

I am pretty sure that you are using a fixed size for your views.
Never use a fixed size for a view. If you are using a ConstraintLayout then set the layout_width and layout_height of any view to either 0dp (which will make the view as big as it can be as long as it doesn't go past the constraints) or wrap_content (which will automatically make the view only the size it needs). On other layouts instead of using 0dp for making the view as big as it can be, use match_parent. wrap_content does the same thing in every layout.

Related

Balancing horizontally 2 TextViews and an ImageView between them according to text length

If Text1 is longer, than it should push everything to the right
If Text2 is longer, than it should push everything to the left
Otherwise, the arrow should be centered according to parent view
If any TextView exceeds, thus the whole view exceeds the parent view, then it should be trimmed (ellipsize)
You can achieve this using ConstraintLayout. Create a packed horizontal chain, and use wrap_content plus constrainedWidth on each text view:
<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="wrap_content">
<TextView
android:id="#+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/image"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constrainedWidth="true" />
<TextView
android:id="#+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedWidth="true" />
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#id/left"
app:layout_constraintEnd_toStartOf="#id/right"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
If both text views have long text, you can control which one gets given space first by re-ordering the tags within the ConstraintLayout. This won't change how they're positioned; it will change only whether the left or right text stretches first.

Placing a horizontal helper in Constraint Layout to be at the bottom of a View with a set custom margin

How do I set it so that a horizontal helper in Constraint Layout is set to be at the bottom of a particular View with a margin of 16dp in between?
What I've tried (with horizontal Guideline):
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.30779755"
app:layout_constraintTop_toBottomOf="#id/view2" />
It doesn't actually care about the layout_marginTop and layout_constraintTop_toBottomOf attribute. If I erase the layout_constraintGuide_percent attribute, it goes haywire and sticks to the top of the parent.
EDIT
I created that Guideline because I have a View which acts as a "background" behind multiple Views. I was hoping to constrain this background View to the bottom of this Guideline with an offset of 16dp from the last vertically aligned View (from the multiple Views). I want this background View to have a height based on the last vertically aligned View from the multiple Views, i.e. the height is determined by the bottom of the view + a 16dp margin. If I constrain the bottom of said background View to the bottom of the last vertically aligned View and add a bottom margin, the background View instead retracts 16dp from the bottom of the last vertically aligned View.
I would use a Space widget with a height of 16dp and a top constrained to the bottom of the lowest view. The bottom of the background view can be constrained to the bottom of the Space view to visually create the margin as follows using 64dp to accentuate the margin:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_red_light"
app:layout_constraintBottom_toBottomOf="#id/space"
app:layout_constraintEnd_toEndOf="#id/view1"
app:layout_constraintStart_toStartOf="#id/view1"
app:layout_constraintTop_toTopOf="#+id/view1" />
<TextView
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="Using a Space widget"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/view2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="view2"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view1" />
<Space
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="64dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view2" />
</androidx.constraintlayout.widget.ConstraintLayout>
I also mentioned using a Layer helper with a bottom padding of 16dp. Although this currently works with ConstraintLayout 2.0.0-beta3, I am not convinced that it should work, so use at your discretion. Here is how it looks again with a Layer using 64dp padding to accentuate the margin. You will need ConstraintLayout 2.0 or later.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Layer
android:id="#+id/layer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_light"
android:paddingBottom="64dp"
app:constraint_referenced_ids="view2,view1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Using a Layer"
app:layout_constraintVertical_chainStyle="packed"
android:textColor="#android:color/white"
android:textSize="30sp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toTopOf="#+id/view2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="view2"
android:textColor="#android:color/white"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/view1" />
</androidx.constraintlayout.widget.ConstraintLayout>

How do I create a ConstraintLayout with 2 fixed parts and 1 expandable?

On this topic, I've been going round in circles and have totally confused myself.
I want to create a layout which has 3 components, stacked vertically. The first should be at the top of the screen, and take up however much space it needs (this will increase and decrease as things in it are clicked). The third should be at the bottom and is a fixed size (Google Ads). The one in the middle should take up the remaining space.
I currently have (wrapped in a ConstraintLayout):
<android.support.constraint.ConstraintLayout
android:id="#+id/cl_create_chart"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/fragment_charts_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
... contents of layout ...
</ConstraintLayout>
<fragment
android:id="#+id/fragment_charts_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/cl_create_chart"
app:layout_constraintBottom_toTopOf="#+id/au_adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout="#layout/fragment_charts_list" />
<com.google.android.gms.ads.AdView
android:id="#+id/au_adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="bottom"
ads:adSize="SMART_BANNER"
ads:adUnitId="..."
ads:layout_constraintBottom_toBottomOf="parent"
ads:layout_constraintEnd_toEndOf="parent"
ads:layout_constraintStart_toStartOf="parent" />
I'm meant to add in some vertical weighting, right? But nothing I try is making any difference - the first bit is floating down the screen so there's blank space above it. Can someone either give me a quick answer or point me to a tutorial that explains how to achieve this? I've read the Android docs, but can't find anything that includes 'filling the leftover space'.
To fill the screen with your three views as you wish, do the following:
Top view: width="0dp" (fill screen width); height="wrap_content" (Will let it grow/shrink as needed)
Middle view: width="0dp"; height = "0dp" (Fill space within top/bottom constraints.)
Bottom view: width="0dp"; height="wrap_content" (Really a fixed size due to nature of the content)
Here is a demo of these concept. I changed a few things around, made a fragment into a generic View, for instance, but the concepts are the same.
And the XML for this image:
<android.support.constraint.ConstraintLayout 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">
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cl_create_chart"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/fragment_charts_list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/lorem_ipsum"
android:textSize="20sp" />
</android.support.constraint.ConstraintLayout>
<View
android:id="#+id/fragment_charts_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_light"
app:layout_constraintBottom_toTopOf="#+id/au_adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/cl_create_chart" />
<com.google.android.gms.ads.AdView
android:id="#+id/au_adView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
I will also point out that you have "ads" as a namespace prefix when you need an "app" prefix for the constraint layout in the Adview.

Possible overdraw: Root element paints background

In my application, it appears this warning on the lints of Android:
Possible overdraw: Root element paints background #drawable/main with
a theme that also paints a background (inferred theme is #android:style/Theme)
I wanna know how to correct this mistake, cause after checking and checking on internet, I just found that it is decreasing application speed cause it reload two times the background to put this source.
This is the source of my layout.xml:
<?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"
android:background="#drawable/main"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
android:layout_centerHorizontal="true"
android:layout_marginLeft="20dp"
android:text="#string/alta1"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_marginTop="20dp"
android:layout_centerHorizontal="true"
android:text="#string/alta2"
android:layout_marginLeft="20dp"
android:textColor="#000"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="#+id/continuaralta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/textView2"
android:layout_marginRight="50dp"
android:layout_marginTop="36dp"
android:textStyle="bold"
android:background="#drawable/boton"
android:text="#string/continuar" />
<Button
android:id="#+id/saliralta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/continuaralta"
android:layout_alignBottom="#+id/continuaralta"
android:layout_marginRight="15dp"
android:layout_toLeftOf="#+id/continuaralta"
android:background="#drawable/boton"
android:textStyle="bold"
android:text="#string/salir" />
Neil Sainsbury, at http://www.earthtoneil.com/, says that Romain Guy has addressed the underlying issue at http://android-developers.blogspot.com/2009/03/window-backgrounds-ui-speed.html. See Neil's blog and search for your error message. Then, go to http://developer.android.com/guide/topics/ui/themes.html to learn how to apply background themes to the app as a whole and to individual activities.
This approach will at least cause the error message to no longer appear. Hitting the two-arrows icon to refresh the warnings in the lint window after making the fix was necessary in my case.

Android UI: how to align a TextView and two radiobuttons to occupy 1/3rd parent each?

I'm sure it's very simple and I'm just being stupid, but I've tried numerous variants and still can't get it working. What's worse - these 3 components are aligned exactly the way I want in the graphical editor in Eclipse, but not on the real device. I only get to align it to 50% for TextView and RadioGroup.
The XML goes like this currently (here I presumed RadioGroup is kind of LinearLayout):
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:text="#string/CC_Direction_caption" />
<RadioButton
android:id="#+id/rb_toCamera"
style="#style/ButtonStyle"
android:text="#string/CC_Backwards_Caption" />
<RadioButton
android:id="#+id/rb_toInfinity"
style="#style/ButtonStyle"
android:text="#string/CC_Forwards_Caption" />
</RadioGroup>
And the ButtonStyle is:
<item name="android:layout_width">0dip</item>
<item name="android:layout_height">70dp</item>
<item name="android:layout_weight">1</item>
And all this is inside a TableRow.
Use android:layout_centerVertical="true" in your TextView.
Below is a sample:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:id="#+id/typeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="GroupBox Label"
android:textColor="#color/black"
android:textSize="14dp" />
<RadioGroup
android:id="#+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/white"
android:layout_alignParentRight="true"
android:gravity="center"
android:orientation="horizontal" >
<RadioButton
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Radio 1 Text"
android:textColor="#color/blue" />
<RadioButton
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Radio 2 t"
android:textColor="#color/blue" />
</RadioGroup>
</RelativeLayout>
Try adding android:layout_weight="1" to all three elements. This specifies the relative weight every element has to the others. The higher this value is the less weight the element gets.
oh, and wrap everything in a linear layout (didn't see you didn't add a layout first).
You should use a Linear Layout with weights on your elements which will make it pretty easy to achieve what you want.
Check the docs for info on Linear Layout and weights.
http://developer.android.com/guide/topics/ui/layout-objects.html
Try changing layout_width to "wrap_content" for radio buttons as well. You have already done it for the text field.

Resources