• Android TextView,EditText要求固定行数自动调整TextSize


    最近项目有个需求要求文本最多显示3行,继续输入则字体变小,删除已经输入的文字,那么字体变大,不管变大变小都不能超过3行。网上怎么找也找不到相关的解决方案,自己动手,丰衣足食了!

    说一下算法思路,后面给出demo。

     第一步 获取当前的行数

        我们需要知道目前文本多少行了,之前我采用TextView.getPaint().measureText("your text")这种方法来获取文字的总长度,然后再除以每行的宽度,得到行数,其实这个算法也是可行,不过我采用更简单的方法了。采用view.post方法里面可以通过lineCount = textView.getLineCount();获取正确的行数,否则getLineCount()一直等于0。

       第二步 训练小于多少个字数的时候使用多大的字体

        比如0~30个字数的时候,字体大小是50sp不会超过3行,31~50个字数的时候,字体大小是40sp不会超过3行,51~80个字数的时候,字体大小是30sp不会超过3行。那么这个数据需要记录,因为,删除文字的时候,删到哪个位置需要知道改用多大的字体。而且取得当前当前位置使用多大的字体的时候,需要删除这个字数和字体大小对应关系的数据,因为,这个数据,我们需要不断的训练更新,因为大小写,字符,不同的语言,得到到文字length是不同的。

       有了上面两步的分析,我们就可以动态的调整文字的TextSize了。

       给出完整的Demo

       1、页面设计,简单的就一个输入框和一个文本框,输入框输入上面文本框就显示什么

    <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.figo.study.activity.TextActivity">
    
        <TextView
            android:id="@+id/txt_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/et_msg"
            android:text="@string/hello_world"
            android:textColor="#ffffff" />
    
        <EditText
            android:id="@+id/et_msg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="141dp" />
    
    </RelativeLayout>

     2、Activity编写

    package com.figo.study.activity;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextPaint;
    import android.text.TextWatcher;
    import android.util.Log;
    import android.widget.EditText;
    import android.widget.TextView;
    import com.figo.study.R;
    import com.figo.study.utils.CommonUtil;
    import java.util.ArrayList;
    
    /**
     * 控制在3行,自动调整textSize
     */
    public class TextActivity extends Activity {
        TextView mTxt;
        EditText mEt;
        int mDefaultTextSize = 50;
        int lineCount = 0;
        int lastTextLength = 0;
        boolean isMinus = false;
        int maxTextSize = 50;
        int minTextSize = 6;
        ArrayList<PositionTextSize> arrayListPts = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_text);
            initView();
        }
    
        private void initView() {
            mTxt = (TextView) findViewById(R.id.txt_msg);
            mTxt.setMaxWidth(600);
            mTxt.setTextSize(mDefaultTextSize);
            mEt = (EditText) findViewById(R.id.et_msg);
            mEt.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                }
    
                @Override
                public void afterTextChanged(Editable s) {
                    mTxt.setText(s.toString());
                    resizeTextSize(mTxt);
                }
            });
        }
    
    
        private void resizeTextSize(final TextView textView) {
            textView.post(new Runnable() {
                @Override
                public void run() {
                    TextPaint textPaint = textView.getPaint();
                    float currentTextSize = CommonUtil.px2sp(TextActivity.this, textPaint.getTextSize());
                    float newTextSize = currentTextSize;
    
                    lineCount = textView.getLineCount();
                    int currentTextLength = textView.getText().length();
                    if (currentTextLength > lastTextLength) {
                        isMinus = false;
                    } else {
                        //说明是在减
                        isMinus = true;
                    }
                    lastTextLength = currentTextLength;
    
                    if (lineCount > 3) {
                        if (currentTextSize > minTextSize) {
                            newTextSize = currentTextSize - 10;
                        }
                        PositionTextSize pts = new PositionTextSize();
                        pts.textSize = currentTextSize;
                        pts.position = currentTextLength;
                        arrayListPts.add(pts);
    
                    }
                    if (isMinus) {
                        newTextSize = findPositionTextSize(currentTextLength);
                    }
                    if ((newTextSize != currentTextSize) && newTextSize > 0) {
                        textView.setTextSize(newTextSize);
                    }
                    Log.i("TextActivity", "getLineCount:" + lineCount);
                    Log.i("TextActivity", "textSize:" + currentTextSize);
                    Log.i("TextActivity", "textLength:" + currentTextLength);
                    Log.i("TextActivity", "ArraryTextSize:" + arrayToString(arrayListPts));
                }
    
            });
        }
    
        private String arrayToString(ArrayList<PositionTextSize> arrPts) {
            StringBuffer buffer = new StringBuffer();
            for (PositionTextSize pts : arrPts) {
                buffer.append("position:" + pts.position);
                buffer.append(",textSize:" + pts.textSize + "|");
            }
            return buffer.toString();
        }
    
        private float findPositionTextSize(int position) {
            float textSize = 0;
            PositionTextSize result = null;
            int size = arrayListPts.size();
            for (int p = size - 1; p >= 0; p--) {
                if (arrayListPts.get(p).position > position) {
                    result = arrayListPts.get(p);
                    textSize = result.textSize;
                    arrayListPts.remove(result);//删除重新训练
                }
            }
            return textSize;
        }
    
        public class PositionTextSize {
            int position;
            float textSize;
        }
    }
  • 相关阅读:
    xlib dev[1]
    [转]Kinect for Windows SDK开发入门(三):基础知识 下
    [译]Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
    [转]Kinect for Windows SDK开发入门(七):骨骼追踪基础 下
    [转]Kinect for Windows SDK开发入门(一):开发环境配置
    [转]Kinect for Windows SDK开发入门(四):景深数据处理 上
    [转]Kinect for Windows SDK开发入门(二):基础知识 上
    [转]Kinect for Windows SDK开发入门(五):景深数据处理 下
    Ogre/Torque 基础类plane简单释疑
    torque dts格式大概分析
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5917206.html
Copyright © 2020-2023  润新知