为了账号安全,请及时绑定邮箱和手机立即绑定

安卓自定义滑动刻度尺,选择身高体重等

标签:
Android

由于最近项目需求,需要一个滑动的刻度尺来选择会员体重,所以自己写了一个选择体重的控件,成品效果就不展示了,下边直接上代码描述基本原理,以及基本的效果:

package view;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.rulerview.R;

/**
 * Created by Administrator on 2018/5/19.
 */

public class RulerView extends View {
    Paint paint;
    int wholeWidth,mCountScale;

    private int[] attrArray = {R.attr.min_number,R.attr.max_number,R.attr.ruler_height,R.attr.spacing};
    int min_number,max_number,ruler_height,mRuler_width,mRuler_height,spacing;
    int len = 40;//刻度的高度

    public RulerView(Context context) {
        super(context);
        initView(null);
    }

    public RulerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);
    }

    public RulerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public RulerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(attrs);
    }

    private void initView(AttributeSet attrs) {

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, attrArray);

        min_number = typedArray.getInteger(0, 0);
        max_number = typedArray.getInteger(attrArray.length-3, 200);
        ruler_height = typedArray.getDimensionPixelOffset(attrArray.length-2,40);
        spacing = typedArray.getDimensionPixelOffset(attrArray.length-1,5);

        typedArray.recycle();

        mRuler_width = (max_number-min_number) * spacing;
        mRuler_height = ruler_height * 2;
        ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(mRuler_width, mRuler_height);
        lp.setMargins(15,0,15,0);
        this.setLayoutParams(lp);
        initPaint();
    }

    int direction;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        wholeWidth = widthMeasureSpec;
        direction = wholeWidth / spacing / 2 + min_number;
        super.onMeasure(MeasureSpec.makeMeasureSpec(mRuler_width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(mRuler_height, MeasureSpec.AT_MOST));
    }

    private void initPaint(){
        paint = new Paint();
        paint.setColor(Color.GRAY);
        paint.setAntiAlias(true);// 抗锯齿
        paint.setDither(true);//图像抖动处理
        paint.setStyle(Paint.Style.STROKE);
        paint.setTextAlign(Paint.Align.CENTER);
    }

    protected OnScrollListener mScrollListener;

    public interface OnScrollListener {
        void onScaleScroll(int scale);
    }

    public void setOnScrollListener(OnScrollListener listener) {
        this.mScrollListener = listener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawLine(0, mRuler_height, mRuler_width, mRuler_height, paint);//画横线

        paint.setTextSize(18);
        for (int i = 0, j = min_number; i <= max_number - min_number; i++) {
            if (i % 10 == 0) {
                canvas.drawLine(i * spacing, mRuler_height, i * spacing, mRuler_height-len , paint);
                canvas.drawText(j+"", i * spacing, mRuler_height - len-20, paint);
                j += 10;
            } else {
                canvas.drawLine(i * spacing, mRuler_height, i * spacing, mRuler_height - len + 15, paint);
            }
        }
        //滑动的刻度
        int tmpCountScale = (int) Math.rint((double) deltaX / (double) spacing); //四舍五入取整
        //需要显示的刻度
        mCountScale =((max_number-min_number)/2) - tmpCountScale;
        if (mScrollListener != null) { //回调方法
            mScrollListener.onScaleScroll(mCountScale);
        }
    }
    int deltaX;
    private int downX;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int)event.getX();
                return true;
            case MotionEvent.ACTION_MOVE:
                deltaX = (int)event.getX()-downX;
                setTranslationX(deltaX);
                postInvalidate();
                return true;
        }

        return super.onTouchEvent(event);
    }
}

自定义的属性:

<resources>
    <attr name="min_number" format="integer"/>
    <attr name="max_number" format="integer"/>
    <attr name="ruler_height" format="dimension"/>
    <attr name="spacing" format="dimension"/>

</resources>

然后是activity里的调用:

RulerView ruler = findViewById(R.id.ruler);
        ruler.setOnScrollListener(new RulerView.OnScrollListener() {
            @Override
            public void onScaleScroll(int scale) {
                tv.setText(scale+"");
            }
        });

基本效果图:
图片描述

点击查看更多内容
3人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消