高级UI具体自定义控件

【安卓相关】自定义控件,重写SeekBar类,显示拖动条控件当前

2020-02-06  本文已影响0人  norkm

场景还原:
最近做开发的时候,用到了Seekbar控件,需要显示拖动条当前滑动到的数值。

<LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <SeekBar
            android:layout_gravity="center"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="50 %"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />
 </LinearLayout>

这好办,旁边加个TextView轻松解决!




完成,收工!








哎,好 Low,实际用起来还麻烦的很,emmmm...
还是试着改改用吧。
ps:第三个和第四个拖动条是 触摸 / 拖动 时的效果,手指抬起或离开则恢复成默认Seekbar的样子。

实现代码:

<com.norkm.diy.NSeekBar
        app:unit="%"
        app:thumbPosition="center"
        app:lucency="true"
        android:max="100"
        android:layout_marginTop="30dp"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <com.norkm.diy.NSeekBar
        app:thumbPosition="top"
        app:lucency="true"
        android:layout_marginTop="100dp"
        android:max="500"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <com.norkm.diy.NSeekBar
        app:thumbPosition="top"
        app:unit="px"
        android:layout_marginTop="100dp"
        android:max="500"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <com.norkm.diy.NSeekBar
        app:thumbPosition="center"
        app:unit="px"
        android:layout_marginTop="100dp"
        android:max="500"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

其中几个重要的自定义属性

属性 描述 补充
app:unit String 向气泡中的文本添加后缀 例如 px , %
app:lucency boolean 气泡是否透明 默认为 false
app:thumbPosition top / center 气泡在中间还是顶部

下面是重写Seekbar的代码,注释应该写的很清楚了,就不做过多描述了。

package com.norkm.diy;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatSeekBar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;

public class NSeekBar extends AppCompatSeekBar {
    private boolean isDrag=false;

    private String seekBar_unit;
    private int seekBar_thumbPosition;
    private boolean seekBar_lucency;

    public NSeekBar(Context context) {
        super(context);
    }

    public NSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NSeekBar);
        seekBar_unit = typedArray.getString(R.styleable.NSeekBar_unit);
        seekBar_thumbPosition = typedArray.getInteger(R.styleable.NSeekBar_thumbPosition,0);
        seekBar_lucency =typedArray.getBoolean(R.styleable.NSeekBar_lucency,false);
        typedArray.recycle();

        if(seekBar_unit ==null){
            seekBar_unit ="";
        }else{
            seekBar_unit =" "+ seekBar_unit+" ";
        }
    }
    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ViewGroup mViewGroup = (ViewGroup) getParent();
        mViewGroup.setClipChildren(false);

        //  字体大小 、 气泡半径 、气泡的 y 轴位置  、拖拽条左边距、拖拽条左边距(像素)
        int textSize=40;
        int pointSize=(textSize)*(String.valueOf(getProgress()).length()+1);
        int floatTop,paddingLeft,paddingLeftPx;

        //  画笔初始化、消除锯齿、填充式风格
        Paint paint=new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);

        paddingLeft = getPaddingLeft();
        paddingLeftPx = (getMeasuredWidth() - paddingLeft * 2) * getProgress() / getMax();
        String text= getProgress()+ seekBar_unit;

        // 浮动球距离顶部距离,0 为top ,1 为 center
        if(seekBar_thumbPosition == 0 ){
            floatTop =getMeasuredHeight() / 2 - pointSize;
        }else{
            floatTop =getMeasuredHeight() / 2;
        }

        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setTextAlign(Paint.Align.CENTER);

        //  如果正在拖动并且非透明效果
        if(isDrag && !seekBar_lucency){
            //  绘制球形阴影
            paint.setStrokeWidth((pointSize/10)*14);
            paint.setColor(Color.GRAY);
            paint.setAlpha(25);
            canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);

            //  绘制纯色圆形
            paint.setAlpha(255);
            paint.setColor(ContextCompat.getColor(getContext(),R.color.colorPrimary));
            paint.setStrokeWidth(pointSize);
            canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);

            //  绘制球形上面的文字
            paint.setTextSize(textSize);
            paint.setColor(Color.WHITE);
            canvas.drawText(text, paddingLeftPx + paddingLeft, floatTop +textSize/4, paint);
        }

        //  透明效果
        if(seekBar_lucency){
            //  如果是透明气泡 且位于顶部 floatTop = 10 否则 TOP = getMeasuredHeight() / 2
            floatTop = (seekBar_thumbPosition==0)   ?   10  :  getMeasuredHeight() / 2  ;


            //  去除默认thunb 与 thumb 的阴影
            if(seekBar_thumbPosition==1){
                setThumb(null);
                setBackground(null);

                //  绘制白色矩形
                paint.setAlpha(255);
                paint.setColor(Color.WHITE);
                int left=(paddingLeftPx + paddingLeft)-pointSize/2;
                int rigt=(paddingLeftPx + paddingLeft)+(pointSize/2);
                int top=getHeight()/2-textSize;
                int bottom=getHeight()/2+textSize;
                canvas.drawRect(new Rect(left,top,rigt,bottom),paint);
                Log.i("结果",getSuggestedMinimumHeight()+"");
            }else{
                //  绘制透明背景
                paint.setStrokeCap(Paint.Cap.SQUARE);
                paint.setAlpha(255);
                paint.setColor(Color.TRANSPARENT);
                paint.setStrokeWidth(pointSize);
                canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);
            }


            //  绘制控件上面的文字
            paint.setTextSize(textSize);
            paint.setColor(ContextCompat.getColor(getContext(),R.color.colorPrimary));
            canvas.drawText(text, paddingLeftPx + paddingLeft, floatTop +textSize/4, paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                isDrag=true;
                break;
            case MotionEvent.ACTION_MOVE:
                isDrag=true;
                break;
            case MotionEvent.ACTION_UP:
                isDrag=false;
                break;
            case MotionEvent.ACTION_OUTSIDE:
                isDrag=false;
                break;
        }
        return super.onTouchEvent(event);
    }
}


写好视图类后,再向 values / attrs.xml 文件中添加自定义属性。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 自定义拖拽条 -->
    <declare-styleable name="NSeekBar">
        <attr name="thumbPosition" format="integer">
            <flag name="top" value="0" />
            <flag name="center" value="1"/>
        </attr>
        <attr name="unit" format="string"/>
        <attr name="lucency" format="boolean"/>
    </declare-styleable>
</resources>

水平有限,如有疏漏,可在话题区留言,感谢!

上一篇下一篇

猜你喜欢

热点阅读