I've encountered a problem with ConstraintLayout while simply placing 2 views in the center of screen. Like Title and Content bellow. Both should be centered vertically. So my layout looks like:
<?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”>
<TextView
android:id=“#+id/title”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:text=“Title”
android:textAppearance=“#style/Title1"
app:layout_constraintBottom_toTopOf=“#id/content”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“parent”
app:layout_constraintVertical_chainStyle=“packed” />
<EditText
android:id=“#+id/content”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:inputType=“text|textMultiLine|textNoSuggestions”
android:textAppearance=“#style/Title4"
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toBottomOf=“#id/title”
tools:text=“body\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\nbody\n” />
</androidx.constraintlayout.widget.ConstraintLayout>
But when Content growth Title is moved out of screen bounds. It looks like a bug. How can I avoid this behavior and make views to be inside screen bounds?
By default, Views that have wrap_content set for a dimension do not have their constraints enforced when the content gets too big to fit them. To change this behavior and limit the dimension you need to set app:layout_constrainedHeight="true" for your EditText.
As a side note, you should also avoid using match_parent for Views contained in ConstraintLayout as stated in the documentation.
Related
I am trying to build an Android UI where I need 7 boxes with the days of the week. In order to do this, I decided to go with a ConstraintLayout in order to be able to auto resize my views on any screen.
I created a chain between all 7 views with the with the "spread_inside" attribute, with worked but since I had my views' widths set to wrap_content, due to the nature of TextViews the views did not have equal widths. So I tried making them have equal widths by setting all of 7 views' widths to 0dp. This works but leaves no space between the views. Is there a way to add some spacing between these 7 views? Or is there another way of achieving the "equal widths" to all 7 views while keeping the auto-resizing ability on any screen? Is this even possible with ConstraintLayout or should I keep using LinearLayout for this kind of things? (as seen in the last screenshot)
I want my views to shrink when the screen is small and to expand up to a level when the screen is big. Please see the screenshots below of how it looks now. I want to add an 8dp padding between each view (on a LinearLayout I achieve this by adding a transparent divider on the layout with 8dp width, as in the last screenshot)
How it should look, achieved using LinearLayout
if you want them to be all the same width you don't even need spread_inside, just set the width to 0dp and then add margins to the views. for example:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view1"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginRight="4dp"
android:layout_marginLeft="8dp"
android:background="#ffff0000"
app:layout_constraintEnd_toStartOf="#+id/view2"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="#+id/view2"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginRight="8dp"
android:layout_marginLeft="4dp"
android:background="#ff00ff00"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/view1"/>
</android.support.constraint.ConstraintLayout>
keep in mind that space between views will be the sum of 2 margins, first and last view will have only 1 margin space, so you need to set them accordingly (like 4dp for margins between views and 8dp for first and last margin)
So I have a UI element (a single line of text) that I want horizontally centered with respect to the overall device -- unless/until it collides with other UI elements in the given view group / layout. At that point I'd like it to be either centered in the space remaining or pegged as close to being centered overall as possible without colliding. [When there's finally not enough space, then I want to use ellipses.]
Is there any way to achieve this using just standard Android layouts?
I'm currently achieving this via code that adjusts layout constraints when the view group's width changes, the text changes, or related UI elements become visible/invisible. It works fine, but I can't help thinking that some layout should just do this for me.
You can use a weighted horizontal LinearLayout like this:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:gravity="center_horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="i am centered"
android:ellipsize="end"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="another widget"/>
.
.
.
</LinearLayout>
The TextView with width 0dp and weight 1 will use the remaining horizontal space.
You can add additional widgets to the LinearLayout, and the TextView will always take the remaining space.
For example, if you change the Visibility of the Button to GONE, you'll see the TextView will expand to use the whole width. Similarly, if you programmatically add new widgets to the LinearLayout, the available space for the TextView will adjust.
You can further add ellipsize options to control what happens when the text does not fit in the TextView size.
I am working on linear layout for my simple android application. I wanna make the portion of two views dynamically change based on the size ( I want to have, for a row for left to right, the first 20% is empty, and all the content is inside the rest of 80%) . For this approach, i chosen the weight for different view. I created an nested linear layout for this approach. For example, the layout hierarchy is something like this.
<linearLayout> //parent layout
<linearLayout //child 1 layout
android:layout_weight="1">
//so that this view occupy 20% of the space regardless the width of device. I intensionally wanna keep this view empty.
</linearLayout>
<linearLayout //child 2 layout
android:layout_weight="4">
//so that this view occupy 80% of the space regardless the width of device. and
//inside this view I have whatever view I wanna add on it.
<EditText>
<ImageView>
</linearLayout>
</linearLayout>
With this approach, the Lint in Android Studio tell me the following warnings:
This is a Nested Layout. 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.
the child 1 layout is useless: This LinearLayout view is useless (no children, no background, no id, no style)
Can anyone address me the right layout to use in order to have the layout dynamically change based on the size of devices? How should I correctly set up the empty space for a linear layout case?
This is a possible solution using weights:
<LinearLayout
android:layout_width="match_parent"
android:gravity="end"
android:weightSum="1">
<!-- Your content here: -->
<View
android:layout_width="0dp"
android:layout_weight="0.8"
android:layout_gravity="end" />
</LinearLayout>
Have a look at PercentRelativeLayout.
Note: You need the Percent library to use it.
This is what is causing me many problems:
<RelativeLayout
android:id="#+id/galleryLayout"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#color/white">
<android.support.v4.view.ViewPager
android:id="#+id/imageViewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/circlePageIndicator"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="#dimen/padding_middle"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Right now this code kind of works only because I've set RelativeLayout's height to 180dp but I don't want to have it this way. I want the whole thing to have height according to ViewPager's child.
There are exactly 2 problems if I set RelativeLayout's height to WrapContent.
Problem 1
ViewPager will expand throughout the whole screen. It just doesn't respect it's wrap_content height attribute. But I've partially solved that with this answer. I'd still appreciate if there's a better solution though.
Problem 2
I want have CirclePageIndicator on the bottom of it's parent (RelativeLayout) so I've added attribute layout_alignParentBottom="true" but now because of this, the RelativeLayout will expand throughout the whole screen for some reason.
So what I'm trying to have is a RelativeLayout which wraps around ViewPager which wraps around it's child. The child is downloaded from web so I can't pre-set it. And on the bottom of that RelativeLayout, I want to have a ViewPagerIndicator.
As for the problem 1 you solved the issue correctly, ViewPager will not wrap its children by default.
As for the second problem, this is a normal RelativeLayout behaviour. If you set its height to wrap_content and add two children, one with layout_alignParentTop="true" and second one with layout_alignParentBottom="true", they will stretch your layout height-wise.
What you should do is: ask yourself if you really need RelativeLayout. If you've provided the whole layout of yours I don't see a need for RelativeLayout (its costly). Vertical LinearLayout would do just fine. If you decide that you really need RelativeLayout, try changing your Indicator's rule from layout_alignParentBottom="true" to android:layout_below="#+id/imageViewPager".
I'm trying to insert a fragment into my application and it's essentially a coloured bar with a few buttons on it. However, whenever I put the fragment onto the main xml file, there's always a bit of a white margin regardless of whatever I do. Here's an sample of some of the fragment code I have in my main xml:
<fragment
android:layout_width="fill_parent"
android:layout_height="50dp"
android:name="sample"
android:id="#+id/sample"
tools:layout="#layout/sample"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_margin="0dp" />
Even though I set the margin to 0dp and the width to fill_parent, there's still a white margin/border on the outside. Is there any way to make a fragment fill the screen widthwise entirely? Thank you!
You have padding and/or margin defined in your parent's ViewGroup that is causing the Fragment's extra spacing. Check the Parent who contains the Fragment and remove the padding :)