I think I have the constraints correct for each element inside of the layout, and I want the app at runtime to look at the preview. The resource for the dice image works properly in another activity, but for some reason doesn't show on the main/first activity.
Here's the preview that's showing inside of Android Studio:
App at runtime:
<?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=".MainActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="80dp"
android:layout_height="100dp"
android:contentDescription="#string/dice_image"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.513"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.202"
tools:srcCompat="#drawable/dice_1" />
<Button
android:id="#+id/roll_d6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="#string/roll_d6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView" />
<Button
android:id="#+id/roll_d4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/roll_d4"
app:layout_constraintEnd_toEndOf="#+id/roll_d6"
app:layout_constraintStart_toStartOf="#+id/roll_d6"
app:layout_constraintTop_toBottomOf="#+id/roll_d6" />
<Button
android:id="#+id/roll_d8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/roll_d8"
app:layout_constraintEnd_toEndOf="#+id/roll_d6"
app:layout_constraintStart_toStartOf="#+id/roll_d6"
app:layout_constraintTop_toBottomOf="#+id/roll_d4" />
<Button
android:id="#+id/roll_d10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/roll_d10"
app:layout_constraintEnd_toEndOf="#+id/roll_d6"
app:layout_constraintStart_toStartOf="#+id/roll_d6"
app:layout_constraintTop_toBottomOf="#+id/roll_d8" />
<Button
android:id="#+id/roll_d12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/roll_d12"
app:layout_constraintEnd_toEndOf="#+id/roll_d6"
app:layout_constraintStart_toStartOf="#+id/roll_d6"
app:layout_constraintTop_toBottomOf="#+id/roll_d10" />
<Button
android:id="#+id/roll_d20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/roll_d20"
app:layout_constraintEnd_toEndOf="#+id/roll_d6"
app:layout_constraintStart_toStartOf="#+id/roll_d6"
app:layout_constraintTop_toBottomOf="#+id/roll_d12" />
</androidx.constraintlayout.widget.ConstraintLayout>
It is working as programmed, you're just checking it on a small display size where there is no room left below the dice image to fit 6 buttons.
What you need to do is make it responsive to accommodate different screen sizes.
Remove the margins from all the buttons or set it to a minimum margin so that it doesn't take much space when the screen size is too small and the last button can fit.
Connect the buttons to each other by connecting their bottom to next button's top as Bottom_ToTop just like Top_toBottom, to make it a chain, useful for 4th point and last button's bottom to the parent's bottom, so that it doesn't go beyond that point.
Set vertical constraint style in buttons (typically, setting it only in the first button is enough) as spread_inside. This will make equal space of the available space between all 6 buttons. Minimum space will be what you set as margin.
For small sizes, consider making it a 2xN grid of buttons instead of list to utilize the horizontal space available.
Use
android:src="#drawable/dice_1"
instead of
tools:srcCompat="#drawable/dice_1"
If you are using android:src in xml during runtime this will show up
on the app, whereas if you use tools:src in xml it will show only on
the preview of Android studio and not on the runtime of the app.
Reference
Related
I have a widget that, no matter what constraints I place upon it and other widgets, including the addition of barriers, always positions itself at the top of the layout.
This is a fairly simple arrangement of two rows of two elements each, not aligned column wise. The first element in each row is a TextView label, the second an input (Spinner).
There is also a lone TextView title above the first row stretching all the way across. By my understanding and previous experience with constraint layout, this shouldn't require a barrier between the rows, and that was my initial version.
This is the design view, where the selected element ("Credentials") is supposed to be in the second row but instead appears above the first row, over top of the title TextView ("PKIX"):
Actual result in the emulator looks much the same. The selected "Credentials" element is the fourth of five elements in the XML layout below. All of the other elements are in the right place.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/bottomborder"
android:text="PKIX"
android:textAlignment="center"
android:layout_marginHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/addsrv_trust_lbl"
/>
<TextView
android:id="#+id/addsrv_trust_lbl"
android:text="Trust"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/addsrv_trust_spin"
app:layout_constraintTop_toBottomOf="#+id/addsrv_pkix_title"
app:layout_constraintBaseline_toBaselineOf="#+id/addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="#+id/addsrv_cred_lbl"
/>
<Spinner
android:id="#+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_pkix_title"
app:layout_constraintBottom_toTopOf="#+id/addsrv_cred_spin"
/>
<TextView
android:id="#+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:paddingHorizontal="10sp"
android:text="Credentials"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/addsrv_cred_spin"
app:layout_constraintTop_toBottomOf="#+id/addsrv_trust_lbl"
app:layout_constraintBaseline_toBaselineOf="#+id/addsrv_cred_spin"
/>
<Spinner
android:id="#+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_cred_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_trust_spin"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I'm perplexed. The addsrv_cred_lbl TextView ("Credentials") is:
Start aligned with parent.
End aligned with the addsrv_cred_spin spinner, which appears correctly positioned;
this alignment is reciprocated to create a horizontal chain. They are also baseline
aligned.
Top aligned with the bottom of the TextView above it, addsrv_trust_lbl.
This alignment is also reciprocated.
There's no bottom alignment yet (there's another row to go); bottom aligning it with the parent makes no difference unless I bottom align the spinner from the same row, in which case the result goes from bad to worse.
Since this did not work, I tried to use a barrier between the rows. If I use it as a "top", with the second row widgets as the constraint referents, the barrier appears at the top, above the title, regardless of what constraints are used to position it below the first row. Used as a "bottom", with the first row widgets referenced and the second row chained below it (which is more logical), things are a little bit better in that the barrier appears in the right place -- but the "Credentials" widget is still up top.
The design view of this looks exactly the same as the previous one except the barrier is visible below the first row. In the XML, I aslo added optimizationLevel="none" after having read this can help with misbehaving barriers (but it made no difference). There's also a few stylistic elements added back here (such as font size) I removed for brevity before.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_optimizationLevel="none"
>
<TextView
android:id="#+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#drawable/bottomborder"
android:backgroundTint="#color/tbar"
android:text="PKIX"
android:textAlignment="center"
android:textSize="#dimen/addsrv_bigfont"
android:textColor="#color/titleText"
android:layout_marginHorizontal="10sp"
app:layout_constraintBottom_toTopOf="#+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="#+id/addsrv_trust_lbl"
android:text="Trust"
android:textSize="#dimen/addsrv_fontsz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/addsrv_trust_spin"
app:layout_constraintTop_toBottomOf="#+id/addsrv_pkix_title"
app:layout_constraintBaseline_toBaselineOf="#+id/addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="#+id/addsrv_bar1"
app:layout_constraintHorizontal_chainStyle="packed"
/>
<Spinner
android:id="#+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_pkix_title"
app:layout_constraintBottom_toTopOf="#+id/addsrv_bar1"
/>
<androidx.constraintlayout.widget.Barrier
android:id="#+id/addsrv_bar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="addsrv_trust_lbl,addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="#+id/addsrv_cred_lbl"
/>
<TextView
android:id="#+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
android:text="Credentials"
android:textSize="#dimen/addsrv_fontsz"
app:layout_constraintBaseline_toBaselineOf="#+id/addsrv_cred_spin"
app:layout_constraintEnd_toStartOf="#+id/addsrv_cred_spin"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_bar1" />
<Spinner
android:id="#+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_cred_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_bar1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Am I correct in observing that some of the constraints on addsrv_cred_lbl are being completely ignored? Doesn't topToBottom mean that the top of the widget is aligned with the bottom of the other? Instead, it seems simply to mean that they will be connected with a squiggly, potentially curved and convoluted line in the design view, and the spacial relation of the two widgets is arbitrary, such that the semantic logic might as well be inverted, "top = bottom, bottom = top", etc.
Please note that I do not want to use absolute values to position anything. If the only way to get this to work is to do that, constraint layout seems a complete waste of time even in this simple case, and I'd rather just stack some liner layouts.
The problem is that Spinner doesn't have a baseline. You were trying to tie it to the baseline of the item inside the Spinner is my guess - ConstraintLayout can't reach children of its children.
You can check it via the design tab with a right click. TextViews will show an option "Show baseline" but the Spinner doesn't.
Also snippet from the doc
Align the text baseline of a view to the text baseline of another
view.
That's what baselines are for, if you want two TextViews connect together so they don't have the height where the text starts messed up.
I think there is a tiny flaw in your approach to the chain. You were setting the top constraint of both elements in each row to the bottom of the previous row(or title in the first row). Even if the Spinner would have a baseline, this would make the label off-centered in relation to the Spinner(slightly higher because the baseline of a text is higher than the actual bottom of the view).
I think the best approach in these types of layouts is to have one guiding element(which is also the element of the chain) that represents the row and let other elements be positioned in relation to it.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="PKIX"
android:textAlignment="center"
android:layout_marginHorizontal="10sp"
app:layout_constraintVertical_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/addsrv_trust_spin"
/>
<TextView
android:id="#+id/addsrv_trust_lbl"
android:text="Trust"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/addsrv_trust_spin"
app:layout_constraintTop_toTopOf="#+id/addsrv_trust_spin"
app:layout_constraintBottom_toBottomOf="#+id/addsrv_trust_spin"
/>
<Spinner
android:id="#+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_pkix_title"
app:layout_constraintBottom_toTopOf="#+id/addsrv_cred_spin"
/>
<TextView
android:id="#+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
android:text="Credentials"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/addsrv_cred_spin"
app:layout_constraintTop_toTopOf="#+id/addsrv_cred_spin"
app:layout_constraintBottom_toBottomOf="#+id/addsrv_cred_spin"
/>
<Spinner
android:id="#+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#+id/addsrv_cred_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/addsrv_trust_spin"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
NOTE: I added the last bottom constraint to the parent and "spread" to the chain for demonstration but also know that if you don't have the bottom of the last view constrained to something - it's not a chain.
Working with ConstraintLayout is easy if you obey few simple rules:
Create one chain. That means Views hooking to each other reciprocally, all the way.
Now that you have a working chain, you can manipulate it with layout_constraintVertical_bias and layout_constraintVertical_chainStyle. If changing those does nothing, it means your chain is broken.
hook remaining Views to ones laid out by the chain
every control must have 4 constraints: top, bottom, start and end
do not create competing chains and try to force them into working together.
Spinner cannot have baseline, only TextView and its descendants have it. Spinner is AdapterView, so it can contain whatever you can imagine.
BTW: don't use #+id to refer to existing ids. Plus means creating new id, so if you make a typo it will create new id that refers to nothing instead of error "there's no such id".
Here's an example: top label and Spinners form the main chain and side labels are positioned each to their Spinner:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10sp"
android:background=""
android:text="PKIX"
android:textAlignment="center"
app:layout_constraintBottom_toTopOf="#id/addsrv_trust_spin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed"
/>
<TextView
android:id="#+id/addsrv_trust_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
android:text="Trust"
app:layout_constraintBottom_toBottomOf="#id/addsrv_trust_spin"
app:layout_constraintEnd_toStartOf="#id/addsrv_trust_spin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/addsrv_trust_spin"
app:layout_constraintVertical_bias="1.0"
/>
<Spinner
android:id="#+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/addsrv_cred_spin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/addsrv_trust_lbl"
app:layout_constraintTop_toBottomOf="#id/addsrv_pkix_title"
app:layout_constraintVertical_bias="0.0"
/>
<TextView
android:id="#+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
android:text="Credentials"
app:layout_constraintBottom_toBottomOf="#id/addsrv_cred_spin"
app:layout_constraintEnd_toStartOf="#id/addsrv_cred_spin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/addsrv_cred_spin"
app:layout_constraintVertical_bias="1.0"
/>
<Spinner
android:id="#+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/addsrv_cred_lbl"
app:layout_constraintTop_toBottomOf="#id/addsrv_trust_spin"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
ok so I have been battling with the design side of android for some time. I am not sure if this belongs here or in code review as I am also asking for advice, whilst there are no major issues / bugs with the layout, it isn't producing the desired results I am getting much better at Kotlin and more back end coding but getting my visual layout to have the desired results doesn't appear to be working for me.
SO I have a item.xml file for recycler view items. I have tried using match parent on width for side by side views, odp, wrap content, match constraints which zeroes out the widths. And this is how much I am struggling I am even wondering if I am explaining myself properly
advice;
small screen v large screen - I see lots of conflicting statements about some saying you should not just make things bigger on a bigger screen, when should it be and when shouldn't it be?
What I am trying to achieve;
As it stands my view below has fixed widths and heights, I personally want it to fit the screen proportionately so fully adapt to the size of the screen but different text views do deserve different weightings I suppose which I read is linear layout, but then with linear layout I cannot understand how to get the 2x2 grid at the end of my view
<?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="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="#drawable/rv_lines"
android:gravity="center_vertical">
<TextView
android:id="#+id/TV_RV_ID"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintBottom_toBottomOf="#+id/TV_RV_QCOUNT_TEXT"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/TV_RV_OutOfText" />
<TextView
android:id="#+id/TV_RV_DIFFICULTY"
android:layout_width="85dp"
android:layout_height="30dp"
android:layout_marginStart="8dp"
app:layout_constraintBaseline_toBaselineOf="#+id/TV_RV_ID"
app:layout_constraintStart_toEndOf="#+id/TV_RV_ID" />
<TextView
android:id="#+id/TV_RV_SUMTYPE"
android:layout_width="70dp"
android:layout_height="30dp"
android:layout_marginStart="8dp"
app:layout_constraintBaseline_toBaselineOf="#+id/TV_RV_DIFFICULTY"
app:layout_constraintStart_toEndOf="#+id/TV_RV_DIFFICULTY" />
<TextView
android:id="#+id/TV_RV_OutOfText"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:text="#string/score_text"
app:layout_constraintStart_toEndOf="#+id/TV_RV_SUMTYPE"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/TV_RV_SCORE"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_marginStart="8dp"
app:layout_constraintBaseline_toBaselineOf="#+id/TV_RV_OutOfText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/TV_RV_OutOfText" />
<TextView
android:id="#+id/TV_RV_QCOUNT_TEXT"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:text="#string/questions_text"
android:textAlignment="gravity"
app:layout_constraintStart_toEndOf="#+id/TV_RV_SUMTYPE"
app:layout_constraintTop_toBottomOf="#+id/TV_RV_OutOfText" />
<TextView
android:id="#+id/TV_RV_QCOUNT"
android:layout_width="50dp"
android:layout_height="30dp"
android:layout_marginStart="8dp"
app:layout_constraintBaseline_toBaselineOf="#+id/TV_RV_QCOUNT_TEXT"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/TV_RV_QCOUNT_TEXT" />
</androidx.constraintlayout.widget.ConstraintLayout>
Just some added info on the different text views. The first one is an integer record ID from the database. Second is a string from easy to impossible. The third is either a mathematical symbol or the word "random". Then the 2x2 fields are small text strings with a field next to them to show 0-99
I'm having a problem as am newbie, I want to put my TextViews according to the background image, i did it well, all good when tested app in virtual device, But when i tested it on my real device, TextView is at some other place (slightly downwards) to what I was expecting.
Is there any way to stretch the background image so that our XML code shows same display results on all devices (with different resolutions).
I just want same design results as shown on android studio Design tab.
Example :-
i want this result on all devices
am getting this on my real device
Please guys suggest the best way to do so.
My XML Layout code :-
<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"
android:background="#drawable/main_bg"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="245dp"
android:text="#string/app_name2"
android:textColor="#color/colorPrimary"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="#string/Admin"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
<EditText
android:id="#+id/editTextTextEmailAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:background="#drawable/rounded_box"
android:backgroundTint="#android:color/white"
android:elevation="1dp"
android:ems="10"
android:hint="Email"
android:inputType="textEmailAddress"
android:padding="9dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
app:layout_constraintVertical_bias="0.39" />
<EditText
android:id="#+id/editTextTextPassword"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="19dp"
android:layout_marginEnd="24dp"
android:ems="10"
android:hint="Password"
android:padding="9dp"
android:background="#drawable/rounded_box"
android:backgroundTint="#android:color/white"
android:elevation="1dp"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/editTextTextEmailAddress" />
<Button
android:id="#+id/button"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="167dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="156dp"
android:text="Log In"
android:background="#drawable/rounded_corners"
android:textColor="#android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/editTextTextPassword" />
</androidx.constraintlayout.widget.ConstraintLayout>
For this ConstraintLayout is a very good choice. how? Let's see
First, You've not provided your layout file completely so I don't know what you're doing.
Now, To position views according to any device, you should resort to scale independent solutions like using bias, setting-up different dimen values as per screen sizes and connecting widgets to each other using Constraints so they don't free float to any position when screen size changes.
Using Bias and Percent - Try to minimize use of fixed margin values like 20dp, 30dp and use Vertical/Horizontal bias, width_percent, height_percent and 0dp with it. 0dp acts as fill_contraint in ConstraintLayout.
As I can see in the pictures, you've five widgets except background, One button, Two EditTexts and two TextViews.
So, constraint button to bottom and top of parent and give it a vertical bias of 0.8 or 0.9.
As:
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.8"
app:layout_constraintWidth_percent="0.4"
/>
<!--Vertical bias will place it on 80% height of the screen and width_percent will
assign it 40% width of the screen. This will remain same in any size of the screen.-->
Now, Constraint Both editTexts to the button using Bottom_toTopOf and give the second one a margin of approx 50dp. The button will always stay on 80% of the screen and both the editText will always stay above the button. And constraint the 'GK Quiz' TextView by giving it a vertical_bias of 0.4/0.45/0.5 (whatever you prefer) and constraint the second textview to its bottom.
This is how you define a layout that will stay on same place in every screen size.
Defining custom dimen.xml - For this you can check this question out. If you don't want to mess with custom values, you can resort to two easy libraries - SDP(For layout Size) and SSP(For Text Size) which provide all the custom values which stays same in every screen size. I use these libraries so I know they work well. There's a medium article on these - How to build for different Android screen sizes using a single layout resource file.
Using Constraints - Remember, the moment you use margins or x/y values to position a widget on screen, you should be aware that they can mess up in any screen size. So, you should always constraints layout with each other to create a tight pack preventing the free flow of the layout elements. By free flow, I mean the different positions on screen in different sizes.
ConstraintLayout is most powerful layout available out there I believe and it has many ways to tackle the issues of different screen sizes. It also supports Animation using its subclass MotionLayout. Read these official docs, you'll learn more.
instead of this use a framelayout and put imageview in it with height and width of match parent and use gravity center. use gravity center for image view.
I placed a button in the middle of design layout from activity_main.xml but when i run the app through my phone, the positioning is not the same as the design inside activity_main.xml.
Tried to change layout to relative and the problem still exist.
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginLeft="160dp"
android:layout_marginTop="276dp"
android:text="Button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I expect that the design position from activity_main is the same when run through an actual android phone.
From the design layout
from the actual phone
First of all, you might want to adjust button relatively with other components. i.e. try to align your button on top of other component or maybe on bottom of another component.
Refer this link, it has all information
https://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams#attr_android:layout_alignBottom
If you have confusion, share whole xml file for us to refer.
You need just to change the <ConstraintLayout/> in <RelativeLayout/> and replace the Button code by this:
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button" />
Hope this will help.
First of all remove that margins from attributes. There is the left margin which make your button to go right and top margin which move button below the actual center point in small density devices.
So If you want to add button in center of screen in all devices. Use below code without any margin. But if your want to add spacing between other view then use small margin in other views.
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Refer this guide to learn basics of constraints : guide
<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="#efeff1">
<Button
android:id="#+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Button" />
</RelativeLayout>
I am trying to include text in my layout but it doesn't show up in Design or Blueprint. In Blueprint, it just shows up as a dot (encircled in red in the picture). I tried opening the default text in the "hello world" app which works on my phone, but the same problem occurs in the layout in Android Studio.
I am following the guide at this link : https://developer.android.com/training/basics/firstapp/building-ui.
I've included a screenshot for reference. If this helps, please note that the emulator is not running in Android Studio and the layout / design screen does not display fully in the window when I select Pixel XL 5.5 screen (it's too large and I can't scroll down to see it).
I also do not get the square box in the Blueprint as shown in figure 3 of the webpage (link above). Screenshot of Android Studio
EDIT : Following is the code for my activity_main.xml file -
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="36dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginLeft="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:text="TextView"
app:layout_constraintDimensionRatio="h,1:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Your code has a couple of issues. You're using ConstraintLayouts, but you're constraints are a little mixed up. In the first TextView, you have your topToTopOf constraint set to parent, which is fine, but your bottom constraint is also set to topOf parent. Change your bottom constraint to bottomToBottomOf parent. Like this:
<TextView
android:id="#+id/textView"
android:layout_width="36dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
In your second TextView, you're using dimensionRatio wrong. It states in the ConstraintLayout docs that you can only use this attribute with H or W if both of your width and height are set to MATCH_CONSTRAINT (aka 0dp). So for example, you've set the dimensionRatio to h,1:3, but this only works if your width is set to 0dp (aka MATCH_CONSTRAINT). You should either make the width 0dp, set the height explicitly, or change your dimensionRatio to 1:3 rather than h,1:3