TextViewの省略表示(マーキーや...)について調べました。
layout xmlで設定する場合
android:ellipsize属性を設定することで、ビューの幅よりも長い文字の場合に省略表示されます。
layout.xml
<TextView
android:id="@+id/text2"
android:focusable="true"
android:ellipsize="none"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center_vertical"
android:singleLine="true"
android:text="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" />
Constant | Description | Example |
---|---|---|
none | 省略なし | 1234567 |
start | 先頭を省略 | …456789 |
middle | 中央を省略 | 123…789 |
end | 最後を省略 | 123456… |
marquee | スクロール |
marqueeについては、TextViewにフォーカスがあたった際にスクロールが実行されます。
setEllipsize methodで設定する場合
setEllipsizeでも設定することができます。
public void setEllipsize (TextUtils.TruncateAt where)
Parameters | Description | Example |
---|---|---|
null | 省略なし | 1234567 |
START | 先頭を省略 | ...456789 |
MIDDLE | 中央を省略 | 123...789 |
END | 最後を省略 | 123456... |
MARQUEE | スクロール | |
END_SMALL | 最後を省略 | 1234567.. |
※END_SMALLはSdkVersion 28からとなります。 |
marqueeの注意点
marqueeについては、TextViewにフォーカスがあたった際にスクロールが実行されます。
TextViewにフォーカスをあてられない場合(例:RecyclerViewでアイテムに複数のTextViewがある場合)はsetSelectedをtrueにする必要があります。
サンプルコード
例:RecyclerViewでアイテムに複数のTextViewがある場合
TextViewSampleActivity.kt
class TextViewSampleActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_text_view_sample)
val recyclerView = findViewById<RecyclerView>(R.id.list)
recyclerView.adapter = TextViewSampleAdapter(this)
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.addItemDecoration(DividerItemDecoration(this, layoutManager.orientation))
}
}
activity_text_view_sample.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/ellipsize"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/targetText"
android:ellipsize="none"
android:layout_width="match_parent"
android:layout_height="30dp"
android:singleLine="true"
android:text="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" />
</LinearLayout>
ポイントは、RecyclerViewのアイテムにフォーカスがあたった際に、isSelectedをtrueにすることです。
TextViewSampleAdapter.kt
class TextViewSampleAdapter(
context: Context) : RecyclerView.Adapter<TextViewSampleAdapter.ListAdapterHolder>() {
private val inflater = LayoutInflater.from(context)
private val ID_NONE = 0
private val ID_START = 1
private val ID_MIDDLE = 2
private val ID_END = 3
private val ID_MARQUEE = 4
private val ID_END_SMALL = 5
private val ID_ARRAY = arrayOf(ID_NONE, ID_START, ID_MIDDLE, ID_END, ID_MARQUEE, ID_END_SMALL)
class ListAdapterHolder(view: View) : RecyclerView.ViewHolder(view)
override fun getItemCount(): Int {
return ID_ARRAY.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListAdapterHolder {
val view = inflater.inflate(R.layout.list_adapter_item, parent, false)
return ListAdapterHolder(view)
}
override fun onBindViewHolder(holder: ListAdapterHolder, position: Int) {
holder.itemView.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
if (position == ID_MARQUEE) holder.itemView.targetText.isSelected = true
} else {
if (position == ID_MARQUEE) holder.itemView.targetText.isSelected = false
}
}
when (position) {
ID_NONE -> setEllipsize(holder, "ellipsize NONE", null)
ID_START -> setEllipsize(holder, "ellipsize START", TextUtils.TruncateAt.START)
ID_MIDDLE -> setEllipsize(holder, "ellipsize MIDDLE", TextUtils.TruncateAt.MIDDLE)
ID_END -> setEllipsize(holder, "ellipsize END", TextUtils.TruncateAt.END)
ID_MARQUEE -> setEllipsize(holder, "ellipsize MARQUEE", TextUtils.TruncateAt.MARQUEE)
else -> setEllipsize(holder, "ellipsize END_SMALL", TextUtils.TruncateAt.END_SMALL)
}
}
private fun setEllipsize(holder: ListAdapterHolder, text: String, where: TextUtils.TruncateAt?) {
holder.itemView.ellipsize.setText(text)
holder.itemView.targetText.ellipsize = where
}
}
list_adapter_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="@+id/ellipsize"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/targetText"
android:ellipsize="none"
android:layout_width="match_parent"
android:layout_height="30dp"
android:singleLine="true"
android:text="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" />
</LinearLayout>