<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Android仿微信全局字體大小調整

          共 9593字,需瀏覽 20分鐘

           ·

          2021-11-14 00:33

          一、前言

          最近項目添加了一項調整應用字體大小功能,做完后空閑之余總結一下。本功能仿照微信應用“設置” - “通用”? -? “字體大小”功能,又有一點區(qū)別。據(jù)我所知,常見改變全局字體大小方法有兩種,我把這兩種分為可控和不可控,為什么這么分呢,當然不是為了方便記憶。那么簡單說下兩者方式的實現(xiàn)過程:


          1、不可控:通過重寫Actiivity的getResources()方法更新應用的字體倍數(shù)來調整全局字體大小


          優(yōu)點:實現(xiàn)簡單

          缺點:不可控制(所有字體放大倍數(shù)都是一致),無法跨進程(項目中另一個進程的字體不會改變,需要重新配置),只對sp字體單位有效果。....

          2、可控:通過setTheme()方法,一開始就初始化設置不同風格的字體樣式來更改全局字體大小。


          優(yōu)點:隨意調節(jié)任意位置的字體大小

          缺點:實現(xiàn)麻煩

          而本文正式采用了第一種方案,主要是中途添加該功能,時間也不充裕,抽取字體大小又太過耗時。


          微信字體大小個人猜測使用第二種方案,后者是更好的實現(xiàn)方式也不一定。


          二、效果預覽



          三、實現(xiàn)步驟


          1、自定義字體調整控件


          網(wǎng)上找了一個相似的控件并加以完善,功能相對簡單,就不做介紹了。


          /** * TODO 仿微信字體大小調整 * 自定義屬性: * lineWidth 線條粗細 * lineColor 線條顏色 * totalCount 線條格數(shù) * circleColor 球型顏色 * circleRadius 球型顏色半徑 * textFontColor 文字顏色 * smallSize 小“A” 字體大小 * standerSize “標準” 字體大小 * bigSize 大“A” 字體大小 * defaultPosition 默認位置 */public class FontSizeView extends View {
          private int defaultLineColor = Color.rgb(33, 33, 33); private int defaultLineWidth; private int defaultMax = 5; private int defaultCircleColor = Color.WHITE; private int defaultCircleRadius; // 當前所在位置 private int currentProgress;
          // 默認位置 private int defaultPosition = 1;
          // 一共有多少格 private int max = 7; // 線條顏色 private int lineColor = Color.BLACK; // 線條粗細 private int lineWidth;
          //字體顏色 private int textColor = Color.BLACK; //字體大小 private int smallSize = 14; private int standerSize = 16; private int bigSize = 28;
          // 圓半徑 private int circleRadius; private int circleColor = Color.WHITE; // 一段的寬度,根據(jù)總寬度和總格數(shù)計算得來 private int itemWidth; // 控件的寬高 private int height; private int width; // 畫筆 private Paint mLinePaint; private Paint mTextPaint; private Paint mText1Paint; private Paint mText2Paint; private Paint mCirclePaint; // 滑動過程中x坐標 private float currentX = 0; // 有效數(shù)據(jù)點 private List points = new ArrayList<>();
          private float circleY; private float textScaleX; private float text1ScaleX; private float text2ScaleX;
          public FontSizeView(Context context) { this(context, null); }
          public FontSizeView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); }
          private void init(Context context, AttributeSet attrs) {
          // initDefault defaultLineWidth = DensityUtils.dp2px(context, 2); defaultCircleRadius = DensityUtils.dp2px(context, 35); lineWidth = DensityUtils.dp2px(context, 1); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FontSizeView); final int N = typedArray.getIndexCount(); for (int i = 0; i < N; i++) { initCustomAttr(typedArray.getIndex(i), typedArray); } typedArray.recycle(); // 初始化畫筆 mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setColor(lineColor); mLinePaint.setStyle(Paint.Style.FILL_AND_STROKE); mLinePaint.setStrokeWidth(lineWidth);
          //文字畫筆 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setColor(textColor); mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);// mTextPaint.setStrokeWidth(DensityUtils.dp2px(context, 1)); mTextPaint.setTextSize(DensityUtils.sp2px(context, smallSize)); textScaleX = mTextPaint.measureText("A"); //文字畫筆 mText1Paint = new Paint(Paint.ANTI_ALIAS_FLAG); mText1Paint.setColor(textColor); mText1Paint.setStyle(Paint.Style.FILL_AND_STROKE); mText1Paint.setTextSize(DensityUtils.sp2px(context, bigSize)); text1ScaleX = mText1Paint.measureText("A");
          //文字畫筆 mText2Paint = new Paint(Paint.ANTI_ALIAS_FLAG); mText2Paint.setColor(textColor); mText2Paint.setStyle(Paint.Style.FILL_AND_STROKE); mText2Paint.setTextSize(DensityUtils.sp2px(context, standerSize)); text2ScaleX = mText2Paint.measureText("標準");
          mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setColor(circleColor); mCirclePaint.setStyle(Paint.Style.FILL);
          // 設置陰影效果 setLayerType(LAYER_TYPE_SOFTWARE, null); mCirclePaint.setShadowLayer(2, 0, 0, Color.rgb(33, 33, 33)); }
          private void initCustomAttr(int attr, TypedArray typedArray) { if (attr == R.styleable.FontSizeView_lineColor) { lineColor = typedArray.getColor(attr, defaultLineColor); } else if (attr == R.styleable.FontSizeView_circleColor) { circleColor = typedArray.getColor(attr, defaultCircleColor); } else if (attr == R.styleable.FontSizeView_lineWidth) { lineWidth = typedArray.getDimensionPixelSize(attr, defaultLineWidth); } else if (attr == R.styleable.FontSizeView_circleRadius) { circleRadius = typedArray.getDimensionPixelSize(attr, defaultCircleRadius); } else if (attr == R.styleable.FontSizeView_totalCount) { max = typedArray.getInteger(attr, defaultMax); } else if (attr == R.styleable.FontSizeView_textFontColor) { textColor = typedArray.getColor(attr, textColor); } else if (attr == R.styleable.FontSizeView_smallSize) { smallSize = typedArray.getInteger(attr, smallSize); } else if (attr == R.styleable.FontSizeView_standerSize) { standerSize = typedArray.getInteger(attr, standerSize); } else if (attr == R.styleable.FontSizeView_bigSize) { bigSize = typedArray.getInteger(attr, bigSize); }else if (attr == R.styleable.FontSizeView_defaultPosition) { defaultPosition = typedArray.getInteger(attr, defaultPosition); } }
          @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); height = h; width = w; circleY = height / 2; // 橫線寬度是總寬度-2個圓的半徑 itemWidth = (w - 2 * circleRadius) / max; // 把可點擊點保存起來 for (int i = 0; i <= max; i++) { points.add(new Point(circleRadius + i * itemWidth, height / 2)); } //初始刻度 currentX = points.get(defaultPosition).x; }
          @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //畫字 canvas.drawText("A", points.get(0).x - textScaleX / 2, height / 2 - 50, mTextPaint);
          //畫字 canvas.drawText("標準", points.get(1).x - text2ScaleX / 2, height / 2 - 50, mText2Paint);
          //畫字 canvas.drawText("A", points.get(points.size() - 1).x - text1ScaleX / 2, height / 2 - 50, mText1Paint);
          // 先畫中間的橫線 canvas.drawLine(points.get(0).x, height / 2, points.get(points.size() - 1).x, height / 2, mLinePaint); // 繪制刻度 for (Point point : points) { canvas.drawLine(point.x + 1, height / 2 - 20, point.x + 1, height / 2 + 20, mLinePaint); }
          // 畫圓 if (currentX < circleRadius) { currentX = circleRadius; } if (currentX > width - circleRadius) { currentX = width - circleRadius; }
          // 實體圓 canvas.drawCircle(currentX + 1, circleY, circleRadius, mCirclePaint); }
          @Override public boolean onTouchEvent(MotionEvent event) { currentX = event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: invalidate(); break; case MotionEvent.ACTION_MOVE: invalidate(); break; case MotionEvent.ACTION_UP: //回到最近的一個刻度點 Point targetPoint = getNearestPoint(currentX); if (targetPoint != null) { // 最終 currentX = points.get(currentProgress).x; invalidate(); } if (onChangeCallbackListener != null) { onChangeCallbackListener.onChangeListener(currentProgress); } break; } return true; }
          /** * 獲取最近的刻度 */ private Point getNearestPoint(float x) { for (int i = 0; i < points.size(); i++) { Point point = points.get(i); if (Math.abs(point.x - x) < itemWidth / 2) { currentProgress = i; return point; } } return null; }
          public void setChangeCallbackListener(OnChangeCallbackListener listener) { this.onChangeCallbackListener = listener; }
          private OnChangeCallbackListener onChangeCallbackListener;
          public interface OnChangeCallbackListener { void onChangeListener(int position); }
          public void setDefaultPosition(int position){ defaultPosition=position; if (onChangeCallbackListener != null) { onChangeCallbackListener.onChangeListener(defaultPosition); } invalidate(); }}


          xml使用方式:

                   android:id="@+id/fsv_font_size"        android:layout_width="wrap_content"        android:layout_height="120dp"        android:layout_marginLeft="@dimen/space_line2"        android:layout_marginRight="@dimen/space_line2"        android:background="@color/white"        app:circleRadius="11dp"        app:lineColor="@color/round_corner_progress_bar_progress_default"        app:standerSize="16" />


          2、滑動按鈕改變當前頁面預覽字體大小

           //備注            14sp        16sp        18sp        20sp        22sp        24sp        26sp        28sp


           //滑動返回監(jiān)聽        fsvFontSize.setChangeCallbackListener(new FontSizeView.OnChangeCallbackListener() {            @Override            public void onChangeListener(int position) {                int dimension = getResources().getDimensionPixelSize(R.dimen.sp_stander);                //根據(jù)position 獲取字體倍數(shù)                fontSizeScale = (float) (0.875 + 0.125 * position);                //放大后的sp單位                double v = fontSizeScale * (int) DensityUtils.px2sp(FontSizeActivity.this, dimension);                //改變當前頁面大小                changeTextSize((int) v);            }        });
           /**     * 改變textsize 大小     */    private void changeTextSize(int dimension) {        tv_font_size1.setTextSize(dimension);        tv_font_size2.setTextSize(dimension);        tv_font_size3.setTextSize(dimension);    }


          3、返回時,保存放大倍數(shù)并重啟應用

          public void onClick(View view) {      SPUtils.put(FontSizeActivity.this,Constants.SP_FontScale,fontSizeScale);      //重啟應用      AppManager.getAppManager().finishAllActivity();      IntentUtils.toActivity(FontSizeActivity.this, MainActivity.class,true);  }


          4、初始化應用時配置字體放大倍數(shù)。

          改變全局大小的關鍵? //? res.updateConfiguration(config,res.getDisplayMetrics());

           //fontSizeScale = (float) SPUtils.get(this, Constants.SP_FontScale, 0.0f); @Override    public Resources getResources() {        Resources res =super.getResources();        Configuration config = res.getConfiguration();        if(fontSizeScale>0.5){//防止第一次獲取SP時得到默認值0            config.fontScale= fontSizeScale;//設置正常字體大小的倍數(shù)        }        res.updateConfiguration(config,res.getDisplayMetrics());        return res;    }


          源碼地址:
          https://github.com/DayorNight/BLCS


          到這里就結束啦。
          瀏覽 71
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美在线无码视频 | 女人天天干免费视频 | 九精品| 久久成人导航 | 伊人久久大香 |