美文网首页
含加号减号 控制 数字的自定义控件

含加号减号 控制 数字的自定义控件

作者: heheworld | 来源:发表于2020-03-03 00:04 被阅读0次

    维护的项目,因为疫情影响,需要加上体温监控,APP端需要用到设置体温区间的控件
    网上搜了一大把,基本都是基于一个线性布局包含三个控件来实现的。
    实在是闲来无聊,自己新写了一个,纯天然的自定义控件。。
    效果图如下:

    因为需求是不可以

    手动输入值,所以控件只支持+-号操作,长按的时候也会动的,如果觉得慢的话,可以修改那个sleep间隔。

    代码:
    布局文件
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <com.nico.myapplication.AddSubInputView
            android:id="@+id/min_temp_view"
            android:layout_width="300px"
            android:layout_height="60px"
            android:textColor="#888888"
            android:textSize="16sp"
            app:add_icon="@mipmap/temp_plus"
            app:default_value="36.2"
            app:low="true"
            app:sub_icon="@mipmap/temp_sub"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </android.support.constraint.ConstraintLayout>
    

    自定义控件代码
    AddSubInputView

    package com.nico.myapplication;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class AddSubInputView extends View implements Runnable {
        private int mViewWidth;
        private int mViewHeight;
    
        private Drawable mAddDrawable, mSubDrawable, mBackgroudDrawable;
    
        private int mSubRightEdge, mAddLeftEdge;
    
        private float mDefaultValue = 0.0f;
    
        private float mCurrentValue = 0.0f;
    
        private boolean isLow = true;
    
        private int mTextSize;
    
        private int mTextColor;
    
        LinkedBlockingQueue mTask = new LinkedBlockingQueue();
    
        @Override
        public void run() {
            if (!mTask.isEmpty()) {
                return;
            } else {
                mTask.add("data");
                switch (mCurrentStatus) {
                    case LEFT:
                        doOperator(true);
                        break;
                    case RIGHT:
                        doOperator(false);
                        break;
                }
                try {
                    Thread.sleep(800);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mTask.clear();
    
            }
    
        }
    
        private enum STATUS {
            LEFT,
            CENTER,
            RIGHT,
        }
    
        private STATUS mCurrentStatus = STATUS.CENTER;
    
        private Executor executors = Executors.newCachedThreadPool();
    
        public AddSubInputView(Context context) {
            super(context);
        }
    
        public AddSubInputView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView(attrs);
        }
    
        public AddSubInputView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView(attrs);
        }
    
        private void initView(AttributeSet attrs) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.AddSubInputView);
            mViewWidth = (int) a.getDimension(R.styleable.AddSubInputView_android_layout_width, 400.0f);
            mViewHeight = (int) a.getDimension(R.styleable.AddSubInputView_android_layout_height, 200.0f);
            mBackgroudDrawable = a.getDrawable(R.styleable.AddSubInputView_backgroud_icon);
            mAddDrawable = a.getDrawable(R.styleable.AddSubInputView_add_icon);
            mSubDrawable = a.getDrawable(R.styleable.AddSubInputView_sub_icon);
            mTextColor = a.getColor(R.styleable.AddSubInputView_android_textColor, Color.GRAY);
            mTextSize = a.getDimensionPixelSize(R.styleable.AddSubInputView_android_textSize, 20);
            mDefaultValue = a.getFloat(R.styleable.AddSubInputView_default_value, 36.2f);
            isLow = a.getBoolean(R.styleable.AddSubInputView_low, true);
            mSubRightEdge = mSubDrawable.getIntrinsicWidth() + 10;
            mAddLeftEdge = (mViewWidth - mAddDrawable.getIntrinsicWidth() - 10);
            mCurrentValue = mDefaultValue;
            a.recycle();
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            super.onDraw(canvas);
    
            Paint paint = new Paint();
            paint.setColor(Color.WHITE);
            canvas.drawRoundRect(0, 0, mViewWidth, mViewHeight, 10.0f, 10.0f, paint);
            int subHeight = mSubDrawable.getIntrinsicHeight();
            int subWidth = mSubDrawable.getIntrinsicWidth();
            canvas.drawBitmap(((BitmapDrawable) mSubDrawable).getBitmap(), 10, (mViewHeight - subHeight) / 2, paint);
    
    
            int addWidth = mAddDrawable.getIntrinsicWidth();
            int addHeight = mAddDrawable.getIntrinsicHeight();
            canvas.drawBitmap(((BitmapDrawable) mAddDrawable).getBitmap(), mViewWidth - addWidth - 10, (mViewHeight - addHeight) / 2, paint);
    
    
            paint.setTextSize(mTextSize);
            paint.setColor(mTextColor);
            float txtwidth = paint.measureText(String.valueOf(mCurrentValue));
    
            int centerWidth = (mViewWidth - addWidth - subWidth - 20);
            int fontStart = (int) (10 + subWidth + (centerWidth / 2) - (txtwidth / 2));
            float baseLineY = mViewHeight / 2 + Math.abs(paint.ascent() + paint.descent()) / 2;
            canvas.drawText(String.valueOf(mCurrentValue), fontStart, baseLineY, paint);
            paint.reset();
        }
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            float posX = event.getX();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    initStatus(posX);
                    break;
                case MotionEvent.ACTION_MOVE:
                    dispathClickEvent(posX);
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    mCurrentStatus = STATUS.CENTER;
                    break;
            }
    
            return true;
        }
    
    
        protected void dispathClickEvent(float rawX) {
            if (getCurrentStatus(rawX) == mCurrentStatus) {
                executors.execute(this);
            }
    
        }
    
    
        private void initStatus(float rawX) {
            mCurrentStatus = getCurrentStatus(rawX);
        }
    
        private STATUS getCurrentStatus(float rawX) {
    //        int centerRightEdge = mViewWidth - mQuartPercent;
            if (rawX < mSubRightEdge) {
                //减法操作
                return STATUS.LEFT;
            } else if (rawX > mAddLeftEdge) {
                //加法操作
                return STATUS.RIGHT;
            } else {
                return STATUS.CENTER;
            }
        }
    
        private void doOperator(boolean sub) {
    
            if (sub) {
                if (mCurrentValue > 36.2f) {
                    mCurrentValue -= 0.1f;
                }
            } else {
                if (mCurrentValue < 37.2f) {
                    mCurrentValue += 0.1f;
                }
            }
            mCurrentValue = (float) (Math.round(mCurrentValue * 10)) / 10;
            postInvalidate();
        }
    
    
        public String getCurrentValue() {
            return String.valueOf(mCurrentValue);
        }
    }
    

    属性文件 attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="AddSubInputView">
            <attr name="background_color" format="color" />
            <attr name="add_icon" format="reference" />
            <attr name="sub_icon" format="reference" />
            <attr name="backgroud_icon" format="reference" />
            <attr name="android:textSize" format="dimension" />
            <attr name="android:layout_width" format="dimension" />
            <attr name="android:layout_height" format="dimension" />
            <attr name="android:textColor" format="color" />
            <attr name="default_value" format="float" />
            <attr name="low" format="boolean"/>
        </declare-styleable>
    
    </resources>
    

    注意点:

    • 自定义控件 attrs.xml 需要了解

    相关文章

      网友评论

          本文标题:含加号减号 控制 数字的自定义控件

          本文链接:https://www.haomeiwen.com/subject/ysvgkhtx.html