1

I have a ListView in which I show some details including prices. I need to show the total sum at the bottom of the ListView. So far I've tried with a ListView to show the details and a table layout with a single row to show the total, the problem is that I can't get them to be aligned.

Do you know I can get a result like this one:

enter image description here

I know that the amount for "Cache" isn't the Total, but the idea is the same. All these rows show their amounts properly aligned and the space between the labels and the amount are filled with dots and this is the result I'd like to achieve, so I would be very grateful if you could help.

This is the layout I'm currently using for my activity

<?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" >

    <LinearLayout       
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"        
        android:orientation="vertical" >

        <ListView
            android:id="@+id/detailsListView"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:dividerHeight="1dp" >
        </ListView>
    </LinearLayout>

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"             
        android:stretchColumns="0,1" >
        <TableRow android:padding="1dp" >

            <TextView
                style="@style/Control.Label.Large.Stretched"
                android:layout_weight="1"
                android:text="@string/total" />

            <TextView
                android:id="@+id/totalSumTextView"
                style="@style/Control.TextView.Large.Stretched"                
                android:layout_weight="1"/>
        </TableRow>

        <TableRow android:id="@+id/tableRow3" />
    </TableLayout>
</LinearLayout>

An this is the layout for each item in the ListView :

<?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" >

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:stretchColumns="0,1" >

        <TableRow android:padding="1dp" >

            <TextView
                style="@style/Control.Label.Small.Stretched"
                android:layout_weight="1"
                android:text="@string/item_quantity" />

            <TextView
                android:id="@+id/itemQuantityTextView"
                style="@style/Control.TextView.Small.Stretched"
                android:layout_weight="1" />
        </TableRow>

        <TableRow android:padding="1dp" >

            <TextView
                style="@style/Control.Label.Small.Stretched"
                android:layout_weight="1"
                android:text="@string/item_unit_price" />

            <TextView
                android:id="@+id/itemUnitPriceTextView"
                style="@style/Control.TextView.Small.Stretched"
                android:layout_weight="1" />
        </TableRow>        

        <TableRow android:padding="1dp" >

            <TextView
                style="@style/Control.Label.Small.Stretched"
                android:layout_weight="1"
                android:text="@string/item_total" />

            <TextView
                android:id="@+id/itemTotalTextView"
                style="@style/Control.TextView.Small.Stretched"
                android:layout_weight="1" />
        </TableRow>
    </TableLayout>

</LinearLayout>

Each Item should look something like this :

enter image description here

And it's the sum of those totals that should be displayed below the ListView

This image is from what I'm trying to do. It's in Spanish, but it should give you a better picture of what I'm saying. As you can see the row below the ListView is not aligned with the values in the above it.

enter image description here

Axel
  • 1,674
  • 4
  • 26
  • 38
  • Pass your "Total" title and "total value" as a last element in adapter of list view. – Chitrang Oct 07 '14 at 18:11
  • Add a footer view that uses the same layout as your ListView cells. – Dan Harms Oct 07 '14 at 18:12
  • @Chitrang that wouldn't work, because I want the **Total** row to be always visible – Axel Oct 07 '14 at 19:56
  • @dcharms how can I add a footer? – Axel Oct 07 '14 at 19:56
  • If you want the total to always be visible, a footer is not the way to go. You will need to add a view below the ListView that contains a TextView with the same right margin as the rows in your ListView. – Dan Harms Oct 07 '14 at 20:07
  • OK. I'll do that,but just to give you better idea each item in my ListView is similar to the "storage" item in the image I posted. – Axel Oct 07 '14 at 20:09
  • Edited my question, please take a look – Axel Oct 07 '14 at 20:25
  • You're right. The sum of Totals (`totalSumTextView`) is not aligned with the Totals from the ListView (`itemTotalTextView`). I'll post an image to give you a better idea. – Axel Oct 07 '14 at 20:58
  • @RichardLeMesurier I've added an image of what I've done so far. I'm still trying to understand why this isn't working. – Axel Oct 07 '14 at 21:11
  • @Axel updated answer to show how I would be doing this. Sorry can't get the dots to work, but I normally just use the method similar to Arian's. – Richard Le Mesurier Oct 07 '14 at 21:53

3 Answers3

2

I think that for what you want to do you should make a custom layout for your ListView, and in that layout make a TextView element aligned to the right.

Your XML would contain something like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="14.99$" />
</RelativeLayout>

That TextView is aligned to the right, add anything you want, then use the layout for every element in the ListView, all the TextViews should then be aligned.

