textarea修改字体位置_Android自定义实现字体大小修改

简单记录下今天做的自定义字体大小修改的功能

需求:添加具体字体自定义大小功能、不需要跟随系统字体大小改变而改变
1.首先看一下用到的调节字体大小的控件:

642ef326b700a5bf04298e87a149bf69.png

控件继承自系统的SeekBar,添加了刻度、文字代码如下:

/** * Des: */public class RaeSeekBar extends AppCompatSeekBar {    //  刻度说明文本,数组数量跟刻度数量一致,跟mTextSize的长度要一致    private String[] mTickMarkTitles = new String[]{            "A",            "标准",            "",            "A"    };    // 刻度代表的字体大小    private float[] mTextSize = new float[]{            0.8f,            1.0f,            1.15f,            1.3f    };    // 刻度画笔    private final Paint mTickMarkTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);    //文本画笔    private final Paint mTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);    //  刻度文本字体大小    private float mTickMarkTitleTextSize = 18;    // 刻度文本跟刻度之间的间隔    private float mOffsetY = 40;    // 刻度线的高度    private int mLineHeight = 10;    // 保存位置大小信息    private final Rect mRect = new Rect();    private int mThumbHeight;    private int mThumbWidth;    public RaeSeekBar(Context context) {        this(context, null);    }    public RaeSeekBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public RaeSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    protected void init() {        mTickMarkTitleTextSize = getSize(mTickMarkTitleTextSize);        mOffsetY = getSize(mOffsetY);        mLineHeight = getSize(mLineHeight);        mTickMarkTitlePaint.setTextAlign(Paint.Align.CENTER);        mTickMarkTitlePaint.setColor(ContextCompat.getColor(getContext(), R.color.color_66989FC3));        mTitlePaint.setTextAlign(Paint.Align.CENTER);        mTitlePaint.setColor(ContextCompat.getColor(getContext(), R.color.color_303132));    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int max = getMax();        int width = canvas.getWidth();        int height = canvas.getHeight();        int h2 = height / 2;        // 画刻度背景        mRect.left = getPaddingLeft();        mRect.right = width - getPaddingRight();        mRect.top = h2 - getSize(1);        mRect.bottom = mRect.top + getSize(1.0f);        canvas.drawRect(mRect, mTickMarkTitlePaint);        int cw = mRect.right - mRect.left; // 总画线的长度 = 右边坐标 - 左边坐标        for (int i = 0; i <= max; i++) {            // 每个间隔的大小            int thumbPos = getPaddingLeft() + (cw * i / max);            // 画分割线            mRect.top = h2 - mLineHeight / 2;            mRect.bottom = h2 + mLineHeight / 2;            mRect.left = thumbPos;            mRect.right = thumbPos + getSize(1.0f);            canvas.drawRect(mRect, mTickMarkTitlePaint);            // 画刻度文本            String title = mTickMarkTitles[i % mTickMarkTitles.length];            mTitlePaint.getTextBounds(title, 0, title.length(), mRect);            mTitlePaint.setTextSize(mTextSize[i] * mTickMarkTitleTextSize);            canvas.drawText(title, thumbPos, mTextSize[mTextSize.length - 1] * mTickMarkTitleTextSize, mTitlePaint);        }    }    @Override    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mThumbWidth = getThumb().getIntrinsicWidth();        mThumbHeight = getThumb().getIntrinsicHeight();        // 加上字体大小        int wm = MeasureSpec.getMode(widthMeasureSpec);        int hm = MeasureSpec.getMode(heightMeasureSpec);        int w = getMeasuredWidth();        int h = getMeasuredHeight();        h += mTextSize[mTextSize.length - 1] * mTickMarkTitleTextSize; // 最大的字体        h += mOffsetY;        // 保存        setMeasuredDimension(MeasureSpec.makeMeasureSpec(w, wm), MeasureSpec.makeMeasureSpec(h, hm));    }    protected int getSize(float size) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, getResources().getDisplayMetrics());    }    public float getRawTextSize(int progress) {        return mTextSize[progress % mTextSize.length];    }    public void setTextSize(float size) {        for (int i = 0; i < mTextSize.length; i++) {            float textSize = mTextSize[i];            if (textSize == size) {                setProgress(i);                break;            }        }    }}
2.RaeSeekBar控件的具体使用

代码如下:

        RaeSeekBar raeSeekBar = findViewById(R.id.rae_seek_bar);        scalaSize = SPUtils.getInstance().getFloat(SPConfig.FONT_SIZE_SCALE, 1.0f);        setTvSize(scalaSize);        raeSeekBar.setTextSize(scalaSize);        raeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {            @Override            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                scalaSize = raeSeekBar.getRawTextSize(progress);                setTvSize(scalaSize);            }            @Override            public void onStartTrackingTouch(SeekBar seekBar) {            }            @Override            public void onStopTrackingTouch(SeekBar seekBar) {            }        });
3.实现部分界面的字体大小的修改

