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:
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 :
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.
I see these problems in your screenshot:
alignment of the columns themselves is different
alignment of text in the columns is centred, not right-aligned
you probably want to use a fixed number of decimal points in your numeric output
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:
Format Float to n decimal places
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.
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:
Not really dots, but that's something to start from, hope that helps.
#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
Related
Following snippet from my layout xml:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/fragment_home_info_card_car_position"
android:maxHeight="300dp"
>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="10dp">
<include
android:id="#+id/fragment_home_filter_chips"
layout="#layout/selection_chips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp" />
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
wraps the content correctly, it wraps the include and doesn't exceed the height. But the content of the include get cut off approx 100dp down when scrolling. This may be because there is a rather slow fill of the include (in the background with a lifeCyclescope coroutine).
In my effort to overcome this I just constraint the height to a fixed value like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_constraintTop_toBottomOf="#id/fragment_home_info_card_car_position"
>
...
Now suddenly the height of the include was correctly justified, and I could scroll down the bottom of it, but of course not constrained to the content if it was smaller than 300dp...
My question is, how do I constraint the height as in the first snippet and is sure that my include is fully expanded (viewed expanded inside the scrollview) ?
Do maxHeight do some "magic" that isn't quite well here ?
I want to add number at specific word in eclipse, I mean replace "btn" and add to him number automaticly like after 1 write 2 after 3 after 4... without do it manually
<Button
android:id="+#id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn"
android:padding="10dp" />
<Button
android:id="+#id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn"
android:padding="10dp" />
<Button
android:id="+#id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn"
android:padding="10dp" />
like that it add number after the specific word
<Button
android:id="+#id/btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn1"
android:padding="10dp" />
<Button
android:id="+#id/btn2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn2"
android:padding="10dp" />
<Button
android:id="+#id/btn3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/btn3"
android:padding="10dp" />
and if we cant with eclipse, can sombody give me a link of something like that :)
I don't think this is possible within the Eclipse editor. The only editor I could think of that might be able to do this is Sublime Text. It does allow you to highlight all instances of a word and edit them at the same time, but after some quick searching, it doesn't look like you can edit them to have increasing numbers like you want.
If there were enough instances that you wanted to change, and you felt like you might use it often, you could always write a small program that does this for you.
I've been using Bauerca's drag-sort-listview, it's easy enough to setup and use, but I'm having an issue where the entire list item is the handle instead of just the drawable I set as the handle. Here's the appropriate XML:
<com.mobeta.android.dslv.DragSortListView
xmlns:dslv="http://schemas.android.com/apk**/res-auto"
android:id="#+id/paletteView"
android:layout_width="match_parent"
android:layout_height="match_parent"
dslv:drag_handle_id="#id/dragHandle"
dslv:sort_enabled="true"
dslv:remove_enabled="false"
dslv:drag_start_mode="onDrag" />
And here's the XML for the list item layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Color View has to be set to specific width/height or else it won't show at all -->
<TextView
android:id="#+id/paletteItemText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toLeftOf="#id/dragHandle"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
<View
android:id="#+id/colorView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/paletteItemText" />
<ImageView
android:id="#id/dragHandle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:src="#drawable/drag_handle" />
Notice the ImageVIew has the id of dragHandle which is used by the drag-sort-listview, that id isn't used anywhere else.
The biggest problem with this is it's making it so I can't press or long press the list item anymore.
AHAH!!! I figured it out, so the issue was actually quite simple, in the XML where I have this: xmlns:dslv="http://schemas.android.com/apk**/res-auto"
It should have been this: xmlns:dslv="http://schemas.android.com/apk/res/com.torygaurnier.openpalette"
I'm new to android development, so I didn't realize this, com.torygaurnier.openpalette is my package name, so the namespace has to point to your own package name.
I am trying to write a XSLT file that will process an Android Activity layout xml file and create an HTML equivalent.
In creating/testing out the xslt file, I am using the eclipse xslt tools.
One of the roadblocks on this path, is that many values are not held in the Android layout file directly (such as string/text values) but are instead held in a seperate xml file located in the 'values' folder
I have been trying to use the xslt function 'document' to open the strings.xml file but without success.
Q) Are there any eclipse permissions that I need to enable to allow the xslt document function to operate?
Q) Is there something missing in my understanding of how the document function should operate?
The line which is contained within the TextView template (in the xslt file) that is trying to access the android strings.xml file, is:
<xsl:value-of select="document('../values/strings.xml')/String[#name=substring-after(#android:text,'/')]" />
The layout file is in the res/layout folder
The xslt is in a res/xsl
folder.
The strings.xml file is in the res/values folder
Here are the code samples:
Android XML Layout snippet:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- This is the full screen vertical layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<!-- This is the main content vertical layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="#dimen/mainHeadingIndent" >
<!-- This is the Status Section Vertical content layout -->
<TextView
style="#style/HeadingTextStyle"
android:id="#+id/textView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:text="#string/Status"/>
**The rest of the layout file is intentionally omitted**
Here is the XSLT file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:android="http://schemas.android.com/apk/res/android">
<xsl:output method="html" version="4.0" encoding="iso-8859-1"
indent="yes" />
<xsl:template match="/">
<html>
<head>
</head>
<body>
<xsl:for-each select="LinearLayout">
<xsl:call-template name="LinearLayout">
</xsl:call-template>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name="LinearLayout">
<xsl:variable name="width">
<xsl:value-of select="#android:layout_width" />
</xsl:variable>
<xsl:variable name="height">
<xsl:value-of select="#android:layout_height" />
</xsl:variable>
<xsl:variable name="margin">
<xsl:value-of select="#android:layout_margin" />
</xsl:variable>
<xsl:variable name="orient">
<xsl:value-of select="#android:orientation" />
</xsl:variable>
<xsl:variable name="pos">
<xsl:number value="position()" format="1" />
</xsl:variable>
<div div_pos='{$pos}' Width='{$width}' Height='{$height}' Margin='{$margin}'
Orient='{$orient}'>
<xsl:for-each select="LinearLayout">
<xsl:call-template name="LinearLayout">
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="TextView">
<xsl:call-template name="TextView">
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="ImageButton">
<xsl:call-template name="ImageButton">
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="Spinner">
<xsl:call-template name="Spinner">
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="Button">
<xsl:call-template name="Button">
</xsl:call-template>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template name="ImageButton">
<div id="{#android:id}">
<xsl:comment>
ImageButton
</xsl:comment>
</div>
</xsl:template>
<xsl:template name="TextView">
<xsl:variable name="pos">
<xsl:number value="position()" format="1" />
</xsl:variable>
Text field =
<xsl:value-of select="#android:text" />
<xsl:variable name="txt">
<xsl:choose>
<xsl:when test="contains(#android:text,'/')">
<xsl:value-of select="document('../values/strings.xml')/String[#name=substring-after(#android:text,'/')]" />
<!--
<xsl:value-of select="substring-after(#android:text,'/')" />
-->
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#android:text" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<div id="{#android:id}">
<xsl:comment>
TextView Element
</xsl:comment>
<p>
Text pointer is: <xsl:value-of select="$txt" />
</p>
<!-- <p>Text pointer is:<xsl:copy-of select="$txt"/></p> <xsl:value-of
select="document('../values/strings.xml')/String[#name=$txt]" />
<xsl:value-of select="substring-after(#android:text,'/')" />
-->
</div>
endoftext
<br />
</xsl:template>
<xsl:template name="Spinner">
<div id="{#android:id}">
<xsl:comment>
Spinner
</xsl:comment>
</div>
</xsl:template>
<xsl:template name="Button">
<div id="{#android:id}">
<xsl:comment>
Button
</xsl:comment>
</div>
</xsl:template>
</xsl:stylesheet>
You need to include the document's root element in the XPath (this is very easy to forget):
<xsl:value-of select="document('../values/strings.xml')/*/String[#name=substring- after(#android:text,'/')]" />
Well, I've solved it.
The big issue is that when xslt fails, it generally fails silently .... ie no errors
The issue turned out not to be the document function per-se. It was the selection criteria that followed the document function. This had a problem such that there was no selected nodes and hence no output from the statement. This all made it look like the document function was not working.
The big change was that the substring-after clause wasn't/isn't being evaluated against the the right attribute. By splittingg the substring clause up, it started to work.
As they say, it's "FM" (flipping magic)!
Here is what I replaced the document line with:
<xsl:variable name='string_value'>
<xsl:value-of select="substring-after(#android:text,'/')" />
</xsl:variable>
<xsl:value-of select="$string_value"/>
<xsl:value-of select="document('../values/strings.xml')/*/string[#name=$string_value]"/>
This sucessfully pulled the correct value out of the strings.xml file.
i have used table layout for my one xml
i am trying to add one background image as follows:
android:background="#drawable/myimg"
den i am getting error like
02-28 11:58:57.713: E/AndroidRuntime(850): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test/com.test.Scan}: android.view.InflateException: Binary XML file line #3: Error inflating class android.widget.TableLayout
i have even tried like following:
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bkg1">
<TableLayout
android:id="#+id/linearLayout1_tblLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TableRow
android:id="#+id/linearLayout1_tblLayout1_tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" >
......
</TableRow>
</TableLayout>
</LinearLayout>
then also i am getting same error.
please some one helppp me.!
Thank you.
sorry guyz , it was my mistake
i was using jpeg format's file.
when i used .png file.
i managed to solve my problem..
YOU CAN SET ONLY .PNG FORMAT'S FILE TO LAYOUT