Consider a trivial ConstraintLayout with a 20% vertical GuideLine and a thick ugly vertical bar left of the invisible line (see XML).
I can manipulate the percentile programmatically by using ConstraintSet.setGuidelinePercent() as per tynn's example, but I need a more dynamic implementation (eg: a draggable GuideLine or Barrier).
Must be a better way than attaching a drag listener to the vertical bar and using setGuidelinePercent()?
It seems incomprehensible that ConstraintLayout would not provide a native solution - perhaps I just couldn't find it?
Sample XML:
<?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/leftTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="#AAA"
android:text="LEFT: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/verticalBar"
/>
<View android:id="#+id/verticalBar"
android:layout_width="8dp"
android:layout_height="match_parent"
android:background="#000000"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideLine" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideLine"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".20" />
<TextView
android:id="#+id/rightTV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="#DDD"
android:text="RIGHT: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#+id/guideLine"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Take a look at MotionLayout. (Emphasis is mine.)
MotionLayout is a layout type that helps you manage motion and widget animation in your app. MotionLayout is a subclass of ConstraintLayout and builds upon its rich layout capabilities. As part of the ConstraintLayout library, MotionLayout is available as a support library and is backwards-compatible to API level 14.
In addition to describing transitions between layouts, MotionLayout lets you animate any layout properties, as well. Moreover, it inherently supports seekable transitions. This means that you can instantly show any point within the transition based on some condition, such as touch input.
Related
This question may have been asked a million times and seem trivial but i still do not understand the logic behind it after reading about 100 of answers.
I have this ultra simple layout XML
<?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">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
From my understanding if i set opposing constraints the render engine interprets them automatically as percentage... i mean right ?
If no specific margin or anything is set then it evens out the distances. This would clearly mean that the button should tae a centered position inside the view. But it doesnt....
I dont understand it. i want to center with WITHOUT SETTING A MARGIN since a margin, from my understanding, is something independent of the constraint. It works within a constraint. but nevertheless i set a margin of 50 on each side. once a margin is set on opposing sides the engine should automatically render it as percentage.... right ?
So this XML:
<?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">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="50dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="50dp"
android:text="Button"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
should say something like "the constraint is 50% to left right top and bottom" which essentially again is exactly the middle. Of course this is again not working. The engine interprets it as absolute value and the button is in another awkward position:
So how to do this ??
What I DON'T WANT TO DO:
Adjust it with some kind of Guideline or Bias.
I want the plain thing.
Just 4 constraints (4 lines inside the xml) and a button that is in the middle of the screen on any device.
Maybe someone can share some insight ?
You should delete these two attributes:
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="0.0"
As you can see the official reference, default bias is fifty-fifty (50% = 0.5).
For example the following will make the left side with a 30% bias
instead of the default 50%, such that the left side will be shorter,
with the widget leaning more toward the left side (Fig. 5):
I am new to constrain layout and after reading documentations i know that view must have 1 horizontal and 1 vertical coordinates but whenever i drag a new view into design it move to 0,0 coordinates
My XML
<?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">
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="181dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<ImageButton
android:id="#+id/imageButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#+id/imageView3"
app:layout_constraintEnd_toEndOf="#+id/imageView3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_add_friend" />
</androidx.constraintlayout.widget.ConstraintLayout>
I already set views vertical and horizontal constrain but it still hangs at the top left also tried with vertical and horizontal bias but views sticks to top left.Please help
I also checked this and this but not working for me.
It happens sometimes if we move around commits. For me it's mostly build related issue. Building the project or make project would fix this issue.
MyActivity has setContentView(MySurfaceView) that covers all the screen.
I would like to divide the screen into two parts: the first 2/3 of the screen must be occupied by MySurfaceView and the last 1/3 by my_activity_layout.xml.
How can I do that? Thanks.
EDIT
Thanks for your answers, but I don't have how to apply them in my case. To be clear, these are my objects:
Solution:
To attach an xml file in your layout, you can make use of the <include> tag.
Reusing layouts is particularly powerful as it allows you create reusable complex layouts. For example, a yes/no button panel, or custom progress bar with description text. More
You can have a functionality as shown in the question with the help of ConstraintLayout. Of course, there are solutions using the legacy <LinearLayout> with something called as weights but as the warning says Weights are bad for performance.
Why weights are bad for performance?
Layout weights require a widget to be measured twice. When a LinearLayout with non-zero weights is nested inside another LinearLayout with non-zero weights, then the number of measurements increase exponentially.
So let's get on to the solution using <ConstraintLayout>.
Let's say we have a layout file called my_activity_layout.xml and we use the below code to achieve what we want:
<?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">
<SurfaceView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.67" />
<include
android:id="#+id/news_title"
layout="#layout/my_activity_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline" />
</android.support.constraint.ConstraintLayout>
As you can see the Guideline help us to get 2/3 i.e 66.666 ~ 67 % of the screen, and then you can constraint your SurfaceView and your layout using <include> tag on your activity.
You can also see the required result:
You can just copy-paste the solution and see if it works as expected.
You can solve this with a linear Layout and specifying a layout weight for the correction ratios.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"/>
<include layout="my_activity_layout.xml"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
I am new to constraints layout. I want to build a very basic UI in which there are four views with equal spaces between them. Now what I want is that when I run the code on smaller device the spaces between elements should be less and when I run it on a tab, the spaces increase.
Upon searching, i came across this:
How to make ConstraintLayout work with percentage values?
Now i know how to add guidelines with percentage, but I am not completely clear still.
Am I supposed to place a horizontal guideline after every view? And anchor the view with its top and bottom guideline? But isn't it two much of work? For 4 views do I need to put 8 guidelines?
If I place a horizontal guideline on 50% of screen, and want to use it as anchor, which constraints will I apply on other views on its top?
If anyone can clear my understanding, it would be highly appreciated.
You can implement via vertical chain and horizontal chain.
read ConstraintLayout Chain.
The approach with Guidelines you describe would probably be the way to do it using the older ConstraintLayout version as discussed in the topic you linked. Now that the ConstraintLayout-1.1.0 is out it is possible to set percentage based dimensions for views by using the app:layout_constraintHeight_percent and app:layout_constraintWidth_percent.
In your case the best approach in my opinion would be to create a vertical chain of the views and set the desired height as percentage of the parent for each view. Assuming the total height percentage of all views would be less than 100%, the remaining space would then be equally divided between the views by using chain_spread_inside or chain_spread (default) attribute.
Example XML:
<?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">
<View
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_orange_dark"
app:layout_constraintVertical_chainStyle="spread_inside"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintBottom_toTopOf="#id/view2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_red_dark"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintBottom_toTopOf="#id/view3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view1" />
<View
android:id="#+id/view3"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_dark"
app:layout_constraintHeight_percent="0.1"
app:layout_constraintBottom_toTopOf="#id/view4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view2" />
<View
android:id="#+id/view4"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_green_dark"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/view3" />
</android.support.constraint.ConstraintLayout>
Result with spread_inside chain style:
and with default spread chain style:
So I'm learning app development for Android, and I'm a bit stuck. I'm trying to make a RecyclerView with CardViews, but there is just too much space between CardViews. This is what it looks like.
I'm going for more of the look that the Google app has with the feed.
This is more like what I'm shooting for.
Anyways, I've searched and searched on this website for a solution to my problem and nothing seems to be working for me. I'm hoping that someone can give me something that will actually work.
Here's the xml for my cardview:
<?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="wrap_content"
android:orientation="vertical"
android:paddingBottom="10dp">
<android.support.v7.widget.CardView
android:id="#+id/cv"
android:layout_width="match_parent"
android:layout_height="120dp"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/note_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:layout_below="#+id/event_time"
android:textSize="24sp" />
<TextView
android:id="#+id/note_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/note_title" />
</RelativeLayout>
</android.support.v7.widget.CardView>
The top and bottom spaces is caused by your padding
android:paddingBottom="10dp", remove this or reduce it
Decrease the PadingBotom of the root constraintLayout
you could put 3 or 4 dp instead of 10dp.
android:paddingBottom="10dp"
Also I do not know if the copy of your code was not good ... the constraintLayout must close at the end:
after this:
</android.support.v7.widget.CardView>
you must have this:
</android.support.constraint.ConstraintLayout>
From the documentation for CardView:
Before Lollipop, CardView adds padding to its content and draws shadows to that area. ... If you want CardView to add inner padding on platforms Lollipop and after as well, you can call setUseCompatPadding(boolean) and pass true.
In your layout, you have this attribute on your CardView tag:
app:cardUseCompatPadding="true"
This does the same thing as the method in the quote above.
As a result, even if you had zero margin on all sides of your cards, users would still see space in between them because of the inner padding behavior. If you want really tight spacing, you'll have to remove this attribute (though of course you'll still get the larger spacing pre-Lollipop).