I'm making a chat Activity that has a send message box at the bottom. The send message box should always be visible and always be at the bottom of the screen. The Scrollview has a vertical LinearLayout that has views added to it inside of a loop. It works pretty much perfectly except when the there are enough views in the LinearLayout to make it scrollable the last element is always covered by the send message box. If I make the send message box invisible you can see all of the views in the layout. See images for clarity.
I DO NOT WANT TO USE A ListView because I don't want to have to use an adapter
This image on the left shows the last item being covered. Then making the send message invisible shows the last element.
Here's the layout
<?xml version="1.0" encoding="utf-8"?>
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_chat" tools:context="com.example.brian.cleverrent.ChatActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:id="#+id/scrollView" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/chatTimeLineLayout">
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sendMessageLayout"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:background="#eeeeee"
android:orientation="horizontal">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/chatEditText"
android:layout_weight=".9"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send"
android:id="#+id/chatSendButton"
android:layout_weight=".1"/>
</LinearLayout>
</RelativeLayout>
Maybe you could try using
android:fillViewport="true"
for the ScrollView. Haven't tested it myself, but it was proposed as a solution to a similar problem here LinearLayout not expanding inside a ScrollView.
Solution was to add...
android:fillViewport="true"
android:paddingBottom="50dp"
Thanks to Nestel for answer
Related
I am learning android programming and working on a simple "post", "comment", "like" type of app. Never in a million years would I have thought the hardest part of building an android app would be trying to get the layout to work. I have all the info from the firebase database, that was easy, but trying to get the layout to look right is next to impossible. I even tried copy/paste from their quickstart apps for firebase, the one that does the database stuff. Still, it will not fill the area. The top section looks great, but I have a RecyclerView that is supposed to be repeating the comments for that post, it is repeating them, but it is only a tiny piece of the height of the page, as you can see in the screenshot. I have tried using ScrollView, NestedScrollView, putting the RecyclerView in a RelativeLayout, LinearLayout, nothing is working. Here is the xml for the view...
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.google.firebase.quickstart.auth.PostDetailActivity">
<include
android:id="#+id/post_author_layout"
layout="#layout/include_post_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" />
<include
android:id="#+id/post_text_layout"
layout="#layout/include_post_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/post_author_layout"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp" />
<LinearLayout
android:id="#+id/comment_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/post_text_layout"
android:layout_marginTop="20dp"
android:weightSum="1.0">
<EditText
android:id="#+id/field_comment_text"
android:layout_width="0dp"
android:layout_weight="0.8"
android:layout_height="wrap_content"
android:maxLines="1"
android:hint="Write a comment..."/>
<Button
android:id="#+id/button_post_comment"
style="#style/Base.Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_weight="0.2"
android:layout_height="wrap_content"
android:text="Post"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_comments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/comment_form"
tools:listitem="#layout/item_comment" />
</RelativeLayout>
Check out the screenshot, the comment section is so small, I took the screenshot in the middle of scrolling so you can see the top is in the right place, but the bottom is only a few pixels tall, it isn't going all the way to the bottom of the screen. Any help is greatly appreciated. Thank you.
If I set the RecyclerView height to match_parent, I still only get one comment, since each comment is now the height of the parent.
Since RecyclerView is a dynamic layout, you want to always fill the parent layout, not have it try to wrap its content.
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_comments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/comment_form"
tools:listitem="#layout/item_comment" />
I have a main Relative layout within which there is a ListView and another Horizontal LinearLayout which I want to place at the bottom of the screen.
When the items in the list view fills up the screen, it gets hidden under the Horizontal Linear layout.
How do I restrict the ListView to take the space only till the Horozontal Linear layout and stop the content of the list view from hiding.
Thank you for your help and suggestions.
here is my Layout and a screen shot of how it looks.
<?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:id="#+id/activity_chat_window"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.raoburugula.speech_soft_ivr.ChatWindow">
<ListView
android:id="#+id/lvMessages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="5dp"
/>
<LinearLayout
android:id="#+id/llAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:weightSum="5"
android:visibility="invisible">
<EditText
android:id="#+id/etMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/btnSendMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/ic_send"
android:tint="#android:color/white"
android:onClick="sendMessage"
/>
</LinearLayout>
</RelativeLayout>
I would remove the android:visibility="invisible" line from the LinearLayout. and check how that works. I also one time built my layout from the bottom up to allow me to place 2 buttons at the bottom of the screen, in hindsight I probably didn't need to. I wasn't able to comment on your post so I made this an answer instead.
Also have you tried a normal button in place of the FAB(FloatingActionButton)? A FAB might have properties that make it visible and at the bottom right regardless of its parents attributes
You made the horizontal linearlayout align the bottom of parent ,yes;
and you must make your listView above the horizontal linearlayout.
I have a dialog fragment that contains linear layout that involves a titleText above a RecyclerView, and at the very bottom, there's a button below the recyclerView.
Since a recyclerView expands or collapses based on the number of items the adapter sets, the button sometimes gets truncated and no longer appears to be on screen, since the recyclerView just covers the entire screen.
My question is, is there a way to set the maximum height of the recyclerView without ever hiding the button underneath. I also don't want to just give the view a random height just in case the recyclerView contains no items, and it would just be a blank section.
Please let me know if you've ever run into this issue, and how you resolved this. Thanks!
UPDATED
You can achieve this easily using layout weights. Here's an example:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Title"
android:textSize="21sp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="30dp">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Submit"/>
</FrameLayout>
The Title and RecyclerView will wrap content according to contents and button will always take up bottom place.
I suggest using RelativeLayout as it handles the positioning of views for cases like yours, so that you can actually focus on main design.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Some title" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/title"
android:layout_above="#+id/button"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:gravity="center"/>
</RelativeLayout>
Above XML code is the skeleton code for what you need. you can add margins and dimensions to control the spacing. But in any case (until you provide negative margins) your views will never overlap each other.
Main trick of using RelativeLayout is the ability to use XML tags like
android:layout_below or android:layout_above or android:layout_start
or android:layout_end which perfectly aligns your view the way you
want.
I have a login layout with two EditText and a Button. When I'm typing some text in EditText, as the keyboard open it overlap the some of my layout. I try to scroll up but not able to scroll up layout to be visible. I'm using Relative Layout to create it. How to solve it?
Thank you.
Place your EditTexts and Button inside a ScrollView. Whatever is inside ScrollView can be scrolled. So your problem will be solved.
Note that ScrollView can host only one child. So you have to place all your Views inside a ViewGroup like LinearLayout or RelativeLayout
Although Julia Zhao's answer is correct, it uses RelativeLayout. If you use RelativeLayout you have to do more work to make your Views appear one below the other. So I suggest you to use LinearLayout with android:orientation="vertical" inside it. It will automatically place one View below the other without any extra effort. So you won't issues like one View overlapping on other.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="UserName"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="Password"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Login"/>
</LinearLayout>
</ScrollView>
Try nesting everything in a ScrollView, hope this helps.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#id/RLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
xmlns:android="http://schemas.android.com/apk/res/android"
>
// Your code
</RelativeLayout>
</ScrollView>
I am new to Android and am reading Wrox's professional android 4 app dev book. In chapter 4 of the book it explains how to modify the existing text view. The problem i am facing is that the listview in my app hides the edit text box. Its hidden (can be seen in the background) but still works that is more stuff can be added to the list through it. Below is the code for my main activity xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
and my todolist_item xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.wroxexample.ToDoListItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="#color/notepad_text"
android:fadingEdge="vertical"
/>
The first option you have is to use a LinearLayout instead of a RelativeLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
A RelativeLayout will allow you to position the elements relatively to the others.
On the other hand a LinearLayout will position the elements one below the other in the order they appear in the xml file.
The second option you have is to keep your RelativeLayout and just add the following tag to your ListView:
android:layout_below="#id/myEditText"
This will position the ListView below the EditText.
Try this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
android:layout_alignParentTop="true"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/myEditText"/>
</RelativeLayout>
Use a LinearLayout and the property android:layout_weight
http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html
Try something like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#+id/myListView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:entries="#array/testea"
android:layout_height="wrap_content"/>
<EditText
android:id="#+id/myEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/addItemContentDescription"
android:hint="#string/addItemHint"
/>
</LinearLayout>
This way ListView will grow to fill only the unused space.
Timothee got there before me but ill just add a little more.
you can, as he says, use a linear layout, or as user1387035 says, you can set the listview to be below the editText.
Relative Layout means "i want to lay things out relatively" and if you dont tell things where to go they will just float to where the 'gravity' is pulling them. The default gravity is top - so I'm guessing your items both ended up bunched at the top left?
As a rule of thumb - do you want your items to come one after another, bunched together (either horizontally or vertically)? if yes then use linear layout. If you want them to be pushed in different directions, use a relative layout. There are some exceptions, normally involving the "weight" attribute you can set in a linearlayout. (here's one I've just had to use: http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/)
If you have a Relative layout and are just using the layout_below/above attributes, without any 'alignParentBottom' or other thing set, then you probably just want a linearlayout
In your case I would say it sounds like you want Timothee's solution. If you want a little separation between the objects, you can use padding/margins to space them a little.
As for gravities, here is a useful blog entry that helped me get my head around LinearLayout's gravities (as well as generally): http://sandipchitale.blogspot.co.uk/2010/05/linearlayout-gravity-and-layoutgravity.html