Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use "TextLayoutView" of Instagram in improving TextView Rendering on Android

To improve TextView rendering in Instagram, the engineers in Instagram provide a hack in here,they use a custom view(TextLayoutView) to cache the text.Layout, but in this post, they don't give us a demo or tell us how to use it, so if I want to use this hack, how could I do?

like image 785
wqycsu Avatar asked Apr 25 '15 02:04

wqycsu


1 Answers

This is my simple implementation:

TextLayoutView:

public class TextLayoutView extends View {

private Layout mLayout;

public TextLayoutView(Context context) {
    this(context, null);
}

public TextLayoutView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public TextLayoutView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setFocusable(true);
}

@Override
protected void onDraw(Canvas canvas) {
    long t1=System.currentTimeMillis();
    super.onDraw(canvas);
    canvas.save();
    if (mLayout != null) {
        canvas.translate(getPaddingLeft(), getPaddingTop());
        mLayout.draw(canvas);
    }

    canvas.restore();
    long t2=System.currentTimeMillis();
    Log.i("TEST", "onDraw::"+(t2-t1));
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    long t1=System.currentTimeMillis();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (mLayout != null) {
        setMeasuredDimension(
                getPaddingLeft() + getPaddingRight() + mLayout.getWidth(),
                getPaddingTop() + getPaddingBottom() + mLayout.getHeight());
    }
    long t2=System.currentTimeMillis();
    Log.i("TEST", "onMeasure::"+(t2-t1));
}


public void setTextLayout(Layout layout) {
    mLayout = layout;
    requestLayout();
}}

you can use it just this:

    @Override
public View getView(int position, View convertView, ViewGroup parent) {
    ......
    viewHolder.textView.setTextLayout(getLayout(mList.get(position)));
    return convertView;
}
    private final Map<String, Layout> mLayoutMap = new ConcurrentHashMap<String, Layout>();
private Layout getLayout(String str) {
    Layout layout = mLayoutMap.get(str);
    if (layout == null) {
        TextPaint textPaint = new TextPaint();
        textPaint.setTextSize(20);
        layout = new StaticLayout(str, textPaint, width, Alignment.ALIGN_CENTER,
                1.0f, 0.0f, true);
        mLayoutMap.put(str, layout);
    }
    return layout;
}
like image 122
adsion Avatar answered Oct 03 '22 00:10

adsion