TextView加载大文本发生卡顿
Posted lauryn_yin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TextView加载大文本发生卡顿相关的知识,希望对你有一定的参考价值。
大概100多kb的文本内容的时候,会发生这个问题,采用的就是原生的TextView,原因的话网上讲得也比较详细,有的甚至连加载流程也都讲出来了,总的来说就是描画文本的作业是在UI线程里进行的
解决方案的话,网上提了大概四个吧。
方法一,把TextView的宽度设定为一个数字或者match_parent。NG,至少对我来说不起任何作用
方法二,使用androidx.appcompat.widget.AppCompatTextView。同上
方法三,在方法二的基础上,采用下述方法,加载速度肉眼可见的有提升,关键是改动量比较小
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.text.PrecomputedTextCompat;
import java.util.concurrent.Future;
。。。。
//关键代码
Future<PrecomputedTextCompat> future = PrecomputedTextCompat.getTextFuture(contentDelayed, txtViewContent.getTextMetricsParamsCompat(), null);
txtViewContent.setTextFuture(future);
方法四,相对方法三来说,改动量有点大:使用StaticLayout,具体原因以及理由网上有,可以自行百度。其实这个方法相当于是一个自定义view了。
参考:https://www.jianshu.com/p/a9d6fbf20642
import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.View;
public class StaticLayoutView extends View
private Layout mLayout = null;
private int mWidth;
private int mHeight;
public StaticLayoutView(Context context)
super(context);
public StaticLayoutView(Context context, AttributeSet attrs)
super(context, attrs);
public StaticLayoutView(Context context, AttributeSet attrs,int defStyleAttr)
super(context, attrs, defStyleAttr);
public void setLayout(Layout layout)
if (layout == null)
return;
mLayout = layout;
if (mLayout.getWidth() != mWidth || mLayout.getHeight() != mHeight)
mWidth = mLayout.getWidth();
mHeight = mLayout.getHeight();
requestLayout();
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
canvas.save();
if (mLayout != null)
mLayout.draw(canvas, null, null, 0);
canvas.restore();
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
super.onLayout(changed, left, top, right, bottom);
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
if (mLayout != null)
setMeasuredDimension(mLayout.getWidth(), mLayout.getHeight());
else
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
public class StaticLayoutManager
public StaticLayout longStringLayout;
private TextPaint textPaint;
private Layout.Alignment alignment;
private int hardCodeWidth;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public void initLayout(Context context, CharSequence longString)
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.density = context.getResources().getDisplayMetrics().density;
textPaint.setTextSize(DisplayUtils.fromDPtoPix(context, DisplayUtils.TEXT_SIZE_DP));
alignment = Layout.Alignment.ALIGN_NORMAL;
hardCodeWidth = DisplayUtils.getScreenWidth(context);
longStringLayout = new StaticLayout(longString, textPaint, hardCodeWidth, alignment, 1.0f, 0f, true);
public StaticLayout getLongStringLayout()
return longStringLayout;
private static StaticLayoutManager INSTANCE = null;
public static StaticLayoutManager getInstance()
if (INSTANCE == null)
INSTANCE = new StaticLayoutManager();
return INSTANCE;
使用方法
public class StaticLayoutAty extends AppCompatActivity
private String readFile()
try
InputStream is = getAssets().open("0.txt");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
return new String(buffer);
catch (IOException e)
return "读取错误...";
StaticLayoutView staticLayoutView;
ProgressDialog pd;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_static_layout_aty);
staticLayoutView = findViewById(R.id.static_content);
pd = new ProgressDialog(this);
pd.show();
new Thread(new Runnable()
@Override
public void run()
StaticLayoutManager.getInstance().initLayout(StaticLayoutAty.this, readFile());
runOnUiThread(new Runnable()
@Override
public void run()
staticLayoutView.setLayout(StaticLayoutManager.getInstance().getLongStringLayout());
Toast.makeText(StaticLayoutAty.this, "init span finish", Toast.LENGTH_LONG).show();
pd.dismiss();
);
).start();
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorAccent"
tools:context=".activity.StaticLayoutAty">
<com.xx.StaticLayoutView
android:id="@+id/static_content"
android:layout_width="fill_parent"
android:layout_height="match_parent"/>
</ScrollView>
PS:方法四在试验的时候还是有问题,progressDialog消失了10多秒之后,文本才加载出来,而且还会ANR,可能是用的不对?
以上是关于TextView加载大文本发生卡顿的主要内容,如果未能解决你的问题,请参考以下文章
AppCompatTextView自动缩放字体在RecyclerView中卡顿,自定义高效自动缩放TextView