Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android text layout question: two textviews, side-by-side, with different layout alignments and weights

I'm still a bit of an Android noob, forgive me if this is simple and I'm just not seeing it.

There are two portions of text in a view that spans the entire width horizontally, but is only as high as one line of text. The left side must always be displayed in full, but should take no more horizontal space than it needs. The right side should be pushed over by the left side and fill up the remainder of the screen width. If the right side text is smaller than this width, the text should be right-aligned horizontally. If the text is greater than the width, it should scroll horizontally.

The text on the right side will be updated frequently and should slide up with new text when the app tells it (explaining the TextSwitcher in the layout).

I have tried two different layout styles. In both situations, I can get the left side to "push" the layout, the right side to scroll, but I can't figure out how to get the right side to right align. It is always left aligned. Here is a picture showing what is happening...

http://img10.imageshack.us/img10/5599/androidlayout.png

In addition (but less important), in my layout code I have android:fadingEdge="none" on the TextViews, but it still has a faded edge on the left and right side when it scrolls. Why is that?

Here are the two layouts I created, which yield the results shown, but not the results I want.

Using a horizontal LinearLayout...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayoutStatusBar"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="2px"
    android:background="#555555"
>
    <TextView
        android:id="@+id/TextViewTimer"
        android:textSize="18px"
        android:textColor="#FFFFFF"
        android:layout_gravity="left"
        android:layout_weight="0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0px"
        android:layout_marginRight="3px"
        android:text="Left Side"
    >
    </TextView>
    <TextSwitcher
        android:id="@+id/TextSwitcherDetails"
        android:inAnimation="@anim/push_up_in"
        android:outAnimation="@anim/push_up_out"
        android:layout_weight="1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginLeft="3px"
        android:layout_marginRight="0px"
    >
        <TextView
            android:id="@+id/TextViewDetails1"
            android:textSize="18px"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="right"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:fadingEdge="none"
            android:text="Right Side 1"
        >
        </TextView>
        <TextView
            android:id="@+id/TextViewDetails2"
            android:textSize="18px"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="right"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:fadingEdge="none"
            android:text="Right Side 2 - This is a really long text this is long and fun and fun and long"
        >
        </TextView>
    </TextSwitcher>
</LinearLayout>

So how do I get that text on the right side to right-align. Thanks!


EDIT:

I found the problem... There were a few things wrong. First, I discovered the difference between gravity and layout_gravity. I needed to use gravity to right-align the text.

I can't add any more links, so copy and paste the link below

thinkandroid.wordpress.com/2010/01/14/how-to-position-views-properly-in-layouts/

However, that didn't give me exactly the layout I wanted, because long lines of text will be right-aligned before scrolling and the front part of the message cannot be read until it loops around. What I needed to do was use three "columns" of views, with the weight on the middle (empty) view to be "1" while the others "0" so that it pushes the right-most text as far as possible to the right, while still maintaining left-alignment.

Next, I discovered that the width of a TextSwitcher is the same as the largest child TextView. This is a problem when switching from a long line to a short line using setText() because the middle column won't push the small text over to the edge. The solution is to use two setText()s. One to cause the fade-out animation, then push a runnable to run after the animation to set the text again to cause the fade-in animation of the new line.

Now my only problem is that when the fade-out animation runs on a long line of text, if it is in mid-scroll, it resets to the X=0 position before fading, so the effect is that it scrolls, jumps to the origin position, then fades out. Anybody know how to fix that?

(I removed the RelativeLayout code above since that was wrong, since this post is really long.)

Here is the working layout code...

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LinearLayoutStatusBar"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="2px"
    android:background="#333333"
>
    <TextView
        android:id="@+id/TextViewTimer"
        android:textSize="18px"
        android:textColor="#FFFFFF"
        android:layout_gravity="top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:layout_marginLeft="1px"
        android:layout_marginRight="4px" 
        android:text="Left Side"
    >
    </TextView>
    <View
        android:id="@+id/ViewSpacer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
    ></View>
    <TextSwitcher
        android:id="@+id/TextSwitcherDetails"
        android:inAnimation="@anim/push_up_in"
        android:outAnimation="@anim/push_up_out"
        android:layout_gravity="top"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:layout_marginRight="1px"
    >
        <TextView
            android:id="@+id/TextViewDetails1"
            android:textSize="18px"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:fadingEdge="none"
        >
        </TextView>
        <TextView
            android:id="@+id/TextViewDetails2"
            android:textSize="18px"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:marqueeRepeatLimit="marquee_forever"
            android:scrollHorizontally="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:fadingEdge="none"
        >
        </TextView>
    </TextSwitcher>
</LinearLayout>
like image 372
Conure Avatar asked Dec 27 '10 01:12

Conure


1 Answers

I found the problem! There were a few things wrong. First, I discovered the difference between gravity and layout_gravity. I needed to use gravity to right-align the text.

http://thinkandroid.wordpress.com/2010/01/14/how-to-position-views-properly-in-layouts/

However, that didn't give me exactly the layout I wanted, because long lines of text will be right-aligned before scrolling and the front part of the message cannot be read until it loops around. What I needed to do was use three "columns" of views, with the weight on the middle (empty) view to be "1" while the others "0" so that it pushes the right-most text as far as possible to the right, while still maintaining left-alignment.

Next, I discovered that the width of a TextSwitcher is the same as the largest child TextView. This is a problem when switching from a long line to a short line using setText() because the middle column won't push the small text over to the edge. The solution is to use two setText()s. One to cause the fade-out animation, then push a runnable to run after the animation to set the text again to cause the fade-in animation of the new line.

Unfortunately, horizontally scrolling the text looks terrible when the text switches every five to ten seconds. So I'm just letting it run off the screen.

like image 77
Conure Avatar answered Nov 15 '22 00:11

Conure