left and right alignment rows inside Listview - android

I want to implement interface like iphone sms:
Now I have chat listview with my custom ChatAdapter, incoming and outcoming messages inflates from different layouts:
outcoming layout:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:background="#drawable/question_bubble"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="27dp"
android:paddingTop="10dp"
android:textColor="#color/BlackColor"
android:textSize="18sp" />
incoming layout:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:autoLink="all"
android:background="#drawable/answer_bubble"
android:paddingLeft="27dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#color/BlackColor"
android:textSize="18sp"/>
I use "layout_gravity", but it doesnt work inside list view. Result:
How can I align question messages to right side?

Add a wrapper layout to your item layouts (for example a LinearLayout) that will have layout_width="match_parent" and gravitiy="left"/"right", this will adjust the inner Layout/TextView to the right position.
In general it is highly recommended to not use wrap_content for items in a ListView, this makes the ListView's onMeasure method to get repeatedly called and slow your app down.

You can try this one:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
**android:layout_width="fill_parent"**
android:layout_height="wrap_content"
**android:gravity="right"**

I've been working on this problem also at the moment. Couldn't get it to work with the suggestions mentioned here. For me it worked only by using:linearlayout.setGravity(Gravity.RIGHT); and setGravity(Gravity.LEFT); programmatically after inflating a standard layout in the getView method of the adapter. These linearlayouts have a width of wrap_content and are child of linearlayout that has match_parent for width. Also don't forget to do this every time a view is being requested via getView, not only if convertView==null.

if you encounter such problem make sure that your text layout is set in this format
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bubble_layout_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/bubble_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/chat_bubble_right">
<TextView
android:id="#+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxEms="12"
android:text="Hi! new message"
android:textColor="#color/colorWhite"
android:textSize="15sp" />
</LinearLayout>
notice that the parent LinearLayout width is set to match_parent while others are set to wrap_content.
this kept me up for hours.

Related

how to add space between items in listview

The below mentioned layout is a model of one item in a ListView. As you see it, the three TextViews are separated from each as each one occupies .3 of the entire row space.
The problem is, when I add items to the ListView I found that the three TextViews are just linked to each other. For example, let's assume I want to add item to the ListView contains the following:
Adam USA M
I expect to see that row on the screen with some spaces separating each textView, but what happens is that I get something like the following:
AdamUSAM
Why this is happening and how to solve it?
model_view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".3"
android:text="Name"/>
<TextView
android:id="#+id/tvAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".3"
android:text="Address: "/>
<TextView
android:id="#+id/tvGender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".3"
android:text="gender: "/>
</LinearLayout>
Update:
Now I changed the layout to be as follows, but the problem is persists which is that the three textviews are appearing clinching to each other without spacing.
layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="3">
<TextView
android:id="#+id/tvName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Name: "
android:focusable="false"/>
<TextView
android:id="#+id/tvAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Address: "
android:focusable="false"/>
<TextView
android:id="#+id/tvGender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="gender: "
android:focusable="false"/>
</LinearLayout>
screen shot:
You need to specify the orientation of LinearLayout e.g. android:orientation="horizontal" then replace your weights to 1 instead of 0.3 and make sure your TextView width is 0dp not wrap_content.
Add a layout_margin or padding to each TextView.
Use property
android:layout_margin="10dp"
in your listView xml add :
android:dividerHeight="8 dip"
or any value you want.
I would suggest to remove layout_weight from TextViews, define a specific height to them and add padding. Adding margins may cause your TextViews to go out of ListView.

Elements superposed using Android RelativeLayout

I have the following Android layout
<?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"
android:paddingBottom="16dp"
android:orientation="vertical" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="" />
</RelativeLayout>
But all the elements are positioned at the top of the screen one on top of the other, like if they didn't occupy any space.
That's not what what it seems to happen in the RelativeLayout documentation, where all elements are vertically positioned one below the other.
What's going on here?
So you need to use the id of the other components to align then properly.
For example the TextView with the id #+id/slideDescription should also have
android:layout_below="#+id/slideTitle" as one of the properties of the xml.
And the TextView with the id #+id/swipeMessage should also have
android:layout_below="#+id/slideDescription" as one of the properties of the xml.
In order to place one view below another in RelativeLayout you have to use layout_below property and set the ID of View you want to be above the specified one. But actually in order to place views vertically below each other it is more convenient to use LinearLayout with orientation set to vertical
layout_below is missed in the above xml code.I replaced the code with that please use that.
In Relative layout elemnets will be arranged relative to other elements in order to do this we should use id values of individual view elments
android:layout_below="#id/slideTitle" should be placed in description text view
android:layout_below="#id/slideDescription" should be placed in message text view
in order to get the output you desired please use the below code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/slideTitle"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/slideDescription"
android:text="" />

100% height android listview