先看看修改字体大小代码,如下:

    /**     * 修改字体大小     *     * @param spKey     */    protected void changeFontSize(String spKey) {        float scale = 1.0f;        Configuration c = getResources().getConfiguration();        if (!TextUtils.isEmpty(spKey)) {            scale = SPUtils.getInstance().getFloat(spKey, 1.0f);        }        c.fontScale = scale;//        DisplayMetrics metrics = new DisplayMetrics();//        getWindowManager().getDefaultDisplay().getMetrics(metrics);//        metrics.scaledDensity = c.fontScale * metrics.density;        getResources().updateConfiguration(c, getResources().getDisplayMetrics());    }

修改字体大小的代码放在BaseActivity中在onCreate中调用changeFontSize(null);,即:

 /**     * 是否需要重置字体大小     * 只有在需要调节字体大小的界面不需要重置,其他的均需要重置     */    protected boolean isNeedResetFontSize = true;    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        BarUtils.setStatusBarColor(this, getResources().getColor(R.color.color_translation));        BarUtil.getInstance().setStatusBarFontIconDark(this, false);        if (isNeedResetFontSize) {            changeFontSize(null);        }        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_base);    }

在需要字体大小改变的页面onCreate中调用changeFontSize("你保存的修改后的字体的倍数对应的SP中的Key");,例如:

    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        isNeedResetFontSize = false;        changeFontSize(SPConfig.FONT_SIZE_SCALE);        super.onCreate(savedInstanceState);    }

到这里修改字体的工作基本上算是完了
但是
修改系统字体大小后会发现自己修改的字体的大小是累加在修改后的系统字体大小之上的

4.禁止APP的字体大小跟随系统字体大小改变而改变

1.Application中重写getResources方法:

    /**     * 重写 getResource 方法,防止系统字体影响     */    @Override    public Resources getResources() {//禁止app字体大小跟随系统字体大小调节        Resources resources = super.getResources();        if (resources != null && resources.getConfiguration().fontScale != 1.0f) {            android.content.res.Configuration configuration = resources.getConfiguration();            configuration.fontScale = 1.0f;            resources.updateConfiguration(configuration, resources.getDisplayMetrics());        }        return resources;    }

2.BaseActivity中重写getResources方法:

    /**     * 重写 getResource 方法,防止系统字体影响     */    @Override    public Resources getResources() {//禁止app字体大小跟随系统字体大小调节        Resources resources = super.getResources();        if (isNeedResetFontSize) {            if (resources != null && resources.getConfiguration().fontScale != 1.0f) {                android.content.res.Configuration configuration = resources.getConfiguration();                configuration.fontScale = 1.0f;                resources.updateConfiguration(configuration, resources.getDisplayMetrics());            }        }        return resources;    }
  • 上面的代码在红米3开发版手机上的效果不理想,如下图:

    f12f4827692e33ff4fef9eeae79f9e6a.png

    图中SeekBar设置的thumb图片跑到了刻度上方

看了下源码(AbsSeekBar.java:732行):

    /**     * Draw the thumb.     */    void drawThumb(Canvas canvas) {        if (mThumb != null) {            final int saveCount = canvas.save();            // Translate the padding. For the x, we need to allow the thumb to            // draw in its extra space            canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);            mThumb.draw(canvas);            canvas.restoreToCount(saveCount);        }    }

源码中画thumb是通过padding值来确定位置的,所以,通过设置padding来适配红米3,代码修改如下:

    @Override    protected void onDraw(Canvas canvas) {        Drawable thumb = getThumb();        int max = getMax();        int width = canvas.getWidth();        int height = canvas.getHeight();        int h2 = height / 2;        boolean xiaomi = RomUtils.isXiaomi();        if (xiaomi) {            setPadding(getPaddingLeft(), (height - thumb.getIntrinsicHeight()) / 2, getPaddingRight(), getPaddingBottom());        }        super.onDraw(canvas);        // 画刻度背景        mRect.left = getPaddingLeft();        mRect.right = width - getPaddingRight();        mRect.top = h2 - getSize(1);        mRect.bottom = mRect.top + getSize(1.0f);        canvas.drawRect(mRect, mTickMarkTitlePaint);        int cw = mRect.right - mRect.left; // 总画线的长度 = 右边坐标 - 左边坐标        for (int i = 0; i <= max; i++) {            // 每个间隔的大小            int thumbPos = getPaddingLeft() + (cw * i / max);            // 画分割线            mRect.top = h2 - mLineHeight / 2;            mRect.bottom = h2 + mLineHeight / 2;            mRect.left = thumbPos;            mRect.right = thumbPos + getSize(1.0f);            canvas.drawRect(mRect, mTickMarkTitlePaint);            // 画刻度文本            String title = mTickMarkTitles[i % mTickMarkTitles.length];            mTitlePaint.getTextBounds(title, 0, title.length(), mRect);            mTitlePaint.setTextSize(mTextSize[i] * mTickMarkTitleTextSize);            canvas.drawText(title, thumbPos, mTextSize[mTextSize.length - 1] * mTickMarkTitleTextSize, mTitlePaint);        }    }

到这里就结束啦.

4444792222e83f627e021a8b26739f76.png

b77e5b578e5c9226fdb6bbffa4c8e95b.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值