The android:layout_alignParentRight="true" attribute makes the TextView (or any view with that attribute) be aligned to the right (inside it's parent).

Edit

For the dots you could use something like in this answer: https://stackoverflow.com/a/10282253/3290971

The full layout file would be something like:

<?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="wrap_content">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Item"
        android:textSize="20dp" />

    <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:layout_toRightOf="@id/item"
        android:layout_toLeftOf="@+id/price"
        android:layout_alignBaseline="@+id/price"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="14.99$"
        android:textSize="20dp" />
</RelativeLayout>

The result would be:

Layout result of the previous XML

Not really dots, but that's something to start from, hope that helps.

Community
  • 1
  • 1
ArianJM
  • 676
  • 12
  • 25
2

I see these problems in your screenshot:

  1. alignment of the columns themselves is different
  2. alignment of text in the columns is centred, not right-aligned
  3. you probably want to use a fixed number of decimal points in your numeric output
  4. row of dots

1) Alignment of columns

I think this is to do with using the TableLayout. As you can see in my previous example, I prefer to use RelativeLayout. When you get the hang of it you will see it is very powerful.

I would use my example below as a starting point for a single row, and make 2 more similar rows below that using the layout_below tag to position them below the row above.

Like this (long) example:

<?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="wrap_content"
    android:padding="16dp" >

    <!-- ROW 1 -->

    <TextView
        android:id="@+id/tvLabel1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Cantidad Pedida" />

    <TextView
        android:id="@+id/tvSizeMb1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/tvLabel1"
        android:layout_alignParentRight="true"
        android:text="12.0" />

    <!-- ROW 2 -->

    <TextView
        android:id="@+id/tvLabel2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tvLabel1"
        android:text="Unidad Medida" />

    <TextView
        android:id="@+id/tvSizeMb2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/tvLabel2"
        android:layout_alignParentRight="true"
        android:text="CJA" />

    <!-- ROW 3 -->

    <TextView
        android:id="@+id/tvLabel3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tvLabel2"
        android:text="Precio Unitario" />

    <TextView
        android:id="@+id/tvSizeMb3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/tvLabel3"
        android:layout_alignParentRight="true"
        android:text="157.6036" />

</RelativeLayout>

2) Right-align the text within the columns

Your TextView items are being centred in the columns, due to using the layout_weight="1" tag. If you instead use the RelativeLayout as described above, the text views themselves are being set to the right.

3) Fixed format for your decimal numbers

To correctly align numbers, it helps to use a fixed number of decimal points. In your case it looks like you might need 4 decimal places.

When you set the values, you are probably doing something like:

myTextView.setText(String.valueOf(myNumber);

Instead of that, use the String.format() method to set the number of decimal places:

myTextView.setText(String.format("%.4f", myNumber);

For more info on that, check out this post:

4) Row of dots between text fields

I was hoping to get something working with an XML Drawable that uses the stroke style, but ran into some strange issues. You might want to play around with that concept a bit.

However what I've done many times in the past is similar to what ArianJM recommends.

<View
    android:layout_width="0dp"
    android:layout_height="1px"
    android:layout_alignBaseline="@+id/tvLabel1"
    android:layout_toLeftOf="@+id/tvSizeMb1"
    android:layout_toRightOf="@+id/tvLabel1"
    android:background="#333"
    tools:ignore="PxUsage" />

Note the use of px instead of dp for the height attribute. This creates a sharper image, and by using a 1px value, the line is not very strong. You could improve this by using a slightly transparent colour for the line.


Previous answer

You could use a basic ListView to display your items. The list view can use a custom XML layout for each item, that aligns the text the way you want it to.

For example, here is a RelativeLayout that aligns 2 text fields in the way you want them to be aligned:

<?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="wrap_content"
    android:padding="16dp" >

    <TextView
        android:id="@+id/tvLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:text="Total" />

    <TextView
        android:id="@+id/tvSizeMb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="4.57MB" />

</RelativeLayout>

Then below your list view, you would want to display your "Cache" row. Use the same layout for this, and the items will align correctly.

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
  • 1
    What about the lines between the labels and the TextViews ? – eddy Oct 07 '14 at 19:51
  • I didn't mentioned anything about divider, but I did mention the lines(or dots) between the `Labels` and the `TextViews`. I'd be really nice if I could do display something like `"Total ......... $ 250"` – Axel Oct 07 '14 at 20:31
  • 1
    Thank you guys! I really wished I could mark all three answers because all of them help, but since the answer provided by @Richard was the most complete, I decided to mark it as the answer – Axel Oct 24 '14 at 00:27
1

@axel this is what I did to get a dotted line :

Create a xml file in the drawable folder and named dotted.xml. Copy and paste the following code:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >
    <stroke
        android:dashGap="3dp"
        android:dashWidth="3dp"
        android:color="@android:color/darker_gray" />
</shape>

and in your layout call the shape using the background attribute

 <View
        android:layout_width="fill_parent"
        android:layout_height="1dp"
        android:layout_toRightOf="@id/item"
        android:layout_toLeftOf="@+id/price"
        android:layout_alignBaseline="@+id/price"
        android:background="@drawable/dotted" />

In case the above code doesn't show the dotted line, add this to the View :

android:layerType="software"

Hope it helps

eddy
  • 4,373
  • 16
  • 60
  • 94