AndroidX 的PrecomputedTextCompat提供了一个方法,getTextFuture(),这个方法可以在异步线程计算文字布局数据,需要注意的是设置后,TextView的参数不能再发生改变,否则可能出现IllegalArgumentException。
Helper for PrecomputedText that returns a future to be used with androidx.appcompat.widget.AppCompatTextView.setTextFuture. PrecomputedText is suited to compute on a background thread, but when TextView properties are dynamic, it’s common to configure text properties and text at the same time, when binding a View. For example, in a RecyclerView Adapter:
void onBindViewHolder(ViewHolder vh, int position) {
ItemData data = getData(position);
vh.textView.setTextSize(...);
vh.textView.setFontVariationSettings(...);
vh.textView.setText(data.text);
}
In such cases, using PrecomputedText is difficult, since it isn’t safe to defer the setText() code arbitrarily - a layout pass may happen before computation finishes, and will be incorrect if the text isn’t ready yet.
With getTextFuture(), you can block on the result of the precomputation safely before the result is needed. AppCompatTextView provides androidx.appcompat.widget.AppCompatTextView.setTextFuture for exactly this use case. With the following code, the app’s layout work is largely done on a background thread:
void onBindViewHolder(ViewHolder vh, int position) {
ItemData data = getData(position);
vh.textView.setTextSize(...);
vh.textView.setFontVariationSettings(...);
// start precompute
Future future = PrecomputedTextCompat.getTextFuture(
data.text, vh.textView.getTextMetricsParamsCompat(), myExecutor);
// and pass future to TextView, which awaits result before measuring
vh.textView.setTextFuture(future);
}
Because RecyclerView prefetches bind multiple frames in advance while scrolling, the text work generally has plenty of time to complete before measurement occurs.
Note: all TextView layout properties must be set before creating the Params object. If they are changed during the precomputation, this can cause a IllegalArgumentException when the precomputed value is consumed during measure, and doesn’t reflect the TextView’s current state.