Auto Scale TextView Text to Fit within Bounds

后端 未结 30 2876
囚心锁ツ
囚心锁ツ 2020-11-21 05:49

I\'m looking for an optimal way to resize wrapping text in a TextView so that it will fit within its getHeight and getWidth bounds. I\'m not simply looking for

30条回答
  •  失恋的感觉
    2020-11-21 06:09

    Here's a simple solution that uses TextView itself with a TextChangedListened added to it:

    expressionView = (TextView) findViewById(R.id.expressionView);
    expressionView.addTextChangedListener(textAutoResizeWatcher(expressionView, 25, 55));
    
    private TextWatcher textAutoResizeWatcher(final TextView view, final int MIN_SP, final int MAX_SP) {
        return new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    
            @Override
            public void afterTextChanged(Editable editable) {
    
                final int widthLimitPixels = view.getWidth() - view.getPaddingRight() - view.getPaddingLeft();
                Paint paint = new Paint();
                float fontSizeSP = pixelsToSp(view.getTextSize());
                paint.setTextSize(spToPixels(fontSizeSP));
    
                String viewText = view.getText().toString();
    
                float widthPixels = paint.measureText(viewText);
    
                // Increase font size if necessary.
                if (widthPixels < widthLimitPixels){
                    while (widthPixels < widthLimitPixels && fontSizeSP <= MAX_SP){
                        ++fontSizeSP;
                        paint.setTextSize(spToPixels(fontSizeSP));
                        widthPixels = paint.measureText(viewText);
                    }
                    --fontSizeSP;
                }
                // Decrease font size if necessary.
                else {
                    while (widthPixels > widthLimitPixels || fontSizeSP > MAX_SP) {
                        if (fontSizeSP < MIN_SP) {
                            fontSizeSP = MIN_SP;
                            break;
                        }
                        --fontSizeSP;
                        paint.setTextSize(spToPixels(fontSizeSP));
                        widthPixels = paint.measureText(viewText);
                    }
                }
    
                view.setTextSize(fontSizeSP);
            }
        };
    }
    
    private float pixelsToSp(float px) {
        float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
        return px/scaledDensity;
    }
    
    private float spToPixels(float sp) {
        float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
        return sp * scaledDensity;
    }
    

    This approach will increase or decrease the font size as needed to fit the text, respecting the MIN_SP and MAX_SP bounds received as parameters.

提交回复
热议问题