I have a LinearLayout which is a view that I need to display under another view, all within a ConstraintLayout. I want to LinearLayout's height to be dynamically equal to the space between the bottom of the above view, and the bottom of the parent. I've tried
<android.support.v7.widget.LinearLayoutCompat
android:id="#+id/sample_layout"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:visibility="gone"
without success. I am very new at Android UI work so I'm not sure if I'm using the right layout. Can anyone suggest a better implementation, or a fix to my current attempt?
You means this?:
<TextView
android:id="#+id/your_linear_layout"
android:layout_width="200dp"
android:layout_height="0dp"
android:layout_marginEnd="56dp"
android:background="#0ff"
android:text="your LinearLayout"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/above_view"
app:layout_constraintVertical_bias="0.0"/>
you can put the LinearLayout inside a RelativeLayout that is under the needed view, and make the height of the relative layout to fill the space, while you can make the linear layout to be in the center of the relative layout such as:
<RelativeLayout ... >
<LinearLayout
....
android:centerVertical="true"
</RelativeLayout>
Related
I have the following structure for a fragment:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/credential_save_button">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
..................
</LinearLayout>
</ScrollView>
<TextView
android:id="#+id/credential_save_button"
android:background="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#color/white"
android:textSize="#dimen/textSize"
android:text="#string/save_initialize"
android:drawableEnd="#drawable/button_right_arrow_blue"
tools:ignore="UseCompatTextViewDrawableXml"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
My expectation is that the save button would be locked to the bottom of the fragment, taking up as much height as it needs to, then the rest of the fragment would be filled with the scrollview and its fields.
Instead the scroll view exceeds the bounds of the Fragment, overlapping the save button and other elements on the page. It seems to always exceed the bounds by about half an element at the top and bottom (would guesstimate it as 20-30dp), no matter how many elements I add to it. If it has few elements in it such that it does not need to scroll, then everything appears correct and no elements are exceeding the bounds of the Fragment.
Changing it to a nested scroll view or adding the fill fillViewport attribute to it does not change anything.
Try setting
android:layout_height="0dp"
for the ScrollView to get it to expand from the top of the layout to the top of the TextView.
Also, don't specify match_parent for any child of ConstraintLayout. Always use 0dp and the appropriate constraints.
In Android, I want to achieve a scroll view with fixed height on the screen, and the content inside also have a fixed height.
The scroll view height is 300dp, the direct child (relative layout) is 500dp, and the text view distance from top is 301dp. This means after I reached the text view, there is 200dp more bottom space for me to scroll from the relative layout height.
I manage to create the desired effect using the XML below.
<ScrollView
android:layout_width="match_parent"
android:layout_height="300dp" >
<RelativeLayout
android:layout_width="match_parent"
android:background="#FFC0CB"
android:layout_height="500dp" >
<TextView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/new_realm_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="301dp"
android:text="long text" />
</RelativeLayout>
</ScrollView>
But here is the problem, if I change the relative layout to constraint layout, now the scrolling will only scroll up to the text View at height 310dp, not of showing the 200dp empty space at the bottom.
Can someone explain why constraint layout is giving me this weird behavior?
According to Differences between ConstraintLayout and RelativeLayout, constraint layout "has dual power of both Relative Layout as well as Linear layout", it should be able to achieve what relative layout can achieve.
Try this:
<ScrollView android:layout_width="match_parent"
android:layout_height="300dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:background="#FFC0CB"
android:minHeight="500dp"
android:layout_height="500dp" >
<TextView
android:id="#+id/new_realm_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="301dp"
android:text="long text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
It seems like there is a bug in constraint layout or layout height cannot be applied to constraint layout in a scroll view but you can use minimum height attribute in constraint layout.
Adding android:fillViewport="true" to the ScrollView.
I have a layout contain one image and 3 text field
I've tried to align the image to right and text field to left but I've failed
I've used
android:layout_gravity="right" for image and left to text but it did not work also I've used end and start in gravity with no success
this is the layout code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:orientation="vertical"
android:background="#drawable/card_background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/listthumb"
android:layout_width="80dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:contentDescription="Rss video thumbnail"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/listtitle"
style="#style/listTitle"
android:maxLines="3"/>
</LinearLayout>
<TextView
android:id="#+id/shortdescription"
android:layout_width="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/listpubdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="11dp"/>
</LinearLayout>
</FrameLayout>
Try to use a <RelativeLayout> instead of a <LinearLayout>
With the RelativeLayout you could place a widget depending on the position of another widget
Here the Relative Layout description
Hope this will help, I have not had time to test....
One linear layout should have vertical orientation and contain the 3 text fields.
One linear layout should have horizontal orientation and contain both the above linear layout and the image.
To push two views to the edges of the screen, you can also give each a left/right margin and then put a blank view with weight = 1 in between them.
Please read a bit more on how layouts work on Android and the different types available to you. A LinearLayout will stack the containing Views either Horizontally or Vertically one after the other. A FrameLayout is simply a container and the items within have to position themselves. RelativeLayout allow you to position your views with a relative reference to other views (in your case, you can position your ImageView, and then your 3 TextViews relative to where the ImageView is).
If you can use LinearLayout instead of RelativeLayout, you should do so, as RelativeLayout is always slower, due to having to perform two passes prior to rendering as it needs to measure each view and then also perform the layouts based on that. You might be looking for something like (pseudo-code):
<LinearLayout orientation=horizontal>
<LinearLayout orientation=vertical>
<TextView />
<TextView />
<TextView />
</LinearLayout>
<ImageView />
</LinearLayout>
You have not described your question well . Check below code if it works .
You just forgot to add orientation in linear layout containing one text view and a Image view .
Add Orientation to Your Linear Layout.
I'm struggling with a widget layout. Essentially I have an image above some text, wrapped in a vertical LinearLayout container. The image seems to take up all the space in the container (aligned at the bottom of the widget) forcing the text off the bottom of the widget and therefore its not visible. Is there a way to get the image to auto-resize to avoid any other views below it from being forced out of the containers view? Here's the code:
<LinearLayout
android:id="#+id/vertical_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/the_image"
android:src="#drawable/image_32"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/the_poor_text_which_doesnt_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Where am I?"
android:textColor="#ffffff"
android:textSize="11dip" />
</LinearLayout>
Try using a RelativeLayout instead of a LinearLayout, declaring the TextView first with the parameter android:layout_alignParentBottom="true", and then the ImageView, with android:layout_above="#+id/the_poor_text_which_doesnt_show".
Why does FOOBARZ get layed out all the way at the bottom when no elements are layout_height="fill_parent" in other words, all elements are wrap_content for height?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/feed_u"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_marginLeft="5dip"
android:scaleType="centerCrop"
android:drawableTop="#android:drawable/presence_online"
android:text="U" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/feed_u">
<ImageView
android:id="#+id/feed_h"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/btn_minus" />
<ImageView
android:id="#+id/feed_ha"
android:layout_toLeftOf="#id/feed_h"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/btn_plus" />
<TextView
android:id="#+id/feed_t"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title">
</TextView>
<TextView
android:id="#+id/feed_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Band"
android:layout_below="#id/feed_t">
</TextView>
<TextView
android:id="#+id/feed_s"
android:layout_below="#id/feed_a"
android:text="S"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
<TextView
android:id="#+id/feed_tm"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="FOOBARZ"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
</RelativeLayout>
</RelativeLayout>
From the RelativeLayout doc:
Class Overview
A Layout where the positions of the children can be described in relation to each other or to the parent.
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM
Class documentation
Which is exactly your case. RelativeLayout can not do that.
For those looking for a solution to this, like I did, you can use FrameLayout instead of RelativeLayout.
Then you can set the gravity the intended object to bottom right as below
<TextView
android:layout_gravity="bottom|right"
android:text="FOOBARZ"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
You have set the RelativeLayout to "wrap_content"
and the TextView to android:layout_alignParentBottom="true", so it automatically tries to stretch the RelativeLayout to the bottom. Don't use such dependencies with Relative Layout, as it can count as "circular dependencies".
From the docs for RelativeLayout:
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a
RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.
Try to align your TextView to something other than the parent RelativeLayout, but watch out for this problem as well:
Circular dependencies, need some help with exact code
Alternatively, try to add more sophisticated inner layouts.
Dont use alight_Parent type properties with the child views
You can use frame layout instead of RelativeLayout with respective gravity
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<TextView
android:layout_gravity="bottom|right"
android:text="Hello "
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</TextView>
</FrameLayout>
FrameLayout is usually good for placing different views one on top of each other (where the most recent child is on top of the previous child). In your case, you'd like to place views one next to each other (above, below, start, end), so I think ConstrainLayout fits better because it's exactly what it does.
Unlike RelativeLayout, you'd be able to set the ConstrainLayout width to wrap_content and still arrange its children views as you wish, for example instead of
android:layout_alignParentTop="true"
you can use
grid:layout_constraintTop_toTopOf="parent"
and instead of
android:layout_alignParentBottom="true"
you can use
grid:layout_constraintBottom_toBottomOf="parent"
Good answers. Now if you don't have layout_alignParentBottom="true" and still getting this issue watch out for android:background="#drawable/bkgnd" where bkgnd is a biggie.
I'm not sure why the clean and obvious way of accomplishing this hasn't been posted yet. This performant solution works for any View MyView with a known height.
Wrap your RelativeLayout with height wrap_content in a FrameLayout:
<!-- width here should constrain RelativeLayout -->
<FrameLayout
android:layout_width="#dimen/my_layout_width"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<MyView
...
android:layout_gravity="bottom" />
</FrameLayout>
Just note that the view at the bottom of the FrameLayout will be on top of your RelativeLayout content, so you'll need to add padding to the bottom of that layout to accomodate it. If you want that view to be variable height, you can either Subclass FrameLayout to add padding in code based on the measured view height, or just change the FrameLayout to vertical LinearLayout if you're not worried about the performance, i.e. it's not a listview item, or the views are relatively lightweight.
Not sure why all the answers here suggest FrameLayout, which is designed to render a single view or views layered in the z axis. OP's problem is a sequence of views stacked vertically, which should be in a LinearLayout.