<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仿今日頭條文字漸變效果

          共 8483字,需瀏覽 17分鐘

           ·

          2021-09-12 12:29

          概述

          本文主要分享仿今日頭條文字漸變效果,效果圖如下:


          實(shí)現(xiàn)要點(diǎn):
          • 繪制水平垂直居中的文本

          • 采用畫布裁剪實(shí)現(xiàn)漸變效果


          繪制水平垂直居中的文本


          文本水平居中


          文本水平居中有兩種方式:
          • 調(diào)用Paint的setTextAlign(Paint.Align.CENTER)方法

          • 控件寬度 / 2 - 文字寬度 / 2計算文本的x軸坐標(biāo)


          文本垂直居中


          文本垂直居中重點(diǎn)在于計算基準(zhǔn)線,大致過程如下:
          • 獲取View的中心位置

          • 中心位置下移半個字體的高度

          • 上移descent,達(dá)到文字的最終位置即BaseLine的位置


          代碼實(shí)現(xiàn)如下:

            Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();  float baseLine = (getHeight() + fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent;


          為了方便理解,baseLine的計算,可參考下圖:


          畫布裁剪實(shí)現(xiàn)漸變效果


          文字漸變主要是通過畫布裁剪實(shí)現(xiàn)的,裁剪漸變部分與不變部分再進(jìn)行疊加,從而達(dá)到漸變的效果,這種實(shí)現(xiàn)方式有一個好處是防止過度繪制。

          關(guān)鍵代碼如下:
          //漸變部分 private void drawGradientText(Canvas canvas) {        //保存當(dāng)前畫布        canvas.save();        //文字水平居中方案二:x = getWidth() / 2 - 文字寬度 / 2        float textWidth = mTextPaint.measureText(mText, 0, mText.length());        float x = (getWidth() - textWidth) / 2;
          //文字垂直居中:BaseLine的計算 = getHeight() / 2 + 文字高度 / 2 - descent
          Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); float textHeight = fontMetrics.descent - fontMetrics.ascent; float y = (getHeight() + textHeight) / 2 - fontMetrics.descent;
          mTextPaint.setColor(Color.RED);
          //先裁剪漸變區(qū)域文字要顯示的區(qū)域 float right = x + textWidth * mPercent; canvas.clipRect(x, 0, right, getHeight());
          //裁剪完成后再繪制文字 canvas.drawText(mText, x, y, mTextPaint);
          //恢復(fù)畫布 canvas.restore(); } //不變部分 private void drawNormalText(Canvas canvas) { canvas.save(); float textWidth = mTextPaint.measureText(mText, 0, mText.length()); float x = (getWidth() - textWidth) / 2;
          Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); float textHeight = fontMetrics.descent - fontMetrics.ascent; float y = (getHeight() + textHeight) / 2 - fontMetrics.descent;
          mTextPaint.setColor(Color.BLACK);
          //對不變區(qū)域文字進(jìn)行裁剪,防止過度繪制(這個很重要) float left = x + textWidth * mPercent; canvas.clipRect(left, 0, x + textWidth, getHeight());
          canvas.drawText(mText, x, y, mTextPaint);
          canvas.restore(); }


          仿今日頭條文字漸變效果實(shí)現(xiàn)思路


          知道了文本繪制居中與畫布裁剪后,實(shí)現(xiàn)仿今日頭條文字漸變效果就很簡單了,大致思路是通過監(jiān)聽ViewPager的滾動獲取滾動的百分比,再通過滾動百分比計算出漸變區(qū)域與不變區(qū)域并分別進(jìn)行裁剪,最后通過圖層疊效果就出來了。

          漸變控件關(guān)鍵代碼:
          public class ColorChangeTextView extends AppCompatTextView {
          private int mTextSize = sp2px(30); private int mTextColor = Color.BLACK; private int mTextColorChange = Color.RED;
          private TextPaint mTextPaint;
          private int mDirection = LEFT;//文件漸變方向
          protected static final int LEFT = 0; protected static final int RIGHT = 1; @IntDef(value = {LEFT, RIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface Direction { }
          private float mProgress;//文字漸變的進(jìn)度
          public float getProgress() { return mProgress; }
          public void setProgress(float mProgress) { this.mProgress = mProgress; invalidate(); }
          public void setDirection(@Direction int direction) { this.mDirection = direction; }
          public ColorChangeTextView(Context context) { this(context, null); }
          public ColorChangeTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
          public ColorChangeTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttr(context, attrs); init(); }
          private void initAttr(final Context context, @Nullable final AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColorChangeTextView); mTextSize = ta.getDimensionPixelSize( R.styleable.ColorChangeTextView_text_size, mTextSize); mTextColor = ta.getColor( R.styleable.ColorChangeTextView_text_color, mTextColor); mTextColorChange = ta.getColor( R.styleable.ColorChangeTextView_text_color_change, mTextColorChange); mProgress = ta.getFloat(R.styleable.ColorChangeTextView_progress, 0);
          ta.recycle(); }
          private void init() { mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); mTextPaint.setColor(mTextColor); mTextPaint.setTextSize(mTextSize); }
          @Override protected void onDraw(Canvas canvas) { switch (mDirection){ case LEFT: drawLeft(canvas); break; case RIGHT: drawRight(canvas); break; } }
          private void drawLeft(Canvas canvas){ //繪制底部不變部分 canvas.save();
          String text = getText().toString(); float textWidth = mTextPaint.measureText(text); Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); float textHeight = fontMetrics.descent - fontMetrics.ascent;
          float x = (getWidth() - textWidth) / 2; float baseLine = (getHeight() + textHeight) / 2 - fontMetrics.descent;
          float left = x + textWidth * mProgress; canvas.clipRect(left,0,x + textWidth,getHeight()); mTextPaint.setColor(mTextColor); canvas.drawText(text,x,baseLine,mTextPaint);
          canvas.restore();
          //繪制頂部漸變部分 canvas.save();
          float right = x + textWidth * mProgress; canvas.clipRect(x,0,right,getHeight()); mTextPaint.setColor(mTextColorChange); canvas.drawText(text,x,baseLine,mTextPaint);
          canvas.restore(); }
          private void drawRight(Canvas canvas) {
          //繪制頂部漸變部分 canvas.save();
          String text = getText().toString(); float textWidth = mTextPaint.measureText(text); Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); float textHeight = fontMetrics.descent - fontMetrics.ascent; float baseLine = (getHeight() + textHeight) / 2 - fontMetrics.descent; float x = (getWidth() - textWidth) / 2;
          float left = x + textWidth * (1 - mProgress); float right = x + textWidth; canvas.clipRect(left,0,right,getHeight()); mTextPaint.setColor(mTextColorChange); canvas.drawText(text,x,baseLine,mTextPaint);
          canvas.restore();
          //繪制底部不變部分 canvas.save();
          right = x + textWidth * (1 - mProgress); canvas.clipRect(0,0,right,getHeight()); mTextPaint.setColor(mTextColor); canvas.drawText(text,x,baseLine,mTextPaint);
          canvas.restore(); }
          static int sp2px(float sp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, Resources.getSystem().getDisplayMetrics()); }}


          ViewPager滾動的關(guān)鍵代碼:
           mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){            @Override            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {                if(positionOffset > 0){                    ColorChangeTextView left = mTabs.get(position);                    ColorChangeTextView right = mTabs.get(position + 1);
          left.setDirection(ColorChangeTextView.RIGHT); right.setDirection(ColorChangeTextView.LEFT);
          left.setProgress(1- positionOffset); right.setProgress(positionOffset); } } });


          需要源碼的童鞋公眾號回復(fù):"TextDraw"即可獲取哦.


          到這里就結(jié)束啦。
          瀏覽 47
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  青青草久久久 | 男女内射动漫网站 | 久久岛国电影免费观看软件 | 五月丁香中文字幕 | 在线观看国产区 |