Detect whether TextView in ListView is ellipsized
Asked Answered
R

4

15

I have a custom Adapter that renders some items in a ListView. I need to show an icon on the ListView's items, if the item's text is ellipsized, and hide it if there's enough room for the text to finish. I have access to the button in getView method of my adapter (where I set the text) but the ellipses are not added immediately upon setting the text.

Is there any way I can do this?

Here's my TextView markup:

<TextView android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:ellipsize="end"
          android:singleLine="true"
          android:id="@+id/list_item_description"/>
Repetitious answered 2/5, 2011 at 9:29 Comment(3)
what u did for ellipses?Drafty
Have you tried the android:ellipsize.Straighten
added the part related to my TextViewRepetitious
A
14

public int getEllipsisCount (int line):

Returns the number of characters to be ellipsized away, or 0 if no ellipsis is to take place.

So, simply call :

if(textview1.getLayout().getEllipsisCount() > 0) {
   // Do anything here..
}

Since the getLayout() cant be called before the layout is set, use ViewTreeObserver to find when the textview is loaded:

ViewTreeObserver vto = textview.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
       Layout l = textview.getLayout();
       if ( l != null){
          int lines = l.getLineCount();
          if ( lines > 0)
              if ( l.getEllipsisCount(lines-1) > 0)
                Log.d(TAG, "Text is ellipsized");
       }  
    }
});

And finally do not forget to remove removeOnGlobalLayoutListener when you need it nomore.

Agustinaah answered 21/2, 2014 at 7:34 Comment(0)
O
8

The tricky part is that the view you're working with in getView will sometimes have been laid out, and sometimes not, so you have to handle both cases.

When it hasn't been laid out, you set a view tree observer to check on the ellipsis once it has been. In the case of recycled views, the layout will already be there and you can check for the ellipsis immediately after setting the text.

public View getView(int position, View convertView, ViewGroup parent) {
  final ViewHolder vh;
  if (convertView == null) {
    vh = new ViewHolder();
    ... // create/inflate view and populate the ViewHolder
  }
  vh = (ViewHolder) convertView.getTag();

  // Set the actual content of the TextView
  vh.textView.setText(...);

  // Hide the (potentially recycled) expand button until ellipsizing checked
  vh.expandBtn.setVisibility(GONE);

  Layout layout = vh.textView.getLayout();
  if (layout != null) {
    // The TextView has already been laid out
    // We can check whether it's ellipsized immediately
    if (layout.getEllipsisCount(layout.getLineCount()-1) > 0) {
      // Text is ellipsized in re-used view, show 'Expand' button
      vh.expandBtn.setVisibility(VISIBLE);
    }
  } else {
    // The TextView hasn't been laid out, so we need to set an observer
    // The observer fires once layout's done, when we can check the ellipsizing
    ViewTreeObserver vto = vh.textView.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        Layout layout = vh.textView.getLayout();
        if (layout.getEllipsisCount(layout.getLineCount()-1) > 0) {
          // Text is ellipsized in newly created view, show 'Expand' button
          vh.expandBtn.setVisibility(VISIBLE);
        }

        // Remove the now unnecessary observer
        // It wouldn't fire again for reused views anyways
        ViewTreeObserver obs = vh.textView.getViewTreeObserver();
        obs.removeGlobalOnLayoutListener(this);
      }
    });

  return convertView;
}
Orcein answered 7/8, 2013 at 2:59 Comment(1)
The part where we check already laid out TextView seems to be not working. Tested on Android emulator api 23.Corky
E
0

I hope I understand your question correctly--if you're looking to end a TextView that's too wide for a screen with ellipses, you can add these attributes to your TextView:

android:ellipsize="end"
android:maxLines="1"
android:scrollHorizontally="true"

If, however, you want to determine whether a TextView is ended with an ellipsis or is displayed fully, I'm not so sure that's possible--it doesn't look like it is. Still, you might want to try the getEllipsize() method of TextView. I'm not sure whether that returns the point at where the TextView is ellipsized by Android, or where you have set the TextView to be ellipsized.

Eld answered 21/11, 2012 at 8:2 Comment(0)
B
-1

You can either set your text to marque. add this in your code might help.....

    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:scrollHorizontally="true"
    android:freezesText="true"
    android:marqueeRepeatLimit="marquee_forever"

You can also put a horizontal scrollview for you code....

    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/list_item_description"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="1"
                android:ellipsize="end"
                android:gravity="center_vertical"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearanceSmall" />
        </LinearLayout>
    </HorizontalScrollView>
Boomkin answered 27/8, 2012 at 20:59 Comment(1)
Neither of your suggestions address the question that Hadi posed, which was why the ellipsize property was not exhibiting the expected behaviour. Instead, they solve a different problem (and the HorizontalScrollView proposal is particularly bad).Kilocalorie

© 2022 - 2024 — McMap. All rights reserved.