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
Related
I ran into the issue concerning a ViewPager's height not being set correctly when setting android:height="wrap_content"
Now, I've successfully applied the fix mentioned here and it is working as expected. My ViewPager is correctly assuming the height of its tallest element.
However! Each of the items inside of my viewpager contains a linearlayout, which contains 2 elements, like so: (This is my container)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_margin="#dimen/gutterSpaceHalf"
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/foo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
This gives me in effect a layout that kind-of looks like this:
And what I'm trying to illustrate here is that, on the second page, LinearLayout foo will have a different height from the first page. This is expected.
But the problem comes in when I want to align the button on each page to the bottom! This is of course an issue as the bottom of foo on page one will not be the same as the bottom of foo on page two.
The standard solution, in my mind, would be to set the height of foo to match_parent. However, if I do this, the whole page becomes the height of my imageview, as the applied fix mentioned above can not calculate each child's height correctly anymore.
So, bearing in mind that my entire goal is to have equal-height pages, with dynamic content (the text), while keeping the buttons aligned to the bottom of the page, what solution would you suggest here?
Things I've tried include jiggering the height settings on layouts up the tree, and setting the height of each view to the measured height of its container upon being added in my ViewPagerAdapter, but nothing seems to be working how I want it to.
Any suggestions would be highly appreciated. Please comment if I've missed something or you'd like to see more information.
IVE DONE IT YES
All I had to do was add a view with weight=1 above my button, and give my button a static height. Now the button lines up to the bottom correctly on each page, due to the added view expanding to fill remaining size.
I also had to add +1 to the height as defined in the "hacky" solution I mentioned above, else the view I added would push items out of the largest page's layout, like so:
if (height != 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + 1 /* This is a heuristic solution */, MeasureSpec.EXACTLY);
}
YESSSSSS
(layout changes):
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View <!-- ADDED -->
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="#dimen/buttonHeight"/>
Firstly, I am new to android so if I have missed something basic I apologise.
I have a page which has two ListViews side by side, both with varying amounts of content. I also have a TextView above the ListViews and another TextView below the listviews. These text view boxes change based on items selected in either of the two ListViews.
These two ListViews sit side by side, taking up half of the screen each, while a Textview sits directly above and directly below, both centred to the page. An image is shown below.
This is the page looking normal on load.
The problem is when I select an item from either list. I have a feeling I am missing some XML properties, but I am not sure which properties or if this is even the case. When an item is selected, let's say from the ListView on the right, the TextView at the bottom is updated with text taken from an array. The ListView also decides to change the width and I am not sure why this is.... I don't want the ListView to change width. I want it to remain taking up half of the page and half of the page only.
This is the page after an item from the right ListView has been selected.
I would also like to keep things in RelativeLayout. I also believe it is only an XML issue and not to do with the adapter or any other code so I will not include that for now. I can include it if required.
Any help would be great. Thanks in advance.
content_titles.xml my activity xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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=".TitlesActivity">
<ListView
android:id="#+id/unlocked_titles_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:longClickable="true"
android:layout_below="#+id/current_title"
android:layout_alignEnd="#+id/requirements"
android:layout_marginEnd="26dp"
android:layout_above="#+id/requirements">
</ListView>
<TextView
android:id="#+id/current_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="65dp"
android:text="Current Title: Novice"
android:textSize="24sp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<ListView
android:id="#+id/locked_titles_list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignStart="#+id/requirements"
android:layout_marginStart="28dp"
android:layout_above="#+id/requirements"
android:layout_below="#+id/current_title"/>
<TextView
android:id="#+id/requirements"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="34dp"
android:text="temp"
android:textAlignment="center"
android:textSize="24sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
activity_listview.xml used as the individual rows of the ListViews
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold" >
</TextView>
The problems with layout could be caused by ScrollView to be the wrapper
I stumbled upon some note in http://developer.android.com/reference/android/widget/ExpandableListView.html
"...Note: You cannot use the value wrap_content for the android:layout_height attribute of a ExpandableListView in XML if the parent's size is also not strictly specified (for example, if the parent were ScrollView you could not specify wrap_content since it also can be any length. However, you can use wrap_content if the ExpandableListView parent has a specific size, such as 100 pixels."
I removed wrapping ScrollView and linear layout started working properly. Now its only to understand how to wrap the stuff to ScrollView. God help me
But anyway this is really weird behavior. I think that fill_parent is not really correct wording. When using heirarchyviewer tool I always see WRAP_CONTENT and MATCH_PARENT values for layout_width and leayout_height. So probably fill_parent is actually means match_parent which puts me in cognitive dissonance.
You have your layout_width properties set to wrap_content. This means that they could change as the data changes. I would recommend putting your ListViews in a LinearLayout with orientation:horizontal and set the amount of space that each element takes up with layout_weight. Here is a relevant SO question What does android:layout_weight mean?
Background
I have a RelativeLayout inside a FrameLayout/RelativeLayout (doesn't matter to me), which should be at the bottom of the screen (like a toolbar), and should hold a few views in it.
Its height is set to "wrap_content" and so does its child-views.
The child-views of this layout are : A textView that is on the left, and a Horizontal LinearLayout on the right with a few buttons.
The problem
It seems that no matter what I do, the textview is causing the RelativeLayout to take the whole space, instead of just its children.
The code
Here's the minimal XML content that causes this problem. I've removed the extra stuff (LinearLayout and its children, and also some attributes that don't matter) since they don't cause this problem in case I remove the TextView:
<RelativeLayout 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"
android:background="#FF000000" >
<!-- Here I've put some views that don't have any relation with the views below, so it doesn't have anything with do with the problem -->
<RelativeLayout
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/vertical_gradient_transparent_to_black" >
<!-- Here I've put a LinearLayout that doesn't cause the problem, so I've removed it for simplicity-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
</RelativeLayout>
I've tried many possible attributes, and also tried adding additional layouts to try to "fool" the RelativeLayout, but none of those have succeeded.
The question
Why does it occur?
A working solution would be to use a Horizontal LinearLayout (with a weight for the TextView ) instead RelativeLayout , but I still want to know why can't I use a RelativeLayout, and why it occurs. Also how to fix it while still using 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.
I have encountered the same issue before, this might be caused by android:layout_alignParentBottom attribute.Maybe you can find another way to achieve your desired effect. See this for more information.
This is some kind of Strange issue. Maybe someone else has the explanation.
I found it working when i removed the line
android:layout_alignParentBottom="true"/>
and it also worked when i tried some like this
<TextView
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"/>
I Want to create an android activity which will have few vertical stripes, here is my code:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="#CCCCCC" >
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="250dp"
android:background="#FFFFFF" >
</LinearLayout>
As you can see the upper stripe is 50 dp and the bottom stripe is 250 dp. the problem is that I am seeing only one stripe, here is what I see:
I see only one stripe.
How should I do this right?
Thanks
I think your parent LinearLayout's orientation attribute is horizontal. If you make its orientation (android:orientation) set to vertical the problem should be fixed.
Please post your whole layout file.
LinearLayout's orientation attribute decides how its child views are going to be drawn: one below the other(vertical) or one besides the other (horizontal).
You can find LinearLayout example here
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