ListView in a custom dialog pushes buttons off the screen - android

I am using my own subclass of Dialog and trying to build it in such a way that if there is not enough content to fill the screen, it will shrink to fit the content (i.e. wrap_content). I can do this with the following layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/dialog_bg">
<RelativeLayout
android:id="#+id/title_container"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:background="#drawable/dialog_title_bg">
. . .
</RelativeLayout>
<LinearLayout
android:id="#+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/content"
android:orientation="horizontal">
. . .
</LinearLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/title_container">
</FrameLayout>
</RelativeLayout>
(I've removed the bits that - I think - are not important). This works great when the content doesn't fill the screen:
But when the content is big, it pushes the buttons off the bottom:
A slight adjustment, I change the button_container so it's got layout_alignParentBottom="true" and the content is above it, like so:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/dialog_bg">
<RelativeLayout
android:id="#+id/title_container"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:background="#drawable/dialog_title_bg">
. . .
</RelativeLayout>
<LinearLayout
android:id="#+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
. . .
</LinearLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/title_container"
android:layout_above="#+id/button_container">
</FrameLayout>
</RelativeLayout>
Now it works for when the content is too big for the screen:
But when the content does not fill the screen, the dialog still does:
How can I get the best of both worlds? I could probably do it in code by setting the "maxHeight" to the height of the screen minus the dialog border and the height of the title and buttons, but that seems a bit hacky to me. I tried looking at the implementation of AlertDialog (which seems to handle this situation correctly) but it looked like black magic to me...
Edit: as requested, here is the content of the layout file that I add to the FrameLayout that represents the "content" of the dialog:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#+id/report_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" />
</RelativeLayout>

Instead of frame layout, better to use the linear. It will work.. If u post the xml code then I can check..

Related

Trying to size correctly android layouts

I'm struggling on a layout management so I decided to ask here.
I would like to get 3 layouts working in a certain way.
I have 3 views vertically dispatched into a RelativeLayout (let's call them VTop, VMiddle and VBottom).
VBottom is a Button, I want him to stay aligned with the bottom of the screen and to never move or get resized (actually working).
VMiddle is a scroll view. I want this ScrollView to take all possible place between the bottom button (VBottom) and the top most layout (VTop) but never having it height inferior to an specific size.
I would like to have VTop (A linear layout containing some TextViews and other stuffs) wrapping all of its content as long as VMiddle doesn't get smaller that its minimum size.
Actually the code I have is almost working but when I Inflate too much content into VMiddle, it keeps growing towards the top of the screen and VTop completely disappear. I want VMiddle to stay at it minimum size if VTop doesn't have enough space to wrap his content.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1" <!-- VTop -->
android:layout_above="#+id/eventDetail_RateLayout"
android:layout_alignParentTop="true"
android:layout_margin="10sp"> <!-- LOT OF VIEWS, NEED TO BE WRAPPED AS MUCH AS POSSIBLE -->
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/eventDetail_RateLayout" <!-- Not visible for now, you can ignore it -->
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:minWidth="25px"
android:minHeight="25px"
android:background="#color/common_google_signin_btn_text_light_default"
android:layout_above="#+id/eventDetail_CommentScrollView"
android:visibility="gone" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton" <!-- VMiddle, this one is doing ok -->
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Thanks for your answers.
Try the following code for the ScrollView -
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/linearLayout1"
android:layout_weight="1"
android:layout_above="#+id/eventDetail_commentButton">
...
</ScrollView>
Use this, however the kind of UI you want can be easily achieved using Linear layout and using weight and weightSum properties.. also rename ID of the layout and views accordingly
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/topLayout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:background="#70AD47"
android:orientation="vertical">
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/btnBottom"
android:layout_below="#+id/topLayout"
android:background="#ED7D31"
android:minHeight="400dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/btnBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#4472C4"
android:text="Bottom button" />
</RelativeLayout>
1. Add attribute android:layout_below="#id/linearLayout1" and android:layout_above="#id/eventDetail_commentButton" to ScrollView to keep it at middle position.
2. Use ScrollView and its child LinearLayout height android:layout_width="match_parent" although its not necessary.
No matter how big the top and bottom layout, middle scrollview will always fill the middle free spaces. It will never change the height of top and bottom layout.
Here is the working layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1"
android:layout_alignParentTop="true"
android:layout_margin="10sp">
</LinearLayout>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton"
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView"
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/linearLayout1"
android:layout_above="#id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
</RelativeLayout>
Hope this will help~
Use android:layout_below="#+id/linearlayout1"
in eventDetail_RateLayout
I'm pretty sure none of the given answers achieve what you're looking for. What you wanna do is not simple because it involves a circular dependency: you basically want your vTop view to wrap and fill any space left by your vMiddle view (android:layout_above="#id/vMiddle") and at the same time you want your vMiddle view to wrap and fill any space left by your vTop view (android:layout_below="#id/vTop").
The only solution I can imagine would be to check and set the view sizes programmatically, I don't think this is doable only by rearranging your layout.
I finally achieved to get something close to what I wanted. I combined layout_above and below and fixed the size of VTop by making the Huge TextView scrollable. I have now VTop and VBottom at a fixed size and VMiddle taking the rest of the place at the center.
Thanks for your fast answers :)

How to set layout height to one screen height except actionbar and status bar, in scrollview

I have a layout in a scrollview and I add another layout to the end of the first one. Actually I am trying to make a one page design and the rest of the other views will appear after scrolling. I tried to put linearlayout1 and linearlayout2 to another view but it didn't work. Also I set scrollview android:fillViewport="true" but it made the scrollview in screen size.
I've added an image of what I want, but it could also be one view, I mean lin1 and lin2 together.
I can set width and height for one phone but I want to do this for each screen. For example like yahoo weather app. They have done one layout for first view and start another view from the end of screen. I tried so many things but I couldn't imagine how to put layouts. Could you help me?
Thanks for your help
Here is what I want
Here is I tried:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearlayout1"
android:background="#android:color/holo_purple"
android:layout_width="match_parent"
android:layout_height="350dp" >
<TextView
android:text="LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/linearlayout2"
android:background="#android:color/holo_blue_bright"
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="vertical">
<TextView
android:text="LinearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:background="#android:color/holo_green_light"
android:layout_width="match_parent"
android:layout_height="350dp">
<TextView
android:text="LnearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</ScrollView>
But unfortunately I couldn't configure this for each screen size.
enter image description here
Just try this.
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/action_bar"
Instead of hardcoding the height as in:
android:layout_height="250dp"
Set android:layout_height="0dp" and use
android:layout_weight="25"
And also in the other layout use weight. Weight works like this, if you have 3 components in your container, set the weights to let's say 1, 2 and 3 => they will take in that order 1/6, 2/6 and 3/6 of the container. 6 being the sum of 1,2,3. So here instead of using heights as 350 and 250, you can set them to 0 and use weights 2.5 and 3.5 or 25 and 35.

Invisible components still take up space

So, I have this one activity that looks like this:
http://i.imgur.com/UzexgEA.jpg
As you can see, it has a button, a list and a button.
If certain conditions are met, I want to hide both buttons just show the list, but as you can see in the next image, the buttons are still taking up space:
http://i.imgur.com/OyLIfSk.jpg
So my question, what can I do to enlarge the list to take that space out?
Here is my layout for the buttons and the list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/findSelected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="registrarAsistencia"
android:text="Registrar Asistencia" />
<ListView
android:id="#+id/listaAlumnos"
android:layout_width="fill_parent"
android:layout_height="376dp"
android:layout_weight="2.29" />
<Button
android:id="#+id/btnChecarBoxes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="seleccionarTodosNinguno"
android:text="Seleccionar / Deseleccionar todo" />
</LinearLayout>
And here it is the layout for the list's contents:
<?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="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<TextView
android:id="#+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="10dp"
android:textSize="16sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/rowTextView2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="10dp"
android:textSize="16sp"
android:textStyle="italic"/>
</LinearLayout>
<CheckBox
android:id="#+id/CheckBox01"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:focusable="false"
android:padding="10dp" />
</RelativeLayout>
Do not make the buttons View.INVISIBLE. Make the buttons View.GONE. There are three visibility states:
visible (normal)
invisible (pixels not drawn, but still takes up space)
gone (not included in rendering)
In the java code
yourView.setVisibility(View.GONE);
and in the XML code
android:visibility="gone"
Thier are 3 state
visible: normal
invisible : takes space and invisible
gone : no space and no visibility
Use
android:layout_height="0dp"
android:layout_weight="1"
In addition to #CommonsWare's answer
You should use a layout that fits well in all screen sizes. If you give you layout a fixed height like android:layout_height="376dp" it will look good only on the device (or emulator) you're testing on. What you have to do is to make sure that your listview takes up all (and only) the space left by your buttons.
Check out this article and this answer to better understand layout weights.
for hiding your widget
yourEditText.setVisibility(View.GONE)
for visbility of your widget
yourEditText.setVisibility(View.VISIBLE)

Android: Layout height in percentage of screen resolution

I'm quite new in Android, so it'll probably be a stupid question, but here it goes.
I have a RelativeLayout of Activity. In this layout I have another Layout at bottom of a screen. Sometimes I hide it or make it visible, this matters not. Is it possible to make the another layout's height lets say 27% of total screen height? The idea is to keep the other content, except this layout on screen.
Have anyone tried something like this?
LinearLayout can handle this via android:layout_weight. For example, here is a layout containing three Button widgets, taking up 50%, 30%, and 20% of the height, respectively:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="50"
android:text="#string/fifty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="30"
android:text="#string/thirty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="20"
android:text="#string/twenty_percent"/>
</LinearLayout>
However, you cannot simply declare that an arbitrary widget at an arbitrary point in your layout file should take up an arbitrary percentage of the screen size. You are welcome to perform that calculation in Java and adjust your widget's LayoutParams as necessary, though.
you can try this, is more complexe but useful.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name" />
<LinearLayout
android:id="#+id/parent_of_bottom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true" >
<LinearLayout
android:id="#+id/content_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="27">
//Add your content here
</LinearLayout>
</LinearLayout>

screen with top banner, webview and bottom banner

I'm trying to create a very simple android screen with the following content: top banner, webview and bottom banner. for some reason, i can't do it. my xml look like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/FrameLayout02"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:fitsSystemWindows="true" android:isScrollContainer="false">
<ImageView android:layout_width="wrap_content" android:layout_above="#+id/Web"
android:layout_height="fill_parent" android:layout_gravity="top"
android:src="#drawable/logo"></ImageView>
<WebView android:layout_gravity="center" android:id="#+id/Web"
android:layout_height="fill_parent" android:layout_width="fill_parent"></WebView>
<ImageView android:layout_width="wrap_content" android:layout_below="#+id/Web"
android:layout_height="fill_parent" android:layout_gravity="bottom"
android:src="#drawable/logo"></ImageView>
</LinearLayout>
what is wrong?
Thanks,
Daniel
Short answer all is wrong. Your code is a mess.
Long answer. You are trying to have an ImageView above a WebView and at the bottom another ImageView. I'm not exactly sure what of the mistakes broke it but that's also not important. Take a look at my example XML code.
<?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="fill_parent">
<ImageView android:id="#+id/topimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:src="#drawable/icon"/>
<ImageView android:id="#+id/bottomimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:src="#drawable/icon"/>
<WebView android:id="#+id/web"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/topimage"
android:layout_above="#id/bottomimage"/>
</RelativeLayout>
Now what my XML does is simple. It uses a RelativeLayout as a container to allow a more flexible child alignment. The ImageView called topimage will adjust its height to its content and fill the parent in width. It is aligned to its parents top. The second ImageView is similar with the only exception that it is pinned to its parents bottom. The WebView is aligned in between both ImageViews. It adjust it's height to the 'ImageView`s heights.
Try to always keep some kind of structure in your XML and also Java code so you and also others can throw a look at it without starting to cry.

Categories

Resources