1. ホーム
  2. android

Android TextViewにandroid:ellipsize=endのバグがある。

2022-02-17 08:07:30
<パス

ダウト

今日、開発中に不思議なバグに遭遇しました。

要件は明確で、TextViewには以下の2行の重要なプロパティが設定されていた。


個人的には何の問題もない、非常にシンプルな要求の結果は、意外にも次のようなものです。

コンテンツが・・・の後にまで表示されるのはちょっと変だし、末尾のテキストが半分しか表示されないのはさらに吐き気がする!

解決方法

以下のサイトで検索すると、関連するソリューションが多数見つかります。

1. これらのプロパティを追加/削除/設定する。

    android:singleLine = "false"
    android:lines = "2"
    android:ellipsize="end"        
    android:maxLines="2"

その結果、問題が解決されない

2. TextViewのコンテンツの長さを強制的に正規化する、String.split()などの

理由が全くわからないまま行く信頼性の低い解決策。

3. 解決する

最終的にこのURLを見つけ、原因が判明しました。

android:ellipsize=endにまつわる奇妙な問題

文字が文字列のどこかにある限り、[一貫性のない]この問題を引き起こしていたことが判明しました。

つまり、textViewのテキストコンテンツに \n 文字や、 \< のような html 文字が含まれている場合です。*といったhtml文字が含まれていることです。

これらの特殊文字が例外の原因です。

解決策も簡単で、setTextの前に直接、呼び出すことで解決します。

myText.replaceAll("\\\<. *? >","");

補足

このテキストの内容はサーバーから取得されるため、ビジネスコードを変更しないよう、Gsonパース時に直接内容を変更する。

TypeAdapterを直接カスタマイズして、このプロパティをパースするようにし、パース時のパフォーマンスも向上させる。

/**
 * Created by QingMei on 2017/11/3.
 * desc:remove all html char or \n in string
 \n in string */

public class MessageContentAdapter extends TypeAdapter
 {

    @Override
    public void write(JsonWriter out, String value) throws IOException {

    }

    @Override
    public String read(JsonReader in) throws IOException {
        return in.nextString().replaceAll("\\\<. *? >|\\n","");
    }
}


エンティティクラスオブジェクトにアノテーションを追加します。

public class Message implements Serializable {

    private int id;
    ...
    ...
    ...
    @JsonAdapter(MessageContentAdapter.class)
    private String description;

}