Vertically aligning suffix with tab space in android TextView - android

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.

Related

Max lines with height set as wrap_content

I have two TextViews in a vertical LinearLayout, one serves as a display for a book's title and the latter as a display for the book's author(s).
I need the first to have wrap_content as its height, so it takes a good part of the linear layout. However, I want it to cap out at three lines max, so that there is still some space left for the second text view;
and I need the latter to fill the remaining space (0dp and layout_weight=0dp).
I want to use specific configuration so that the author view will be always right after the title view (on its bottom).
Something like this, however the max_lines do not kick in.
I tried to set max_lines to 3 and wrap_content for the first view height, but it seem that max_lines is ignored if height is set to wrap_content.
I also tried to circumvent the problem by sort of cheating and adding a max_height, but then the two views may be spaced apart from one another.
At last I tried to convert the linear layout to a constraint layout, to see if I could access some other layout settings to no avail.
Any help?
It seems to be working fine on my side with android:max_lines="3" even with wrap_content
This is just a test layout I created
<TextView
android:id="#+id/textview1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:maxLines="3"
android:textSize="#dimen/_13sdp"
android:textStyle="bold"
android:text="Very Very Very Very Very Very Very Very Very Very Very Very Long Text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textview2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:text="Very Very Short Text "
app:layout_constraintStart_toStartOf="#+id/textview1"
app:layout_constraintTop_toBottomOf="#+id/textview1" />
Screenshot ->
Hope this helps! :)
Replacing app:max_lines with android:max_lines seems to have fixed the issue.

Android - Equal column width layout for any size text

I'm quite new to android. I wanted to show cards in a tabular form. I want 2 columns which should be exactly equal in length (even if the size of the content in one of the column increases).
For example, it should be like Play Store or Google Keep. My card will have 2 lines of data. First for Title and second for Description.
I tried many layouts; TableLayout, GridLayout etc. but neither worked actually. Lastly I read this SO post but it doesn't work if text size on my card increases.
Any idea on how this can be done? It will be a bonus if the Description text ellipsizes at end.
If I understand you well enough:
Try using a LinearLayout and setting the layout_weight of the items inside the layout. So you'll have something like:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Card
android:id="#+id/card1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Card
android:id="#+id/card2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
Then if you wanted to perhaps have multiple things in the columns just make those card items additional LinearLayouts of vertical orientation.

Can't Align ImageView in Table Cell in Android

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.

Android RelativeLayout strange behaviour

I'm learning the relative layout and wrote a little test layout to simulate a login page:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView android:id="#+id/labelUsername"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="username:"
android:layout_centerVertical="true"/>
<EditText android:id="#+id/txtUsername"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:hint="input username here"
android:layout_toRightOf="#id/labelUsername"
android:layout_alignBaseline="#id/labelUsername"/>
<TextView android:id="#+id/labelPassword"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="password:"
android:layout_below="#id/txtUsername"
android:layout_alignParentLeft="true"/>
<EditText android:id="#+id/txtPassword"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:hint="input password here"
android:layout_below="#id/txtUsername"
android:layout_alignLeft="#id/txtUsername"
android:layout_alignBaseline="#id/labelPassword"/>
</RelativeLayout>
What I want is putting the Username Label and Textfield above the Password Label and TextField. But the result is reverted, password are above!
I think the problem is the "android:layout_below" property in labelPassword, if I set it to below labelUsername, it works, however because the textfield is much bigger than label, the both textfields are in this case overlayed. So i try to make the labelPassword below the txtUsername, but it performs strange, I don't understand.
By the way, is there any guideline when I build layout with Relative Layout?
What should I put there at first?
What should I put at last?
thanks!
I think what you are trying to achieve here is trying to get both the username and password fields vertically centered, and the password field below the username field. The error in your layout is that you only tell the username textview and edittext to center vertically, and relative layout centeres the layouts after having arranged them. So your username field is centered, while the password is left on top.
What you should do is tell the parent(RelativeLayout) to vertically center all its child elements.
For that simply remove this attribute from the "username" TextView element :
android:layout_centerVertical="true"
And add this attribute to your RelativeLayout element:
android:gravity="center_vertical" //tells RelativeLayout to vertically center all child elements
In this case i would recommend using a LinearLayout but you can continue using RelativeLayout for now. Hope it helps!
To answer your concrete question, it's because android:layout_centerVertical="true" rule you are applying to labelUsername.
It seems that the relative position doesn't work well, when the elements you are refering to, are centered. And it also doesn't make sense, in this case, because you probably want the whole form centered, not only the username fields and then put the password bellow.
You can put the elements in a containing element (another relative layout, or linear layout, or table layout, etc.) and center that element. That works. Or to center all the contents, you can add android:gravity="center" to the containing layout.
As you go through the different Layouts you will find that while Relative layout feels the most "natural" if you're used to positioning things via CSS, for example (with absolute or relative positions) the situation you're describing here calls for either Linear or Table layout. Table layout is probably your best bet for anything "form" related. Your table elements (columns) should have a layout_span attribute that details how many columns to go across (it's sort of analog to colspan in HTML).
I'm not sure what specifically is going wrong in your RelativeLayout above, and I'm sure that with adequate trial and error you could get it to do roughly what you want, but I strongly advise you to use the right tools for the job.
LinearLayout is also a terrific tool (which you should remember can be nested indefinitely). Give your Layout a weightSum and then each item can have a layout_weight (they should add up to be the sum), while their layout_width should be 0dp (it's not intuitive, but that's how it works). That's also a terrific way to make things sit where they ought to.
Lastly the answer to the correct order in RelativeLayout is that the items are Z ordered from bottom to top, so the later an item appears in the sibling order, the higher its Z order is. Otherwise, their order is irrelevant.

Align overlapping text in TextViews

I want two TextViews to overlap such that individual letters will overlap perfectly (i.e. you can't even see there is another TextView on the screen). Here is the relevant part of my layout:
<com.testing.android.animals.OutlinedTextView
android:id="#+id/label_left_name"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Elephant"
android:layout_alignTop="#id/picture_left"
android:layout_centerHorizontal="true"
android:textColor="#ffffff"
android:textSize="40dp"
android:background="#99000000"
></com.testing.android.animals.OutlinedTextView>
<com.testing.android.animals.OutlinedTextView
android:id="#+id/label_left_letter"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="E"
android:layout_alignBaseline="#id/label_left_name"
android:layout_alignLeft="#id/label_left_name"
android:textColor="#ffffff"
android:textSize="40dp"
android:background="#99ffffff"
></com.testing.android.animals.OutlinedTextView>
When rendered, it looks like this:
Notice the individual "E" (in light gray) is aligned too high.
What can I change in the layout that will get them to overlap better?
The issue is that the p makes the bottom of the full word textview taller. and since you have wrap_content as the height, the two heights of the textviews are different.
If you set the height of each textview to a specific size (the same size), they should align.
But in general, i think your approach might be wrong - you may want to either look into spannable strings for formatting or, since it appears you are using a custom control anyway, have it do the formatting of the first letter. (here is an example of spannable strings: http://www.chrisumbel.com/article/android_textview_rich_text_spannablestring )

Categories

Resources