Android View編のフォントサイズ調整レバーの実現

12486 ワード

みなさんこんにちは、今回はちょっと面白いビューをご紹介します.100行以上のコードが実現できるので、効果を見てみましょう.
構想分析
1、目盛線はフォントごとの大きさを表しています.SeekBarはこのような機能ですか.目盛フロートのスタイルを変更すればいいです.
2、目盛の上の表記のテキストはフォントの大きさの説明を代表して、仮に1つのLinearLayoutで3つのTextViewを包む方法でテキストと目盛の位置合わせを実現するのは難しいと仮定して、描くしかありません.
コードの書き込みを開始SeekBarをベースに、onDraw()を書き換える方法で、その前に基本プロパティを初期化します.

/**
 *         
 * Created by ChenRui on 2017/10/13 0013 12:50.
 */
public class RaeSeekBar extends AppCompatSeekBar {

    //        ,           , mTextSize      
    private String[] mTickMarkTitles = new String[]{
            "A",
            "  ",
            "",
            "",
            "A"
    };
    //          
    private int[] mTextSize = new int[]{
            16,
            18,
            24,
            26,
            28
    };

    //       
    private final Paint mTickMarkTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    //          
    private float mTickMarkTitleTextSize = 18;
    //             
    private float mOffsetY = 40;
    //       
    private int mLineHeight = 10;
    //         
    private final Rect mRect = new Rect();

    // ...          
    public RaeSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        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.ph1));
        //                  
        setMax(mTextSize.length);
        //        
        setProgress(1);
    }
}

測定レイアウト
従来のSeekBarに加えてテキストを追加するため、従来のSeekBarの高さに最大目盛りの文字を追加すべき高さがコントロールレイアウトの高さです.
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //        
    int wm = MeasureSpec.getMode(widthMeasureSpec);
    int hm = MeasureSpec.getMode(heightMeasureSpec);
    int w = getMeasuredWidth();
    int h = getMeasuredHeight();
    
    //          ,        
    h += getSize(mTextSize[mTextSize.length - 1]);
    //             
    h += mOffsetY;
    //       
    setMeasuredDimension(MeasureSpec.makeMeasureSpec(w, wm), MeasureSpec.makeMeasureSpec(h, hm));
}

再描画
絵の考え方をまとめると、コードの実現をよく理解することができます.全体の過程で3つの部分を描く必要があります.
  • 直線
  • 目盛線
  • 目盛りテキスト
  • もちろんスライドブロックもあります.これはSeekBarが持っている効果を使うことができます.つまり、スタイルをカスタマイズしたり、怠けたりすることができます.次は絵の具体的な手順を解析します.
    1、直線を描く
    まず,外部は矩形であり,直線は中間に位置し,左右の間隔はスライダの半分であると理解した.研究により、getPaddingLeft() getPaddingRight()がちょうどこの半分の値であることが分かった.
    2、目盛線
    目盛線は実際に直線を等分していることがわかりやすく、等分の多少はsetMax()の値に依存し、mTextSize.lengthにも相当し、直線を描くことで簡単に実現できます.
    3、目盛りテキスト
    最も重要なのは、テキストがある(x,y) を特定すればよく、テキストの座標が目盛線の位置に従って変化していることがわかりにくくないので、目盛線を描くときに一緒にテキストも描くことができます.
    4、スライダ位置
    システムスライダの位置は、分割線の位置と同じです.等分直線で、分割線の中心にあります.
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //     
        int maxLength = getMax();
        int width = getWidth();
        int height = getHeight();
        int h2 = height / 2; //   
    
        //      
        mRect.left = getPaddingLeft();
        mRect.right = width - getPaddingRight();
        mRect.top = h2 - getSize(1); //   
        mRect.bottom = mRect.top + getSize(1.5f); // 1.5f      
        //      
        int lineWidth = mRect.width();
        //    
        canvas.drawRect(mRect, mTickMarkTitlePaint);
    
        //      ,         
        for (int i = 0; i <= maxLength; i++) {
    
            //         =     + (      *        /     )
            int thumbPos = getPaddingLeft() + (lineWidth * i / maxLength);
            //     
            mRect.top = h2 - mLineHeight / 2;
            mRect.bottom = h2 + mLineHeight / 2;
            mRect.left = thumbPos;
            mRect.right = thumbPos + getSize(1.5f); //       1.5
            canvas.drawRect(mRect, mTickMarkTitlePaint);
    
            //      
            String title = mTickMarkTitles[i % mTickMarkTitles.length]; //       
            mTickMarkTitlePaint.getTextBounds(title, 0, title.length(), mRect); //              
            mTickMarkTitlePaint.setTextSize(getSize(mTextSize[i])); //         
            //    
            canvas.drawText(title, thumbPos, getSize(mTextSize[mTextSize.length - 1]), mTickMarkTitlePaint);
        }
    }
    

    絵を描くのは待ちきれないのではないでしょうか.実際に応用してみましょうか.
    適用例
  • レイアウトファイル
  • 
    <com.rae.cnblogs.widget.RaeSeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:progressDrawable="@android:color/transparent"
        android:theme="@style/Widget.AppCompat.SeekBar"
        android:thumb="@drawable/seekbar_thumb_material_anim_font_setting" />
    
  • thumbスライダピクチャ
  • <selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
        <item>
            <shape android:shape="oval">
                <solid android:color="@color/badge_color" />
                <size android:width="24dp" android:height="24dp" />
            shape>
        item>
    selector>
    
  • スライダコールバックリスニング
  • mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int value, boolean b) {
                //                 
                int size = mSeekBar.getRawTextSize(value);
                mMessage.setTextSize(size);
            }
            //...       
        });
    

    ソースコード
    はい、この文章はここで終わりました.思わずやってみたくなったのは、ソースコードを参考にしてやってみると、ブログパークAndroidオープンソースクライアントプロジェクトで、好きなのはStar~~
    ソースの主要クラス:
  • RaeSeekBar
  • FontSettingActivity

  • 転載先:https://juejin.im/post/5cd24dfb6fb9a0320c5ac7f8