android ellipsize 多行textview

2024-01-09

我需要省略多行文本视图。我的组件足够大,可以用椭圆显示至少 4 条线,但只显示 2 条线。我尝试更改组件的最小和最大行数,但它没有任何改变。


这是问题的解决方案。它是 TextView 的子类,实际上适用于椭圆化。我发现之前的答案中列出的 android-textview-multiline-ellipse 代码在某些情况下存在错误,并且受 GPL 约束,这对我们大多数人来说并不真正有效。您可以自由地使用此代码,无需注明出处,或者如果您愿意,也可以在 Apache 许可证下使用。请注意,当文本变成椭圆形时,有一个监听器会通知您,我自己发现这非常有用。

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.widget.TextView;

public class EllipsizingTextView extends TextView {
    private static final String ELLIPSIS = "...";

    public interface EllipsizeListener {
        void ellipsizeStateChanged(boolean ellipsized);
    }

    private final List<EllipsizeListener> ellipsizeListeners = new ArrayList<EllipsizeListener>();
    private boolean isEllipsized;
    private boolean isStale;
    private boolean programmaticChange;
    private String fullText;
    private int maxLines = -1;
    private float lineSpacingMultiplier = 1.0f;
    private float lineAdditionalVerticalPadding = 0.0f;

    public EllipsizingTextView(Context context) {
        super(context);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void addEllipsizeListener(EllipsizeListener listener) {
        if (listener == null) {
            throw new NullPointerException();
        }
        ellipsizeListeners.add(listener);
    }

    public void removeEllipsizeListener(EllipsizeListener listener) {
        ellipsizeListeners.remove(listener);
    }

    public boolean isEllipsized() {
        return isEllipsized;
    }

    @Override
    public void setMaxLines(int maxLines) {
        super.setMaxLines(maxLines);
        this.maxLines = maxLines;
        isStale = true;
    }

    public int getMaxLines() {
        return maxLines;
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        this.lineAdditionalVerticalPadding = add;
        this.lineSpacingMultiplier = mult;
        super.setLineSpacing(add, mult);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);
        if (!programmaticChange) {
            fullText = text.toString();
            isStale = true;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (isStale) {
            super.setEllipsize(null);
            resetText();
        }
        super.onDraw(canvas);
    }

    private void resetText() {
        int maxLines = getMaxLines();
        String workingText = fullText;
        boolean ellipsized = false;
        if (maxLines != -1) {
            Layout layout = createWorkingLayout(workingText);
            if (layout.getLineCount() > maxLines) {
                workingText = fullText.substring(0, layout.getLineEnd(maxLines - 1)).trim();
                while (createWorkingLayout(workingText + ELLIPSIS).getLineCount() > maxLines) {
                    int lastSpace = workingText.lastIndexOf(' ');
                    if (lastSpace == -1) {
                        break;
                    }
                    workingText = workingText.substring(0, lastSpace);
                }
                workingText = workingText + ELLIPSIS;
                ellipsized = true;
            }
        }
        if (!workingText.equals(getText())) {
            programmaticChange = true;
            try {
                setText(workingText);
            } finally {
                programmaticChange = false;
            }
        }
        isStale = false;
        if (ellipsized != isEllipsized) {
            isEllipsized = ellipsized;
            for (EllipsizeListener listener : ellipsizeListeners) {
                listener.ellipsizeStateChanged(ellipsized);
            }
        }
    }

    private Layout createWorkingLayout(String workingText) {
        return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),
                Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false);
    }

    @Override
    public void setEllipsize(TruncateAt where) {
        // Ellipsize settings are not respected
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android ellipsize 多行textview 的相关文章

  • 不同 Android 设备上 box2D 中出现奇怪的“口吃”

    我正在用 C 同时开发引擎和游戏 并使用 box2D 作为物理后端 我正在不同的 Android 设备上进行测试 在三分之二的设备上 游戏运行良好 物理效果也很好 然而 在我的 Galaxy Tab 10 1 上 我偶尔会遇到某种 口吃 的
  • 使用 GoogleServices 插件时忽略 Gradle ArchivesBaseName

    我经常使用 archivesbasename 来重命名我的输出 apk 但自从使用 google services 插件后 它就被忽略了 我能做些什么来让它再次工作吗 下面附上了我完整的 build gradle 感谢您的指点 apply
  • Google Play 商店中基于服务的 Android 应用程序

    我正在开发一个应用程序 该应用程序仅包含一些服务 没有任何活动 即没有 UI 基本上 当用户在他 她的设备上安装应用程序时 我希望有 2 到 3 个服务在后台运行 对此我有几个疑问 应用程序安装后我的服务将如何启动 我的BroadcastR
  • 导航组件参数默认值

    在导航组件中 将参数从第一个片段发送到第二个片段时 默认值不会从导航图中获取哪个集合 这是我的代码 导航图 xml
  • 毕加索磁盘缓存

    我正在使用 Picasso 从 URL 加载图像 Picasso with getApplicationContext load product getImageUrl into imageView 据我所知 每次都会访问该网址 而不是缓存
  • 编译后从字节代码中删除注释

    我们正在使用一个包含使用 JAXB 注释进行注释的 bean 的库 我们使用这些类的方式完全不依赖于 JAXB 换句话说 我们不需要 JAXB 也不依赖注释 但是 由于注释存在 它们最终会被处理注释的其他类引用 这要求我将 JAXB 捆绑到
  • 游标索引越界异常

    打开后出现光标索引越界错误 数据库 请任何人告诉我如何打开现有数据库 sqllite Android 我想在数据库上触发一个选择查询 检索一些信息 public void getPatient SQLiteDatabase db Strin
  • Android 中有没有办法获取 SD 卡大小?

    欢迎大家 我已经在 Stackoverflow 和 google 上尝试过与此相关的每个问题 但没有一个有效 我已经尝试过类似下一个链接的操作 但它返回的内容与内部存储相同 如何获取外部存储 SD 卡的大小 带安装的 SD 卡 https
  • Android 谷歌地图 V2 已停止

    我正在尝试构建地图应用程序并关注这个链接 https blog emildesign rhcloud com p 435一步步 我在这里找到了类似的主题 但对我没有帮助 我想显示地图 但是当我运行它时 它返回强制关闭和我的 Android
  • android:进程和进程名称

    我试图理解android process属性 Ref says http developer android com guide topics manifest application element html proc 如果分配给该属性的
  • 将图像保存到内部存储器并将出现在图库中

    我搜索了很多与我的问题相关的问题 是否有办法将图像存储在内存中并且它也应该出现在图库中 这是完全有可能的 我以前也这么做过 在将图像保存到内存 或称为应用程序文件夹等 之前 您最好设置Context MODE WORLDREADABLE 虽
  • Android - 多次实例化一个片段?

    我正在创建一个在 ListView 中显示数据的应用程序 数据分为两种类型 热门 收藏夹 我有一个活动和两个片段 片段根据类别显示项目列表 我为此使用了 ListView 然后我有两个fragment layouts 它们在设计上完全相同
  • 收到“无法解析上传的APK的AndroidManifest.xml。它是否正确编译?”启用 Google 应用签名后出现错误

    启用后谷歌应用程序签名 https support google com googleplay android developer answer 7384423 hl en 每次我尝试将签名版本 APK 上传到 Play 商店时 都会收到一
  • 截图显示黑色

    我正在拍摄快照并创建缩略图 然后共享此图像 但缩略图显示全黑 我使用了以下代码 Bitmap bitmap View v1 v getRootView v1 setDrawingCacheEnabled true bitmap Bitmap
  • 无法登录 Google Play 游戏服务

    我在开发者控制台上使用包名称和正确的签名证书设置了我的游戏 并为其创建了排行榜 但没有创建任何成就 然后 我从以下位置下载了示例 Type A Number Challenge 和 BaseGameUtils https developer
  • BitmapFactory.decodeResource() 忽略 jpg 图像的 inPreferredConfig 选项

    我尝试将jpeg资源图像加载到ARGB 8888格式的位图 BitmapFactory Options opts new BitmapFactory Options opts inPreferredConfig Bitmap Config
  • 将 Crashlytics 集成到图书馆项目

    我有一个图书馆项目 自定义视图库项目 它没有任何活动 服务 我想将 Crashlytics SDK 集成到我的库中 当我尝试通过 Android Studio 的 Crashlytics 插件 工具栏中的图标 添加它时 它只是停留在 Che
  • 应用程序中空指针异常[重复]

    这个问题在这里已经有答案了 我正在尝试在我的应用程序中实施应用程序内计费 我写了这段代码 public class Settings extends PreferenceFragment ServiceConnection mService
  • 使用 RecyclerView.Adapter 在 onBindViewHolder() 内设置 onItemClickListener

    我有一个自定义对象 学生班 public class Student private String name private String age public String getName return name public void
  • 膨胀类 android.support.design.widget.CoordinatorLayoute 时出错

    我正在尝试运行我的应用程序 但不断收到标题中列出的错误 我读过周围的内容 人们说尝试将主题更改为 AppCombat 主题 但这似乎不起作用 以下是我遇到的错误 Process com example jmeyer27 crazytiles

随机推荐

  • Objective-C 中的静态 NSString

    我经常在类实例方法中看到这样的代码片段 static NSString myString This is a string 我似乎不明白为什么这会起作用 这是否只是 objc 等价于仅限于方法范围的 define 我 认为 我理解变量的静态
  • 数组上的“each”/“map”会导致 create_time_zone_conversion_attribute 中的“当您没有预料到时,您有一个 nil 对象”?

    我有一个按钮 它通过 XHR 向 Rails 服务器中的特定操作发送 get 请求 此操作调用我在模型 类别 中定义的函数 该函数执行类似 x Category subcategories 的操作 并在下一行中执行类似 x map id 或
  • 如何将绘图保存到PDF文件中,周围没有大边距[重复]

    这个问题在这里已经有答案了 如果我打印一个情节EPS http en wikipedia org wiki Encapsulated PostScript格式时 EPS 文件的内容完全被绘图占据 但如果我打印一个情节PDF http en
  • 如何选择*加上另一列[重复]

    这个问题在这里已经有答案了 我试图从一个表中选择所有值 然后选择仅运行这些列之一的函数的输出 并将所有这些显示为我的 SQL 查询输出 我这样做的目标是从 Geometry 列创建可用的 WKT 输出 并将其包含在查询结果中 这样我就可以在
  • FabricInvalidAddressException:尝试从 .NET Core 应用程序连接时出现 NamedEndpoint“V2Listener”

    我正在尝试使用以下方式连接到 Service Fabric 应用程序ServiceProxy像这样的类 return ServiceProxy Create
  • php和mysql将记录从一个表复制到另一个表

    我想通过将记录从一个表移动到另一个表来对学生进行存档 这是我尝试使用的代码
  • 您相信 ASP.Net MVC 已准备好投入生产吗?

    我真的很喜欢 Microsoft 承诺将 MVC 引入 Web 为此 我对将我现有的 ASP NET 应用程序之一转换为 MVC 感到兴奋 并想知道我是否操之过急 虽然这个网站正在使用 MVC 但它在技术上仍处于测试阶段 您有什么想法 从
  • Google 容器引擎:访问云存储

    我无法让应用程序默认凭据在 Google 容器引擎中工作 文档说它们适用于 App Engine 和 Compute Engine 但我被告知它们应该透明地传递到在 Container Engine 上运行的容器 这是失败的代码 crede
  • iOS 7 状态栏与导航栏发生冲突

    我的应用程序中有一个视图控制器 在故事板中拖动了一个导航栏 它在 iOS 6 中运行良好 但在 iOS 7 中它看起来像这样 状态栏和导航栏不应相互冲突 我在堆栈溢出上看到过很多这样的问题 但它们对我没有太大帮助 有些问题说我应该使用这个
  • asp.net core 检查中间件中的路由属性

    我正在尝试构建一些 ASP Net core 中间件 需要查看当前路由是否标记为 授权 eg public async Task Invoke HttpContext context if context Request Path Valu
  • 在 PyTables 中,如何创建可变长度的嵌套数组?

    我正在使用 PyTables 2 2 1 w Python 2 6 我想创建一个包含可变长度嵌套数组的表 我搜索了 PyTables 文档和教程示例 PyTables 教程 3 8 http www pytables org docs ma
  • Dojo MVC 的简单登录实现

    有没有关于如何实现简单的登录页面 对话框的示例 我一直在尝试使用 dojo 样板来做到这一点 检查我之前的问题 Dojo MVC 的布局实现 https stackoverflow com questions 10953316 layout
  • 更新会话变量而不刷新页面[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当单击 iframe 外部页面 中的链接时 我需要更新第 1 页上的会话变量 当我点击 iframe 的链接时 会话变量已成功设置 问题是
  • 如何读取.net core api项目中appsetting.json文件中的多个连接字符串

    我有多个连接字符串属性 例如 在 AppSetting json 文件中 connectionstring connection1 datasource1 connection2 datasource2 我想读取控制器或服务文件中的连接字符
  • Phalcon Multi module - 动态模块注册

    大家好 我在 Phalcon 的多模块项目中使用以下结构 modules module1 controllers models views module2 controllers models views module n controll
  • 无法使用 Nuitka 编译 Python

    我正在尝试编译使用 urllib request BeautifulSoup 和 网页浏览器 nuitka python py Nuitka WARNING python py 16 Cannot find urllib request a
  • 使用 Add-on SDK 的 Firefox 插件提供更多存储空间

    我想使用插件生成器开发一个插件 我读到 通过简单的存储 一个人的插件可以有大约 5 MB 的空间 但 5 mgb 的空间不足以容纳我的应用程序 我需要更多 我能做什么 考虑到附加 SDK API 您无法做太多事情 相反 你可以冲出沙箱 ht
  • 什么时候应该在 OCaml 中使用对象?

    通常 OCaml 程序可以使用或不使用对象来编写 什么时候使用物品最有利 什么时候应该避免使用物品 作为一般经验法则 不要使用对象 它们带来的额外复杂性通常并不值得 我认为这也是适用于其他语言的规则 但那是另一回事了 至少对于 OCaml
  • 显示本地时间的 MySQL 时间戳

    我有一个 MySQL 数据库 其中存储的大量数据均采用 UTC 时间的时间戳 当用户查询该数据库时 我希望他们能够在本地时区查看数据 我不想每次都计算偏移量并使用 PHP 代码更改时间戳 还有其他办法吗 您可以使用localtime htt
  • android ellipsize 多行textview

    我需要省略多行文本视图 我的组件足够大 可以用椭圆显示至少 4 条线 但只显示 2 条线 我尝试更改组件的最小和最大行数 但它没有任何改变 这是问题的解决方案 它是 TextView 的子类 实际上适用于椭圆化 我发现之前的答案中列出的 a