I have this ScrollView Which contains a ConstraintLayout with wrap_content height
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:ignore="ContentDescription">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
----------------
----------------
----------------
----------------
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Currently I am having one ImageView inside ConstraintLayout. which comes at the Bottom when I get the data from server.
But When I am in processing state , I see the image in the middle of the screen. That I want show at the bottom.
I want to place the ImageView at the bottom in such a manner that after getting data from server, it should come at the last after scrolling the screen and in the processing state It should be seen at the bottom.
try to set android:fillViewport="true" for ScrollView. this will make child of ScrollView (in your case ConstraintLayout) fulfil height of ScrollView in case when it have smaller height (so probably when you have only one ImageView inside). for testing just set some fixed color background for ConstraintLayout and check with and without this flag (by default its false)
Related
I want to document the problems I ran into and the solution for the benefit of others, and find help with the key flaw in my solution.
I want a RecyclerView with an arbitrary number of rows in a layout with a number of other Views. The RecyclerView and other Views should be in a ScrollView that scrolls, but the RecyclerView itself should not scroll.
Since the number of rows in the RecyclerView is unknown, and I'm required to have other views immediately underneath the RecyclerView, I can't use a fixed height or match_parent.
I experienced some odd problems: when I would update the RecyclerView data (using an AsyncListDiffer) and the UI was supposed to update, the entire RecyclerView would jump above the view it was constrained underneath, straight to the top of the parent. This is not how a ConstraintLayout is supposed to behave.
Then I was able to stop that from happening, but Views underneath the RecyclerView would disappear--appearing once the RecyclerView data updated.
The solution:
Put the RecyclerView and other Views inside a ConstraintLayout inside a ScrollView (or NestedScrollView)
Set the RecyclerView to have a height of wrap_content (and adding app:layout_constrainedHeight="true" doesn't hurt)
Make sure the rows in the RecyclerView have a fixed height and do not have a height of wrap_content
This was helpful to me after banging my head against the wall and trying some proposed solutions that did not work: make RecyclerView's height to "wrap_content" in Constraint layout
This solution is pretty simple. The layout can be something like:
<ScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- other Views -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/otherView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#+id/anotherView"
/>
<!-- other Views -->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
And then the layout for a row:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight">
<!-- other views -->
</androidx.constraintlayout.widget.ConstraintLayout>
Here's the problem: I'm not a fan of fixed-height rows. What if other content needs to go in there? What if the user changes their text size? I much prefer flexible layouts that can adapt in size. But if I do that, then the RecyclerView takes up a screen's worth of height inside the ScrollView, shoving all lower views off the bottom of the screen, no matter how few rows it contains.
The alternatives I can think of are to make all the other Views outside the RecyclerView become rows of the RecyclerView, or to avoid a RecyclerView altogether and programmatically add Views to a LinearLayout. These are much uglier approaches.
Is there a way to fix it so the rows of the RecyclerView can have a height of wrap_content?
I want to display a horizontal list of scrollable buttons at top of the phone screen containing 30 items, for this purpose I am using a HorizontalScrollView with a LinearLayout with "horizontal" orientation as it's child but the linear layout is not taking up the entire phone width even on setting its width as "match-parent". Here's the code :
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_gravity="center">
<GridView
android:id="#+id/gridView_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchMode="columnWidth" />
</LinearLayout>
</HorizontalScrollView>
Here is shown in the image that linear layout is not taking up the entire space and LinearLayout is only covering some of the space. Also on changing the size to a fixed size, I noticed that the HorizontalScrollView was actually behaving like a vertical Scroll View only.
NOTE: Also if there is an alternative way to display a horizontal list of buttons with 30 items with numbers from 1 to 30 on it, please suggest it.
To achive this easily you may use Recyclerview with Horizotanl Layout Manager.For Example
recycler_view.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false));
I don't think you need a HorizontalScrollView with a nested LinearLayout for what you are trying to achieve. It would be a better idea to simply use a horizontal RecyclerView if your button layouts are similar and the functionality of the buttons is similar too. Refer to this answer for help https://stackoverflow.com/a/40584425/9119277
I'm doing this in Xamarin, so there will be slight deviations in the casing and names of methods.
I have a RelativeLayout that has ads and is placed at the bottom. Unfortunately, the ads block part of the playable map, so I'm attempting to move it to the top when the player moves near the bottom. I initialize the banner with the following code:
_banner = new RelativeLayout(this);
_lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
_lp.AddRule(LayoutRules.AlignParentBottom);
_lp.AddRule(LayoutRules.AlignParentLeft);
AddContentView(_banner, _lp);
I'm now attempting to move it to the top, but am failing. I've tried removing and re-adding it, but that does nothing.
var lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
((FrameLayout)(_banner.Parent)).RemoveView(_banner);
lp.AddRule(LayoutRules.AlignParentTop);
lp.AddRule(LayoutRules.AlignParentLeft);
AddContentView(_banner, lp);
I've also tried setting the LayoutParameters, but that throws an exception. What am I doing wrong?
Thank you.
-Nick
From your code I gather you are nesting a RelativeLayout (contains the ad) inside a FrameLayout. Your RelativeLayout only matches your parent in width, not height.
As such the RelativeLayout doesn't have the same size as your FrameLayout.
Your ad is thus touching both top and bottom of the RelativeLayout. And that RelativeLayout is always aligned to the top of the FrameLayout.
To solve this you have three options:
Make the RelativeLayout match the entire height of the FrameLayout and position your ad within that RelativeLayout.
Change the FrameLayout into a RelativeLayout, that way your alignParentBottom parameter will start working.
Use a 'layout_gravity' parameter on the RelativeLayout to tell the FrameLayout you want this View sent to the bottom.
Effectively your code is doing:
<?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="match_parent">
<RelativeLayout
android:alignParentBottom="true"
android:background="#FF0000"
android:layout_width="match_parent"
android:layout_height="240dp"
/>
</FrameLayout>
But for stuff to work you need to use android:layout_gravity which is a FrameLayout.LayoutParameter.
<?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="match_parent">
<RelativeLayout
android:layout_gravity="bottom"
android:background="#FF0000"
android:layout_width="match_parent"
android:layout_height="240dp"
/>
</FrameLayout>
Just paste the two pieces in a layout.xml and use the Android Designer to view the difference.
I've got an activity, which is themed with Holo.Dialog (or plain old Dialog on older API levels), and contains a ScrollView as it's main layout, in case we encounter smaller screens that can't display all the content. My problem now is that the dialog is needing to scroll to see all the content, even when we have leftover vertical screen space, as seen below:
Here's the code for the ScrollView and it's one child, a LinearLayout:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
What do I need to change to get this dialog to wrap more nicely? Thanks!
The solution that worked for me was to take the buttons out of the ScrollView and put them top level in a RelativeLayout. By putting the buttonbar first in the XML, aligned to parent bottom, and then setting the scrollView's layout_above to the buttonBar, I got the effect I was looking for
I am trying to make a selection ListActivity, similar to the one used to add shortcuts to the launcher screens. I have rolled my own header and footers, which I would like to be "sticky" at the top and bottom of the view when on screen. In order to do this, I am using a RelativeLayout with the header set to dock to top, footer set to dock to bottom, and the list set to go below the header and above the footer. In terms of the overall layout of the activity, this is rendering as I would expect. The header is sticky to the top, the footer is sticky to the bottom, and the list scrolls in between them.
One odd thing though happened when I switched to the RelativeLayout as my root. Please see the following screenshot:
I want my Activity's height to be wrap_content, so that the form is only as high as the content displayed in it, but once i switched to RelativeLayout, it seems to render the Activity effectively as fill_parent, taking up the whole screen, even though the content doesn't warrant it. Notice that there are not enough list items to fill the screen, which with the fill_parent style, is leaving a bunch of whitespace between the end of the list, and the footer. I was setting my height's via styles - which worked fine with LinearLayout, but seems to be ignored now. So I tried hard-coding the height directly on the RelativeLayout, but it still doesn't work and still renders as fill_parent.
Here is my layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/GroupsList"
android:layout_height="wrap_content">
<FrameLayout android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="#+id/hdrGroups"
android:layout_alignParentTop="true">
<include layout="#layout/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</include>
</FrameLayout>
<FrameLayout style="#style/MyFooter"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:id="#+id/ftrGroups">
<ImageView style="#style/CloseButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/add"
android:id="#+id/imgGroupsAdd"
android:clickable="true">
</ImageView>
</FrameLayout>
<ListView android:divider="#9f9f9f"
android:id="#+id/android:list"
android:choiceMode="singleChoice"
android:dividerHeight="1dp"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_below="#id/hdrGroups"
android:layout_above="#id/ftrGroups">
</ListView>
<TextView android:text="#string/browser_no_groups"
style="#style/ListedItemB"
android:id="#+id/android:empty"
android:layout_height="wrap_content"
android:layout_above="#id/ftrGroups"
android:layout_below="#id/hdrGroups"
android:layout_width="fill_parent">
</TextView>
</RelativeLayout>
All layout is done via XML, ... I am not doing any layout in code.
How can I get the sticky header and footer while also having the activity as a whole behave in a wrap_content mode for its height? Is there some other way I should be going about this instead of a RelativeLayout?
According to the developer documentation your desired behaviour is not possible for Relative layout ;
"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."
RelativeLayout
To solve your problem you could maybe try to use a linear layout, set to wrap_content and set max height via code to screen height.
You can get the screen height as described here : get screen height
I just change my RelativeLayout in FrameLayout and all starts to work