I'm trying to create a nested ConstraintLayout in Android.
The objective is to have an Image to the left, and another constraint layout to the right, inside a constraint layout, as the following image:
It correctly shows on the preview, but inside the application, it bugs and doesn't show at all
Layout 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:id="#+id/box_npcs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/npcImage"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="#+id/layoutInformation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="#+id/layoutInformation"
app:srcCompat="#color/colorBlueishGreen" />
<android.support.constraint.ConstraintLayout
android:id="#+id/layoutInformation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:maxWidth="250dp"
app:layout_constraintHorizontal_bias="0.021"
app:layout_constraintLeft_toRightOf="#+id/npcImage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/top_priority"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:ellipsize="start"
android:text="DummyTextIsDummy"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:textColor="#color/common_google_signin_btn_text_light_default"
android:textSize="24sp"
android:textStyle="bold"
android:typeface="normal"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
The layout is being added to another ConstraintLayout using the code
parent.addChild(inflater.inflate(R.layout.box_npc);
How should I fix this? And even, what is the issue?
The situation faced was that OP was trying to add the created ConstraintLayout to another ConstraintLayout programatically. That was being made using
inflater.inflate(R.layout.box, null)
It was an incorrect approach, as this ignores the layout parameters from the box. What was made to fix it was
inflater.inflate(R.layout.box, PARENT_LAYOUT/* One that box was being added to*/)
This fixes some issues due to the fact that the layout parameters were now being respected by the parent layout.
More information: Understaing Android's Layout Inflater.inflate()
For child views of each inner ConstraintLayout, use the id of parent layout instead of "parent".
For example instead of:
app:layout_constraintTop_toTopOf="parent"
Use
app:layout_constraintTop_toTopOf="#+id/parent_id"
Related
I have an issue with my App on Android Studio.
I want to know how can I put on the bottom of my layout (in a fixed position) without ruining the structure on various smartphones. I'm using a Linear Layout and the elements to put at the bottom are :
Edit-text (comments area) + Button "Send comment" in the right of the Edit-Text. Thank you.
Ideal approach is to use a ConstraintLayout, because it will give you a lot of options to do that. Using a LinearLayout if the linear layout height is match parent. You can set the item property of gravity=bottom.
Sample Code of constraint layout
<androidx.constraintlayout.widget.ConstraintLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="16dp"
android:background="#drawable/bg_input"
android:hint="Taper votre message"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="#drawable/bg_button"
android:text="Send"
android:textColor="#android:color/white"
app:layout_constraintBottom_toBottomOf="#+id/editText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/editText" />
</androidx.constraintlayout.widget.ConstraintLayout>
Maybe you can use a new Layout called ConstraintLayout. You have to put this new layout at the same level as your linear layout and it will not destroy your work.
This is my layout I am using for a activity.
<?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="com.example.phocast.AboutMeActivity">
<android.support.v7.widget.CardView
android:id="#+id/cv_abtme"
android:layout_width="369dp"
android:layout_height="260dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="101dp"
android:background="#color/colorPrimaryLight"
app:cardBackgroundColor="#color/bgcol_abtme"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.883">
<ImageView
android:id="#+id/imageView2"
android:layout_width="120sp"
android:layout_height="120sp"
app:srcCompat="#drawable/ic_face_black_24dp" />
<ImageView
android:id="#+id/iv1_abtme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tv_abtme"
app:srcCompat="#drawable/about_icon_facebook" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="serif-monospace"
android:lineSpacingExtra="12sp"
android:text="#string/facebook_id"
android:textSize="18sp" />
<TextView
android:id="#+id/tv_abtme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="cursive"
android:text="#string/user_name"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:textSize="36sp" />
</android.support.v7.widget.CardView>
....
</android.support.constraint.ConstraintLayout>
The output looks like:
The problem is I can't move the items inside the cardview either programatically or using drag in design view of android studio.
Like, for say, I want to have
Imageview iv1_abtme(the facebook icon) below the tv_abtme
textview4 horizentally aligned to iv1_abtme
etc.
Can anyone kindly help me on what is going wrong here(why I cant simply drag items)
CardView is based on a FrameLayout and the documentation there clearly says:
Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other. You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.
So, to solve your problem, your CardView needs to have a single child that is a view group for your views, such as LinearLayout, RelativeLayout, or ConstraintLayout.
I am currently trying ConstraintLayout in our project.
The layout I would like to implement can be simplified as following:
There are two views (say TopA and TopB) on the top of the layout, and there is another view (say BottomC) positioned below them.
TopB have changeable height, in different situations TopB's height may be larger or smaller than TopA's.
My questions is: how to constrain BottomC to the bottom of the Top view who has a larger height, so that BottomC won't be overlapped by the view with a larger height. (Screenshot attached below)
I can do that by adding TopA and TopB to an extra ViewGroup (LinearLayout for example) and constrain BottomC to the bottom of that ViewGroup. But is it possible to achieve that without introducing an extra layer of ViewGroup?
3 minutes after posting the question, I just found that recently released version 1.1.x of ConstrainLayout has a new feature called Barrier, and the official training doc of ConstrainLayout has been updated to introduce it.
This is exactly what I was looking for. Hope this can help guys like me.
The actual layout code looks like this (notice the android.support.constraint.Barrier node):
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/topA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher"/>
<TextView
android:id="#+id/topB"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="24dp"
android:text="Text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toEndOf="#+id/topA"
app:layout_constraintTop_toTopOf="#+id/topA"
/>
<android.support.constraint.Barrier
android:id="#+id/barrier4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="topA,topB"
tools:layout_editor_absoluteY="16dp"/>
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/barrier4"/>
</android.support.constraint.ConstraintLayout>
Actually this one is the common problem with the ConstraintLayout so basically there are two options, one is that if your imageview is of fixed height then set TextView minheight as imageview's height else ConstraintLayout is now introduced Barrier but this is in the Beta version if you want to use it with beta version set up as follow
This is new feature introduced in ConstraintLayout which is currently in Beta version.
How to add beta ConstraintLayout to project follow steps below
add maven support in project gradle file as below
allprojects {
repositories {
maven { url 'https://maven.google.com' }
jcenter()
}
}
then in app gardle dependencies add ConstarintLayout library dependency
compile 'com.android.support.constraint:constraint-layout:1.1.0-beta3'
add barrier in layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
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">
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView2"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Barrier
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/barrier1"
app:barrierDirection="bottom"
app:constraint_referenced_ids="textView2, imageView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintTop_toBottomOf="#id/barrier1"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
Now Beta3 is released with some fixes and new features
https://androidstudio.googleblog.com/2017/10/constraintlayout-110-beta-3-is-now.html
Option 1:
I recommend to do the following by adding the two views(Image, TextView) to a viewgroup(Any can do) then constraint the progressbar to the bottom of the viewgroup.(Edit:Just read the part were you said no view group so option 2)
Option 2:
But if u have to do it programmatically for animation or other reasons i recommend reading about:
https://developer.android.com/reference/android/support/constraint/ConstraintSet.html
and
https://developer.android.com/reference/android/transition/TransitionManager.html
I have a constraint layout inside a ScrollView. This ConstraintLayout is supposed to be a parent for other Views that will be added into it, as shown:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/generated_main_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.constraint.ConstraintLayout>
When I try to add view to this ConstraintLayout, I inflate the view from XML, with the following code:
(ConstraintLayout) getLayoutInflater().inflate(R.layout.box_npcs, MAIN_CONSTRAINT, false);
This layout is defined in XML1 (end of the question).
Then I add TextViews with information to this Layout's LinearLayout, for that I use a programatically created TextView and add it into the layout
linearLayout.addView(new TextView("Foo"));
With that setup, I add this box to the main constraint layout.
The problem is: When I try to add more than 5 views, it takes a long time to proccess the UI, taking up to 5 seconds on the max amount of view to be added (50).
How can I add Complex Views to a ConstraintLayout in a way that it doesn't lag when trying to add the views?
XML1:
<?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:id="#+id/box_npcs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/npcImage"
android:layout_width="88dp"
android:layout_height="88dp"
android:layout_marginBottom="0dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="#+id/layoutInformation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="#+id/layoutInformation"
app:srcCompat="#drawable/camera" />
<android.support.constraint.ConstraintLayout
android:id="#+id/layoutInformation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:maxWidth="280dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="#+id/npcImage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/top_priority"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="0dp"
android:layout_marginTop="0dp"
android:ellipsize="start"
android:text="DummyTextIsDummy"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:textColor="#color/common_google_signin_btn_text_light_default"
android:textSize="22sp"
android:textStyle="bold"
android:typeface="normal"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<LinearLayout
android:id="#+id/linearLayout_high_highest_normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="#+id/top_priority"
app:layout_constraintTop_toBottomOf="#+id/top_priority" />
</android.support.constraint.ConstraintLayout>
Images for examples:
Each 'box' in this screen is a box in the Main Constraint Layout.
Each TextLine is a different TextView added to the LinearLayout
What is the android version in your test device?
A few days ago, I found a problem.
If I use two or more ConstraintLayouts in Android 5 or 6, it will be slow.
When I used the Android Studio CPU Profiler, I saw the com.android.internal.policy.impl.phonewindow$decorview.onmeasure spent much time.
So I tried to use LinearLayout, and the problem was solved.
I think ConstraintLayout in Support Library is not friendly for Android 5 or 6.
I make UI of many buttons to input text by constraint layout.
For example, the following image.
But,I feel strange that android studio become very slow as I put more UIs and adaptive hook allows I set, sometimes disappear(ex.some buttons' allow disapper head row above image).It should use very large memory and I guess free memory to calculate position and re-render UI.
Can I avoid this situation? or Alternative way to make same UI using another layout. I'm very nervous for this problem because I can't understand the best way to make grid flexible-scaling UI.Any tips will help me.
I could solve the problem using grid layout enclosing the buttons nested constraint view and it seem best way that relative positioning UI.
<?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">
<EditText
android:layout_width="456dp"
android:layout_height="64dp"
android:inputType="textPersonName"
android:text="Name"
android:ems="10"
android:id="#+id/editText"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent" />
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="8"
android:rowCount="5"
android:useDefaultMargins="true"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="32dp"
android:foregroundGravity="center_horizontal"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/editText"
app:layout_constraintVertical_bias="0.81">
<Button
android:text="button"
android:layout_width="88dp"
android:background="#drawable/oval_btn"
android:id="#+id/str_wa"
android:layout_height="88dp"
tools:layout_editor_absoluteY="520dp"
tools:layout_editor_absoluteX="529dp" /> ・・・・・・
And you can place what you like.