I am just starting to develop android apps. I have a layout question. I want to create the main screen for my app. It is a menu with 7 options, each options would be an icon at the left, a short text and a check at the left (on/off component).
I have written it in a list view element, I have created a simple adapter with this layout:
<?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" >
<ImageView android:id="#+id/icon"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:src="#drawable/ic_action_io"/>
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/icon"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true" />
</RelativeLayout>
Menu will have always 7 options, I would like that the listview filled the height of the screen. Each element with the same height. Is it possible that with listview? Or, perhaps would be better making the menu out of a list view?
I have been reading about linear layout and the weight property. Please, could you help me? It is my first layout, I would thank any advice aboput layout I should use.
Thanks a lot, best regards!
P.D: Sorry for my english.
I would use a Linearlayout and inside i put all the items to be displayed...
Something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<RelativeLayout android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ImageView android:id="#+id/icon"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="#drawable/ic_launcher"/>
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/icon"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Texto"
android:singleLine="true" />
</RelativeLayout>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<ImageView android:id="#+id/icon"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="#drawable/ic_launcher"/>
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/icon"
android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Texto"
android:singleLine="true" />
</RelativeLayout>
<!-- Repeat the item five times more -->
</LinearLayout>
if you want all the items to be displayed (without a scroll) then there's no use in a ListView. use a LinearLayout instead and set the layout_weight of each menu item to 1.
As the others guys said is better use the LinearLayout. And like you mentioned you can use weight attribute too.
Equally weighted children
To create a linear layout in which each child uses the same amount of space on the screen, set the android:layout_height of each view to "0dp" (for a vertical layout) or the android:layout_width of each view to "0dp" (for a horizontal layout). Then set the android:layout_weight of each view to "1".
As you are trying to implement a Menu, I think the best approach is substitute each RelativeLayout(with textview and imageview) for a button. So, your layout will be like that:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="7.0" > //Defines the maximum weight sum
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:height="0dp"
android:layout_weight="1"
android:text="Option 1"
android:drawableLeft="#drawable/icon1"
android:onClick="handleOption"/> // method to handle onClick
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:height="0dp"
android:layout_weight="1"
android:text="Option 2"
android:drawableLeft="#drawable/icon2"
android:onClick="handleOption"/> // method to handle onClick
//Add more five buttons
.
.
.
In your activity, you should load this layout, using setContentView() and you must implement a method handleOption like below to handle onClick event of each button.
public view handleOption(View view)
{
switch(view.getId()) ....
}
In that way, you do not need implement onClickListener Interface, have one method to each button and set the onClickListener for each button.

Android Layout Matching Peers

I'm looking for some insights into the layout system. Is anyone aware of a method in the Android layout system that allows peer View elements (meaning Views grouped together in the same container) to match their height and width attributes without creating an interstitial container just to govern their sizes?
For example: A layout has two TextView elements. The first should always wrap width to its text content, but the second should match the width of the first. A solution that WORKS is this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textTwo"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
However, I had to create a special container for both views to ensure they both match the width of whatever text is in the first; adding unnecessary complexity to the hierarchy. What I would love to know is if there is a layout attribute I could use to do something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textTwo"
android:layout_widthMatchPeer="#id/textOne" <!-- An attribute like this -->
android:layout_height="wrap_content"
android:layout_below="#id/textOne" />
</RelativeLayout>
Creating a hard dimension as the width is defeating the purpose of letting the primary element wrap. Is there a technique someone is aware of, or an attribute I've missed, to accomplish this? Could be in any standard layout, I just chose RelativeLayout as an example.
Additionally, what if the elements are not located near each other?
Cheers.
I think the RelativeLayout class can do what you want:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/textOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textTwo"
android:layout_alignLeft="#id/textOne"
android:layout_alignRight="#id/textOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/textOne" />
</RelativeLayout>
since the views are in a relatve layout, use android:layout_below="id/firsttv" android:layout_alignLeft="id/firsttv" and android:layout_alightRight="id/firsttv"

How do I vertically align an item within a list using relative layout?

I am using a list view in Android 1.5 to show a list of images and text next to the image. I am trying to vertically center the text but the text is at the top of the row instead of centered. Below is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:paddingRight="10dip"
android:src="#drawable/default_image" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
/>
</RelativeLayout>
It seems strange that I need to set alignParentTop="true" when I'm trying to vertically center the text, but if I don't the text does not even show up. What am I doing wrong?
EDIT following the comments:
It turns out making this work with RelativeLayout isn't easy. At the bottom of the answer I've included a RelativeLayout that gives the effect wanted, but only until it's included in a ListView. After that, the same problems as described in the question occurred. This was fixed by instead using LinearLayout(s).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:orientation="horizontal">
<ImageView android:id="#+id/pickImageImage"
android:layout_width="100dp"
android:layout_height="80dp"
android:background="#drawable/icon"
android:scaleType="fitXY"
android:layout_marginRight="10dp"/>
<TextView android:id="#+id/pickImageText"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="left|center_vertical"
android:text="I'm the text"/>
</LinearLayout>
If you want to have two text boxes, you can nest a second orientation="vertical" and LinearLayout after the ImageView and then put the text boxes in there.
This works, but I have to admit I don't know why the RelativeLayouts didn't. For example, this blog post by Romain Guy specifically says that the RelativeLayout should. When I tried it, I never got it to quite work; admittedly I didn't do it exactly as he did, but my only changes were with some attributes of the TextViews, which shouldn't have made that much of a difference.
Here's the original answer:
I think you're confusing Android with all those somewhat contradictory instructions in RelativeLayout. I reformatted your thing to this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:src="#drawable/icon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_centerVertical="true"
android:text="Blah!"/>
</RelativeLayout>
And that works fine. I removed many of your redundant android:layout_alignParentxxx because they weren't necessary. This view now comes up with the picture in the top left corner and the text vertically centered next to it. If you want the picture vertically centered as well, then you can't have the RelativeLayout be on android:layout_height="wrap_content" because it's trying to make itself no taller than the height of the picture. You'd have to specify a height, e.g. 80dp, and then set the ImageView to a fixed height like 60dp with android:scaleType="fitXY" to make it scale down to fit properly.
Was stuck on a similar issue for a while, but found this from CommonsWare:
"When you inflate the layout, use inflate(R.layout.whatever, parent, false), where parent is the ListView."
Works but only when you set the height of the row to a specific value (ie you can't use wrap_content).
Baseline directive would do it, but ImageView simply does not support baseline alignment as of today. You can work around this by creating a subclass of ImageView, override the getBaseline() method and return the height of the image.

Categories

Resources