检测ListView中的TextView是不是为椭圆

Posted

技术标签:

【中文标题】检测ListView中的TextView是不是为椭圆【英文标题】:Detect whether TextView in ListView is ellipsized检测ListView中的TextView是否为椭圆 【发布时间】:2011-08-16 20:44:43 【问题描述】:

我有一个自定义适配器,可以在 ListView 中呈现一些项目。如果项目的文本是椭圆的,我需要在 ListView 的项目上显示一个图标,如果有足够的空间让文本完成,则隐藏它。我可以访问适配器的 getView 方法中的按钮(我在其中设置文本),但在设置文本时不会立即添加省略号。

有什么办法可以做到吗?

这是我的 TextView 标记:

<TextView android:layout_
          android:layout_
          android:ellipsize="end"
          android:singleLine="true"
          android:id="@+id/list_item_description"/>

【问题讨论】:

你为省略号做了什么? 你试过android:ellipsize吗。 添加了与我的TextView相关的部分 【参考方案1】:

public int getEllipsisCount (int line):

返回要省略的字符数,如果没有省略,则返回 0。

所以,只需调用:

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

由于在布局设置之前无法调用getLayout(),所以使用ViewTreeObserver查找textview的加载时间:

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");
         
    
);

最后不要忘记在您不再需要时删除 removeOnGlobalLayoutListener

【讨论】:

【参考方案2】:

棘手的部分是您在getView 中使用的视图有时会被布局,有时不会,因此您必须同时处理这两种情况。

当它没有被布置时,你设置一个视图树观察者来检查省略号。在循环视图的情况下,布局已经存在,您可以在设置文本后立即检查省略号。

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;

【讨论】:

我们检查的部分已经布局 TextView 似乎无法正常工作。在 Android 模拟器 api 23 上测试。【参考方案3】:

我希望我能正确理解您的问题——如果您希望结束一个对于带有椭圆的屏幕来说太宽的TextView,您可以将这些属性添加到您的TextView

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

但是,如果您想确定 TextView 是以省略号结尾还是完全显示,我不太确定这是否可能——它看起来不像。不过,您可能想尝试TextViewgetEllipsize() 方法。我不确定这是否会返回 TextView 被 Android 椭圆化的点,或者 将 TextView 设置为椭圆化的位置。

【讨论】:

【参考方案4】:

您可以将文本设置为标记。 在你的代码中添加这个可能会有所帮助.....

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

您还可以为您的代码放置一个水平滚动视图....

    <HorizontalScrollView
        android:layout_
        android:layout_ >

        <LinearLayout
            android:layout_
            android:layout_
            android:orientation="vertical" >

            <TextView
                android:id="@+id/list_item_description"
                android:layout_
                android:layout_
                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>

【讨论】:

您的建议都没有解决 Hadi 提出的问题,这就是为什么 ellipsize 属性没有表现出预期的行为。相反,他们解决了一个不同的问题(HorizontalScrollView 提案特别糟糕)。

以上是关于检测ListView中的TextView是不是为椭圆的主要内容,如果未能解决你的问题,请参考以下文章

ListView 中的可选 TextView(缺少动画)

动态更改 ListView 中的 TextView 字体颜色

遍历 ListView 中的所有 TextView

ListView 不可点击,行中的所有小部件都是 TextView

Ellipsize 不适用于自定义 listView 中的 textView

从自定义 ListView 中的 TextView -w/Button 获取文本