3

I have two textviews like this:

=======================
= TextView1 TextView2 =
=======================

And I would like to detect when the textviews are too long such that they are displayed like this:

=======================
=      TextView1      =
=      TextView2      =
=======================

currently for longer text, it is displayed like this:

=======================
= TextView1 Text      =
=           View2     =
=======================

how can I do this, such that when the text is short the textviews are side by side and when it is too long, the second textview is not splitted but moved to the second line?

I tought at a solution to create a single textview and build the text according to length (text 1 + padding + text 2 if short, and text 1 + "\n" + text 2 if long) but I do not like this solution.

Is there any way to detect if the second text will be split such that to change the orientation of the layout that contains the textviews from horizontal cu vertical?

UPDATE

This is my xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:gravity="center">

    <TextView
        android:id="@+id/my_text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:padding="10dp"
        android:text="@string/text1"/>

    <TextView
        android:id="@+id/my_text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginRight="5dp"/>

</LinearLayout>
Mihaela Romanca
  • 1,368
  • 2
  • 14
  • 23
  • could you provide some code, where your textviews are used ? – woliveirajr Jul 09 '12 at 13:34
  • I have updated the question with the xml I am using. I need to display two texts that usually are displayed one next to another, but if they are too long, they should be displayed one under another. This is what I was asked to do. – Mihaela Romanca Jul 09 '12 at 13:42
  • they really need to be separated, or could a simple wrap of the second text, begining in the left margin of the second line, be enough? – woliveirajr Jul 09 '12 at 13:45
  • 1
    no, there is no way to achieve this from xml. you could somehow programatically measure your `text1` and add your `TextView` from code based on the size of `text1` and device width. but this will be far more complex than just using text1+" " text2. – Ovidiu Latcu Jul 09 '12 at 13:46

3 Answers3

1

I have found a better solution. Changed my textviews into autoresizable textviews (more info here)

Also, each textview is in a separate layout, to make sure both textviews are resized to the same value. My xml looks like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:id="@+id/value_linear_layout"
              android:gravity="center">

    <LinearLayout 
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="wrap_content">
        <com.mihaela.view.AutoResizeTextView
            android:id="@+id/my_text_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <LinearLayout 
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="wrap_content">

        <com.mihaela.view.AutoResizeTextView
            android:id="@+id/my_text_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

and I have implemented the OnTextResizeListener from AutoResizeTextView to do this:

public class TextWidthResizeListener implements OnTextResizeListener {

    @Override
    public void onTextResize(TextView textView, float oldSize, float newSize) {
        TextPaint paint = textView.getPaint();
        if (paint.measureText(textView.getText().toString()) > (valueLinearLayout.getWidth() / 2)){
            valueLinearLayout.setOrientation(LinearLayout.VERTICAL);
        }
    }
}

where valueLinearLayout is:

valueLinearLayout = (LinearLayout)findViewById(R.id.value_linear_layout);

This solution best fits for me, as the textviews are dimensioned when they are side by side until a minimum size. When the minimum size is reached, and the text still does not fit, the textviews will be aligned one under another.

Also, this idea with the listener can be applied to non-resizable textviews also. I will set this answer as the correct one.

Community
  • 1
  • 1
Mihaela Romanca
  • 1,368
  • 2
  • 14
  • 23
  • I'm trying your solution but am just getting the ellipsized, resized result from the other answer you linked to. Where did you put your TextWidthResizeListener class and how do you call it? – Kalina Oct 16 '12 at 13:50
0

You should use a single, multi-line TextView and set the text as follows :

mTextView.setText(text1+" "+text2);

or

mTextView.setText(text1+"\n"+text2);

depending on your particular needs.

EDIT: you could specify your text in html, and then use Html.fromHtml(htmlString) and display this text in your TextView.

 String text1 ="<font color=\"red\">This is some text!</font>"
 String text2="<font color=\"blue\">This is some other text!</font>"
 textView.setText(Html.fromHtml(text1+ "<br/>"+ text2);
Ovidiu Latcu
  • 71,607
  • 15
  • 76
  • 84
  • This is not really an option for me as I have different styles on textviews, different text colors etc... – Mihaela Romanca Jul 09 '12 at 13:56
  • I have tried a different approach to use adjustable size textviews and check when text is minimized to change layout orientation to vertical, but I did not managed to make it work, as onDraw() method did not trigger any layoutchangelisteners and getTextSize returned the size of the text before onDraw change it. So, I think your solution remains the only option. Thanks. – Mihaela Romanca Jul 10 '12 at 07:14
0

I made a slightly different version of the accepted answer. I did not alter my layout xml in any way and did not use onTextResize() or AutoResizeTextView as that seemed an overkill for my situation. I needed my LinearLayout to switch from Horizontal orientation to Vertical orientation if the device's language setting caused a long string to be used.

Layout

<LinearLayout
    android:id="@+id/customer_care_bottom_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="horizontal"
    android:layout_marginBottom="@dimen/lmargin_bottom_10">

    <TextView
        android:id="@+id/customer_care_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/CUSTOMER_CARE_TITLE" />

    <TextView
        android:id="@+id/customer_care_number_information"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/CUSTOMER_CARE_INFORMATION"/>
</LinearLayout>

Java

private void setCustomerServiceLayoutOrientationBasedOnTextWidth() {
        TextPaint paint = customer_care_number_text.getPaint();
        TextView tvCustomerCareTitle = (TextView) findViewById(R.id.customer_care_title);
        TextView tvCustomerCareInformation = (TextView) findViewById(R.id.customer_care_information);
        int halfCustomerServiceLayoutWidth = getScreenWidth() / 2;
        boolean isCustomerCareTitleTooLong = paint.measureText(tvCustomerCareTitle.getText().toString()) > customerServiceLayoutWidth;
        boolean isCustomerCareInformationTooLong = paint.measureText(tvCustomerCareInformation.getText().toString) > customerServiceLayoutWidth;

        if (isCustomerCareTitleTooLong || isCustomerCareInformationTooLong) {
            LinearLayout llCustomerCareBottom = (LinearLayout) findViewById(R.id.customer_care_bottom_layout);
            llCustomerCareBottom.setOrientation(LinearLayout.VERTICAL);
        }
    }

private int getScreenWidth() {
    int screenWidth;Display display = getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT < 13) {
        screenWidth = display.getWidth();
    } else {
        Point point = new Point();
        display.getSize(point);
        screenWidth = point.x;
    }
    return screenWidth;
}
nuix
  • 1