OK, here's ANOTHER question about positioning objects in tables in Android, but nothing I've found on Stack has helped.
I want the ImageView in the XML below to be left aligned in its cell. No matter what I've tried, though, it won't do this (it's always centered). The layout_width and layout_weight are set as they are to control the position and sizes of the cells themselves. Maybe these settings are making it impossible to left align the ImageView in its cell, though.
android:layout_gravity="left" and android:gravity="left" didn't work in either the ImageView tag or the TableRow tag. One kind of kludgy solution that seems to work is to add a blank TextView in a third column, to force the 2nd column holding the ImageView to be exactly the width of the ImageView's bitmap. However, I'd prefer not to have to do this, especially since different rows may contain bitmaps of different widths.
<TableLayout
android:id="#+id/scoreTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" >
<TableRow
android:id="#+id/thisWeek"
android:layout_width="wrap_content"
android:layout_height="fill_parent" >
<TextView
android:id="#+id/thisWeekText"
android:layout_width="0px"
android:layout_height="30dp"
android:layout_weight="35"
android:gravity="right"
android:paddingRight="30px"
android:text="#string/thisWeek"
android:textStyle="bold" />
<ImageView
android:id="#+id/chevron1"
android:layout_width="0px"
android:layout_height="20dp"
android:layout_weight="65"
android:layout_marginLeft="0px"
android:src="#drawable/doser_scale4a"
android:visibility="visible" />
</TableRow>
I replaced the TextViews with ImageViews, using bitmaps of the text that was in the TextViews. This was OK for me because that text won't be changing, though I guess if it did I could create images for all possible text and switch between those images.
This was not an ideal solution, since I assume using bitmaps instead of text uses more memory, and making bitmaps for my text required a little time and effort and some sacrifice of ease and flexibility of changing the text, if that is desired at some point, but I couldn't figure out how to make this work with TextViews. Android definitely seems limited in this way, since it shouldn't be that difficult to align text any way you want in a table cell, should it?
Each "cell" of the TableRow is a View, so you could put a LinearLayout (with your preferred gravity) and put inside this LinearLayour your image.
Related
I have rows (of horizontal LinearLayout) with a TextView at the end that displays time. An this is how it looks:
Now I need the suffix (am/pm) in all rows to be aligned vertically. This is not the case in the above layout, as you can see, the last row is misaligned as the displayed time is longer.
I achieved this using the tab character \u0009. This means I would set the text to be for example "7:21\u0009\u0009pm". This produces desired result as show below:
However, I need to know if (1) this is the most efficient way and (2) that this would work on all android devices. If there is an alternative way to achieve this please let me know.
And here is an XML layout of a row for your reference:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/prayer_time_row_height"
android:layout_marginLeft="48dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Today"
android:textColor="#color/material_light_secondary_text"
android:visibility="invisible" />
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Event"
android:textColor="#color/material_light_primary_text" />
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="12:06\u0009\u0009am"
android:textColor="#color/material_light_primary_text" />
</LinearLayout>
BONUS
Bonus points for pointing out a way to vertically align the hour-minute separator, i.e., colon character.
Maybe using tabs is the most efficient, but the gap is pretty big and not configurable. If you need all those rows in a single view group, you may try to check out RelativeLayout: align am/pm vertically on common left, and put hours to the left and on the baseline. This is the most flexible way, since you can control relative positions and margins, but computation-wise it's less efficient because it requires extra calculation upon laying out elements.
As per aligning colons — in most fonts (not just monospace) digits are designed to take equal space, so just align the numbers on the right (e.g. in relative layout) and it should do.
For the colon character, you could try using the character "\uee01" instead of ":". This is what google does with the clock in the lock screen.
https://github.com/android/platform_frameworks_base/blob/master/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java#L247
You can use a 2-column TableLayout. The first column is the time without AM/PM and the second column is just the AM/PM. Set the gravity of the first column to "end" or "right" and the times will be lined up at the colons if you are using a fixed width font.
I am trying to create a table/grid for some items within my app and I would like to have a border around each cell to divide the items up and have a coherent association of the setting with the item. This app will be used in an industrial setting where there may be people unfamiliar with Android that need to use this, thus trying to make it as easy as possible.
The table/grid will contain TextView, EditText, Spinner, and Button, and will also be scrollable (via ScrollView parent).
I read about the GridView and found that it (seems) to only be able to get items programmatically, please correct me if I am wrong. I felt that this was unnecessary since I know what items I want and where. Also, I have not tried adding items to a layout programmatically yet so I figured I would try the other options first. Also, the GridView documentation does not say one way or the other if border lines are automatically shown, or if you can have them shown at all.
I started with a TableLayout and was able to get everything except the border lines to work. I tried android:divider to get the lines but that didn't work. One thought I had was to create a bunch of TextViews with black backgrounds and ~2dp widths/heights to make my own border lines. This feels like a huge waste though. Then I also read the TableLayout documentation and found this: "TableLayout containers do not display border lines for their rows, columns, or cells."
I then tried the GridLayout and had the same results as the TableLayout. I tried padding and margins, neither worked. Also, the GridLayout documentation states: "The grid is composed of a set of infinitely thin lines that separate the viewing area into cells."
My questions are:
Is there an attirbute that I missed in TableLayout or GridLayout that will give me border lines via the xml?
If no, then will the GridView give me the lines I want?
Will I be able to add all the perviously mentioned items I want to the GridView?
I was actually able to achieve the desired look by setting the android:background="#000000" within the GridLayout view and then in the child items I set the android:background="#8CDD81" (just some green color) and combined with android:layout_margin="2dp" I was able to get the "grid" lines that I wanted. Thanks to CommonsWare though for getting me thinking in a new direction that turned into a solution.
EDIT:
This does not work quite as anticipated. You need the android:layout_alignLeft/Right which are only available via RelativeLayout in order to get just the right width on the child items. Haven't tested this yet using this idea, child items within RelativeLayout within GridLayout.
Is there an attirbute that I missed in TableLayout or GridLayout that will give me border lines via the xml?
No.
If no, then will the GridView give me the lines I want?
No.
Will I be able to add all the perviously mentioned items I want to the GridView?
Yes, though how well something like a Spinner will work, I can't say.
The simplest way, off the top of my head, to give you the lines you seek is to have each cell of the TableLayout or GridLayout be some container containing the widget(s) for that cell, where you give the container a background that is your line. A ShapeDrawable could be defined in XML for that background, which will be nicely resizeable based upon the actual requirements of the cell.
For future visiters this is how I did it with TableLayout:
table.xml
<TableLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#969696">
<!-- table heading -->
<TableRow>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:background="#d2d2d2"
android:layout_margin="1dp"
/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:background="#d2d2d2"
android:layout_margin="1dp"
/>
</TableRow>
<!-- table data -->
<TableRow>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ahtisham"
android:layout_margin="1dp"
android:background="#f1f1f1"
/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kashmir"
android:layout_margin="1dp"
android:background="#f1f1f1"
/>
</TableRow>
</TableLayout>
I'm trying to achieve the following layout: a fixed width TextView aligned to the left of its parent, with the text inside it aligned to the right side of that TextView (that's why fixed width, can it be done other way?) and the rest of the parent is filled with a drawable (simple line). Like this:
It's a ListView containing 2 types of rows and the layout for the rows with lines is quite trivial - LinearLayout with TextView and ImageView (I can post the exact code later if needed). And I'm getting a warning that it could be replaced with a single TextView with compound drawable.
I'm all for optimization so I really tried to follow that advice. Unfortunately I wasn't able to get the same result - the line is either constrained to TextView's width or text is aligned to the right side of the ListItem, now to fixed position.
Am I missing something?
Edit: Apparently it is not actually possible and since there are some other complications (the drawable is now a level-list drawable, which is not always a line and sometimes it has a non-fixed height that I have to set) I will leave it as it is now - linear layout, containing one TextView and one ImageView.
I don't think that you're missing anything. The TextView compound drawable features are not very customizable and in general are not worth the time you spend trying to get them to look right. Some lint warnings are a little overzealous and premature.
The optimization that the lint refers to is something that is better attributed for a fixed size image. In your case, the line has to stretch the rest of the screen length and as such it is not something that can be done with a textview with compound drawable. This kind of lint warning is more of a suggestion rather than something that MUST be done and is detected by just checking for a linear layout with only a textview and an imageview rather than checking what would need to go in the image view. If you already have it working the way you did it I think you should leave it alone.
Your view create from this -
<?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="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/time"
android:layout_width="#dimen/today_time_width"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:gravity="right"
android:layout_marginRight="5dp" />
<ImageView
android:layout_gravity="center"
android:id="#+id/border"
android:layout_width="match_parent"
android:layout_height="#dimen/today_current"
android:src="?attr/item_boundary" />
</LinearLayout>
There is no way to achive this using only standart TextView. If you really want to reduce view count you can create your custom TextView class, set layoutWidth to matchParent and draw line from text end to right border. But it's not worth to be doing. Some extra views won't slow your list.
I am not sure if you will be able to achieve what you really want to , but then you could change the linear layout in the link you posted to something like this:
<RelativeLayout
android:id="#+id/relTrial"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtTime"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="right"
android:text="12:45 AM"
android:layout_alignParentLeft="true"/>
<LinearLayout
android:id="#+id/lnrSep"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:gravity="bottom"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:orientation="horizontal"
android:background="#android:color/darker_gray"
android:layout_toRightOf="#+id/txtTime"
android:layout_alignParentRight="true"></LinearLayout>
</RelativeLayout>
This way the time text will be right aligned although being at the left side, and the line will also be visible.
Hope that helps.
If I got you right, you want to add bottom border to list view item?
What about to try this:
android:drawableBottom="#drawable/line"
I have a listview where each item has 2 images, one on the right and the other on the left. Between them there is a textview that is filled from data. If text is long then it can continue down but there is a lot of free space just as you can see in the image. I want to use this space also to display text. I have been looking around the web and I have seen things like this http://code.google.com/p/android-flowtextview/downloads/detail?name=FlowTextDemo.zip&can=2&q= but this is useless. I don't want to lose the control of the images because I need their click method. What is the best way to do it? I have thought that maybe I can put a textview between images and an other down and when the first is filled continue in the second one but how can I know how many letters can keep the first textview?
I don't understand why FlowTextView (that you linked to) won't work for you. It's derived from RelativeLayout and flows text around any child views. The child views can be your images, positioned as you normally would in a RelativeLayout. Their onClick methods should work just fine.
<com.pagesuite.flowtext.FlowTextView
android:id="#+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/the_text >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="onTopLeftClick"
android:src="#drawable/top_left_image" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="onTopRightClick"
android:src="#drawable/top_right_image" />
</com.pagesuite.flowtext.FlowTextView>
You will need to set the text in code, or else extend FlowTextView and define your own custom attribute(s) to do it from xml.
I want to draw an image on the left of an EditText. I don't want the image appear insde the EditText though.
I use this:
<EditText
android:id="#+id/firstNameTxt"
style="#style/UserInfoInputs"
android:drawablePadding="20dp"
android:drawableLeft="#drawable/first_name" >
</EditText>
It displays the image inside of the EditText. However I use this on TextView and it works fine:
<TextView
android:id="#+id/positionValue"
style="#style/userInfo"
android:drawableLeft="#drawable/position" />
How this can be done for an EditText?
try this
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/go_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="#drawable/icon"
/>
<EditText
android:id="#+id/url"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:lines="1"
android:layout_weight="1.0" />
</LinearLayout>
let me know if this works.
The difference between the two use-cases you describe are simple. There is no difference. With an EditText, there are lines that are easily discernible. With a TextView there is not. Try setting the background property of the textview, and you'll see that the drawable is, in fact, drawn on the left side, but still 'inside', the TextView.
The simplest way to accomplish your task (as described) is to utilize an ImageView. Depending on what ViewGroup (LinearLayout, RelativeLayout, etc) you're using, the code may be a bit different; so, update your question with the appropriate info and I'll make my answer a bit more specific.
I should note that, another method you could use is to create your own custom component, which is really very easy to do. See this article Custom Components | Android Developer, be sure to scroll down to the Compound Controls heading title "Compound Controls". This would be especially helpful when this is a 'common' format of controls that you'll use often (I.E. you have an image next to a TextView throughout your app).
That is because the background part of the EditText stretches behind the entire contents of the view, including the drawables.
If you are using a RelativeLayout you can just add a separate ImageView:
<ImageView
layout_width="wrap_content"
layout_height="wrap_content"
layout_toLeftOf="#+id/firstNameTxt"
src="#drawable/first_name"
other imageview attributes as neccessary...
/>
<EditText
android:id="#+id/firstNameTxt"
style="#style/UserInfoInputs"
/>
Or if you use another kind of layout, create a LinearLayout-wrapper:
<LinearLayout
layout_width="wrap_content"
layout_height="wrap_content">
<ImageView
layout_width="wrap_content"
layout_height="wrap_content"
layout_toLeftOf="#+id/firstNameTxt"
src="#drawable/first_name"
other imageview attributes as neccessary...
/>
<EditText
android:id="#+id/firstNameTxt"
style="#style/UserInfoInputs"
/>
</LinearLayout>