自定义时间选择器

自定义时间选择器

文章目录

  • 自定义时间选择器
    • 第一章 效果演示
      • 第01节 效果图
      • 第02节 主要文件
    • 第二章 案例代码
      • 第01节 核心文件 WheelPicker
      • 第02节 实体类 WheelBean
      • 第03节 接口类 IWheelPicker
      • 第04节 原子时间类 DateTimePickerView
      • 第05节 原子时间类 PickerYear
      • 第06节 原子时间类 PickerMonth
      • 第07节 原子时间类 PickerDay
      • 第08节 原子时间类 PickerHour
      • 第09节 原子时间类 PickerMinute
      • 第10节 原子时间类 PickerSecond
      • 第11节 测试Activity
      • 第12节 布局文件
      • 第13节 属性文件




第一章 效果演示

第01节 效果图




第02节 主要文件

1、来自于 Java 的类文件
	A. 核心文件
		src/java/view.wheel.WheelPicker.java
	B. 实体类和接口
		src/java/view.wheel.WheelBean.java
		src/java/view.wheel.IWheelPicker.java
	C. 原子时间类
		src/java/view.wheel.atom.time.DateTimePickerView.java
		src/java/view.wheel.atom.time.PickerDay.java
		src/java/view.wheel.atom.time.PickerHour.java
		src/java/view.wheel.atom.time.PickerMinute.java
		src/java/view.wheel.atom.time.PickerMonth.java
		src/java/view.wheel.atom.time.PickerSecond.java
		src/java/view.wheel.atom.time.PickerYear.java
	D. 测试Activity
		src/java/DemoActivity.java
		
2、来自于资源文件的类
	A. 布局文件
		res/layout/view_picker_time_date.xml
		res/layout/activity_demo.xml
	B. 属性文件
		res/values/attrs.xml




第二章 案例代码

第01节 核心文件 WheelPicker

位置

src/java/view.wheel.WheelPicker.java

代码

package view.wheel;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.Typeface;
import android.os.Build.VERSION;
import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Scroller;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;

public class WheelPicker extends View implements IWheelPicker, Runnable {
    private final Handler mHandler;
    private Paint mPaint;
    private Scroller mScroller;
    private VelocityTracker mTracker;
    private WheelPicker.OnItemSelectedListener mOnItemSelectedListener;
    private WheelPicker.OnWheelChangeListener mOnWheelChangeListener;
    private Rect mRectDrawn;
    private Rect mRectIndicatorHead;
    private Rect mRectIndicatorFoot;
    private Rect mRectCurrentItem;
    private Camera mCamera;
    private Matrix mMatrixRotate;
    private Matrix mMatrixDepth;
    private List<WheelBean> mData;
    private String mMaxWidthText;
    protected String label;
    private int mVisibleItemCount;
    private int mDrawnItemCount;
    private int mHalfDrawnItemCount;
    private int mTextMaxWidth;
    private int mTextMaxHeight;
    private int mItemTextColor;
    private int mSelectedItemTextColor;
    private int mItemTextSize;
    private int mIndicatorSize;
    private int mIndicatorColor;
    private int mCurtainColor;
    private int mItemSpace;
    private int mItemAlign;
    private int mItemHeight;
    private int mHalfItemHeight;
    private int mHalfWheelHeight;
    private int mSelectedItemPosition;
    private int mCurrentItemPosition;
    private int mMinFlingY;
    private int mMaxFlingY;
    private int mMinimumVelocity;
    private int mMaximumVelocity;
    private int mWheelCenterX;
    private int mWheelCenterY;
    private int mDrawnCenterX;
    private int mDrawnCenterY;
    private int mScrollOffsetY;
    private int mTextMaxWidthPosition;
    private int mLastPointY;
    private int mDownPointY;
    private int mTouchSlop;
    private boolean hasSameWidth;
    private boolean hasIndicator;
    private boolean hasCurtain;
    private boolean hasAtmospheric;
    private boolean isCyclic;
    private boolean isCurved;
    private boolean isClick;
    private boolean isForceFinishScroll;
    private int centerRectColor;    // 中间矩形的颜色
    private int centerLineColor;    // 中间线的颜色
    private int centerLineWidth;    // 中间线的粗细
    private boolean centerLineIsShow;  // 中间线是否展示
    private boolean centerRectIsShow;  // 中间线是否展示

    public WheelPicker(Context context) {
        this(context, null);
    }

    public WheelPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mHandler = new Handler();
        this.mMinimumVelocity = 50;
        this.mMaximumVelocity = 8000;
        this.mTouchSlop = 8;
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WheelPicker);
        this.mData = new ArrayList<>();
        this.mItemTextSize = typedArray.getDimensionPixelSize(R.styleable.WheelPicker_wheel_item_text_size, dp2px(context, 18));
        this.mVisibleItemCount = typedArray.getInt(R.styleable.WheelPicker_wheel_visible_item_count, 7);
        this.mSelectedItemPosition = typedArray.getInt(R.styleable.WheelPicker_wheel_selected_item_position, 0);
        this.hasSameWidth = typedArray.getBoolean(R.styleable.WheelPicker_wheel_same_width, false);
        this.mTextMaxWidthPosition = typedArray.getInt(R.styleable.WheelPicker_wheel_maximum_width_text_position, -1);
        this.mMaxWidthText = typedArray.getString(R.styleable.WheelPicker_wheel_maximum_width_text);
        this.label = typedArray.getString(R.styleable.WheelPicker_wheel_label);
        this.mSelectedItemTextColor = typedArray.getColor(R.styleable.WheelPicker_wheel_selected_item_text_color, -1);
        this.mItemTextColor = typedArray.getColor(R.styleable.WheelPicker_wheel_item_text_color, -7829368);
        this.mItemSpace = typedArray.getDimensionPixelSize(R.styleable.WheelPicker_wheel_item_space, dp2px(context, 12));
        this.isCyclic = typedArray.getBoolean(R.styleable.WheelPicker_wheel_cyclic, false);
        this.hasIndicator = typedArray.getBoolean(R.styleable.WheelPicker_wheel_indicator, false);
        this.mIndicatorColor = typedArray.getColor(R.styleable.WheelPicker_wheel_indicator_color, -1166541);
        this.mIndicatorSize = typedArray.getDimensionPixelSize(R.styleable.WheelPicker_wheel_indicator_size, dp2px(context, 2));
        this.hasCurtain = typedArray.getBoolean(R.styleable.WheelPicker_wheel_curtain, false);
        this.mCurtainColor = typedArray.getColor(R.styleable.WheelPicker_wheel_curtain_color, -1996488705);
        this.hasAtmospheric = typedArray.getBoolean(R.styleable.WheelPicker_wheel_atmospheric, false);
        this.isCurved = typedArray.getBoolean(R.styleable.WheelPicker_wheel_curved, false);
        this.mItemAlign = typedArray.getInt(R.styleable.WheelPicker_wheel_item_align, 0);
        typedArray.recycle();
        this.updateVisibleItemCount();
        this.mPaint = new Paint(69);
        this.mPaint.setTextSize((float) this.mItemTextSize);
        this.updateItemTextAlign();
        this.computeTextSize();
        this.mScroller = new Scroller(this.getContext());
        if (VERSION.SDK_INT >= 4) {
            ViewConfiguration conf = ViewConfiguration.get(this.getContext());
            this.mMinimumVelocity = conf.getScaledMinimumFlingVelocity();
            this.mMaximumVelocity = conf.getScaledMaximumFlingVelocity();
            this.mTouchSlop = conf.getScaledTouchSlop();
        }
        if (TextUtils.isEmpty(label)) {
            label = "";
        }

        this.mRectDrawn = new Rect();
        this.mRectIndicatorHead = new Rect();
        this.mRectIndicatorFoot = new Rect();
        this.mRectCurrentItem = new Rect();
        this.mCamera = new Camera();
        this.mMatrixRotate = new Matrix();
        this.mMatrixDepth = new Matrix();
    }

    private void updateVisibleItemCount() {
        if (this.mVisibleItemCount < 2) {
            throw new ArithmeticException("Wheel's visible item count can not be less than 2!");
        } else {
            if (this.mVisibleItemCount % 2 == 0) {
                this.mVisibleItemCount++;
            }
            this.mDrawnItemCount = this.mVisibleItemCount + 2;
            this.mHalfDrawnItemCount = this.mDrawnItemCount / 2;
        }
    }

    private void computeTextSize() {
        this.mTextMaxWidth = this.mTextMaxHeight = 0;
        if (this.hasSameWidth) {
            this.mTextMaxWidth = (int) this.mPaint.measureText(String.valueOf(this.mData.get(0)));
        } else if (this.isPosInRang(this.mTextMaxWidthPosition)) {
            this.mTextMaxWidth = (int) this.mPaint.measureText(String.valueOf(this.mData.get(this.mTextMaxWidthPosition)));
        } else {
            if (!TextUtils.isEmpty(this.mMaxWidthText)) {
                this.mTextMaxWidth = (int) this.mPaint.measureText(this.mMaxWidthText);
            } else {
                for (WheelBean bean : this.mData) {
                    String text = String.valueOf(bean);
                    this.mTextMaxWidth = (int) Math.max(mTextMaxWidth, mPaint.measureText(text));
                }
            }
        }

        Paint.FontMetrics metrics = this.mPaint.getFontMetrics();
        this.mTextMaxHeight = (int) (metrics.bottom - metrics.top);
    }

    private void updateItemTextAlign() {
        switch (this.mItemAlign) {
            case 1:
                this.mPaint.setTextAlign(Align.LEFT);
                break;
            case 2:
                this.mPaint.setTextAlign(Align.RIGHT);
                break;
            default:
                this.mPaint.setTextAlign(Align.CENTER);
        }
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
        int resultWidth = this.mTextMaxWidth;
        int resultHeight = this.mTextMaxHeight * this.mVisibleItemCount + this.mItemSpace * (this.mVisibleItemCount - 1);
        if (this.isCurved) {
            resultHeight = (int) ((double) (2 * resultHeight) / Math.PI);
        }

        resultWidth += this.getPaddingLeft() + this.getPaddingRight();
        resultHeight += this.getPaddingTop() + this.getPaddingBottom();

        resultWidth = this.measureSize(modeWidth, sizeWidth, resultWidth);
        resultHeight = this.measureSize(modeHeight, sizeHeight, resultHeight);
        this.setMeasuredDimension(resultWidth, resultHeight);
    }

    private int measureSize(int mode, int sizeExpect, int sizeActual) {
        int realSize;
        if (mode == 1073741824) {
            realSize = sizeExpect;
        } else {
            realSize = sizeActual;
            if (mode == Integer.MIN_VALUE) {
                realSize = Math.min(sizeActual, sizeExpect);
            }
        }

        return realSize;
    }

    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        this.mRectDrawn.set(this.getPaddingLeft(), this.getPaddingTop(), this.getWidth() - this.getPaddingRight(), this.getHeight() - this.getPaddingBottom());


        this.mWheelCenterX = this.mRectDrawn.centerX();
        this.mWheelCenterY = this.mRectDrawn.centerY();
        this.computeDrawnCenter();
        this.mHalfWheelHeight = this.mRectDrawn.height() / 2;
        this.mItemHeight = this.mRectDrawn.height() / this.mVisibleItemCount;
        this.mHalfItemHeight = this.mItemHeight / 2;
        this.computeFlingLimitY();
        this.computeIndicatorRect();
        this.computeCurrentItemRect();
    }

    private void computeDrawnCenter() {
        switch (this.mItemAlign) {
            case 1:
                this.mDrawnCenterX = this.mRectDrawn.left;
                break;
            case 2:
                this.mDrawnCenterX = this.mRectDrawn.right;
                break;
            default:
                this.mDrawnCenterX = this.mWheelCenterX;
        }

        this.mDrawnCenterY = (int) ((float) this.mWheelCenterY - (this.mPaint.ascent() + this.mPaint.descent()) / 2.0F);
    }

    private void computeFlingLimitY() {
        int currentItemOffset = this.mSelectedItemPosition * this.mItemHeight;
        this.mMinFlingY = this.isCyclic ? Integer.MIN_VALUE : -this.mItemHeight * (this.mData.size() - 1) + currentItemOffset;
        this.mMaxFlingY = this.isCyclic ? Integer.MAX_VALUE : currentItemOffset;
    }

    private void computeIndicatorRect() {
        if (this.hasIndicator) {
            int halfIndicatorSize = this.mIndicatorSize / 2;
            int indicatorHeadCenterY = this.mWheelCenterY + this.mHalfItemHeight;
            int indicatorFootCenterY = this.mWheelCenterY - this.mHalfItemHeight;
            this.mRectIndicatorHead.set(this.mRectDrawn.left, indicatorHeadCenterY - halfIndicatorSize, this.mRectDrawn.right, indicatorHeadCenterY + halfIndicatorSize);
            this.mRectIndicatorFoot.set(this.mRectDrawn.left, indicatorFootCenterY - halfIndicatorSize, this.mRectDrawn.right, indicatorFootCenterY + halfIndicatorSize);
        }
    }

    private void computeCurrentItemRect() {
        if (this.hasCurtain || this.mSelectedItemTextColor != -1) {
            this.mRectCurrentItem.set(this.mRectDrawn.left, this.mWheelCenterY - this.mHalfItemHeight, this.mRectDrawn.right, this.mWheelCenterY + this.mHalfItemHeight);
        }
    }

    protected void onDraw(@NonNull Canvas canvas) {
        if (null != this.mOnWheelChangeListener) {
            this.mOnWheelChangeListener.onWheelScrolled(this.mScrollOffsetY);
        }

        int drawnDataStartPos = -this.mScrollOffsetY / this.mItemHeight - this.mHalfDrawnItemCount;
        int drawnDataPos = drawnDataStartPos + this.mSelectedItemPosition;

        for (int drawnOffsetPos = -this.mHalfDrawnItemCount; drawnDataPos < drawnDataStartPos + this.mSelectedItemPosition + this.mDrawnItemCount; ++drawnOffsetPos) {

            // 绘制中间的矩形
            drawCenterRect(canvas, drawnOffsetPos);

            String data = "";
            int mDrawnItemCenterY;
            if (this.isCyclic) {
                mDrawnItemCenterY = drawnDataPos % this.mData.size();
                mDrawnItemCenterY = mDrawnItemCenterY < 0 ? mDrawnItemCenterY + this.mData.size() : mDrawnItemCenterY;
                data = String.valueOf(this.mData.get(mDrawnItemCenterY));
            } else if (this.isPosInRang(drawnDataPos)) {
                data = String.valueOf(this.mData.get(drawnDataPos));
            }

            this.mPaint.setColor(this.mItemTextColor);
            this.mPaint.setStyle(Style.FILL);
            mDrawnItemCenterY = this.mDrawnCenterY + drawnOffsetPos * this.mItemHeight + this.mScrollOffsetY % this.mItemHeight;
            int distanceToCenter = 0;
            int lineCenterY;
            if (this.isCurved) {
                float ratio = (float) (this.mDrawnCenterY - Math.abs(this.mDrawnCenterY - mDrawnItemCenterY) - this.mRectDrawn.top) * 1.0F / (float) (this.mDrawnCenterY - this.mRectDrawn.top);
                lineCenterY = 0;
                if (mDrawnItemCenterY > this.mDrawnCenterY) {
                    lineCenterY = 1;
                } else if (mDrawnItemCenterY < this.mDrawnCenterY) {
                    lineCenterY = -1;
                }

                float degree = -(1.0F - ratio) * 90.0F * (float) lineCenterY;
                if (degree < -90.0F) {
                    degree = -90.0F;
                }

                if (degree > 90.0F) {
                    degree = 90.0F;
                }

                distanceToCenter = this.computeSpace((int) degree);
                int transX = this.mWheelCenterX;
                switch (this.mItemAlign) {
                    case 1:
                        transX = this.mRectDrawn.left;
                        break;
                    case 2:
                        transX = this.mRectDrawn.right;
                }

                int transY = this.mWheelCenterY - distanceToCenter;
                this.mCamera.save();
                this.mCamera.rotateX(degree);
                this.mCamera.getMatrix(this.mMatrixRotate);
                this.mCamera.restore();
                this.mMatrixRotate.preTranslate((float) (-transX), (float) (-transY));
                this.mMatrixRotate.postTranslate((float) transX, (float) transY);
                this.mCamera.save();
                this.mCamera.translate(0.0F, 0.0F, (float) this.computeDepth((int) degree));
                this.mCamera.getMatrix(this.mMatrixDepth);
                this.mCamera.restore();
                this.mMatrixDepth.preTranslate((float) (-transX), (float) (-transY));
                this.mMatrixDepth.postTranslate((float) transX, (float) transY);
                this.mMatrixRotate.postConcat(this.mMatrixDepth);
            }

            int drawnCenterY;
            if (this.hasAtmospheric) {
                drawnCenterY = (int) ((float) (this.mDrawnCenterY - Math.abs(this.mDrawnCenterY - mDrawnItemCenterY)) * 1.0F / (float) this.mDrawnCenterY * 255.0F);
                drawnCenterY = Math.max(drawnCenterY, 0);
                this.mPaint.setAlpha(drawnCenterY);
            }

            drawnCenterY = this.isCurved ? this.mDrawnCenterY - distanceToCenter : mDrawnItemCenterY;
            if (this.mSelectedItemTextColor != -1) {
                canvas.save();
                if (this.isCurved) {
                    canvas.concat(this.mMatrixRotate);
                }

                canvas.clipRect(this.mRectCurrentItem, Op.DIFFERENCE);
                canvas.drawText(data, (float) this.mDrawnCenterX, (float) drawnCenterY, this.mPaint);
                canvas.restore();
                this.mPaint.setColor(this.mSelectedItemTextColor);
                canvas.save();
                if (this.isCurved) {
                    canvas.concat(this.mMatrixRotate);
                }

                canvas.clipRect(this.mRectCurrentItem);
                canvas.drawText(data, (float) this.mDrawnCenterX, (float) drawnCenterY, this.mPaint);
                canvas.restore();
            } else {
                canvas.save();
                canvas.clipRect(this.mRectDrawn);
                if (this.isCurved) {
                    canvas.concat(this.mMatrixRotate);
                }

                canvas.drawText(data, (float) this.mDrawnCenterX, (float) drawnCenterY, this.mPaint);
                canvas.restore();
            }
            // 绘制中间线
            drawCenterLine(canvas, drawnOffsetPos);
            drawnDataPos++;
        }

        if (this.hasCurtain) {
            this.mPaint.setColor(this.mCurtainColor);
            this.mPaint.setStyle(Style.FILL);
            canvas.drawRect(this.mRectCurrentItem, this.mPaint);
        }

        if (this.hasIndicator) {
            this.mPaint.setColor(this.mIndicatorColor);
            this.mPaint.setStyle(Style.FILL);
            canvas.drawRect(this.mRectIndicatorHead, this.mPaint);
            canvas.drawRect(this.mRectIndicatorFoot, this.mPaint);
        }
    }

    // 绘制中间选择线
    private void drawCenterRect(Canvas canvas, int drawnOffsetPos) {
        if (!centerRectIsShow) {
            return;
        }
        if (drawnOffsetPos == 0) {
            canvas.save();
            canvas.clipRect(this.mRectDrawn);
            this.mPaint.setColor(centerRectColor);
            this.mPaint.setStyle(Style.FILL);

            this.mPaint.setStrokeWidth(centerLineWidth);
            float startY = mWheelCenterY - this.mHalfItemHeight;
            float endY = mWheelCenterY - this.mHalfItemHeight + this.mItemHeight;
            canvas.drawRect((float) this.mRectDrawn.left, startY, (float) this.mRectDrawn.right, endY, this.mPaint);
            canvas.restore();
        }
    }


    // 绘制中间选择线
    private void drawCenterLine(Canvas canvas, int drawnOffsetPos) {
        if (!centerLineIsShow) {
            return;
        }
        if (drawnOffsetPos == 0) {
            canvas.save();
            canvas.clipRect(this.mRectDrawn);
            this.mPaint.setColor(centerLineColor);
            this.mPaint.setStyle(Style.STROKE);
            this.mPaint.setStrokeWidth(centerLineWidth);
            float startY = mWheelCenterY - this.mHalfItemHeight;
            float endY = mWheelCenterY - this.mHalfItemHeight + this.mItemHeight;
            canvas.drawLine((float) this.mRectDrawn.left, startY, (float) this.mRectDrawn.right, startY, this.mPaint);
            canvas.drawLine((float) this.mRectDrawn.left, endY, (float) this.mRectDrawn.right, endY, this.mPaint);
            canvas.restore();
        }
    }

    private boolean isPosInRang(int position) {
        return position >= 0 && position < this.mData.size();
    }

    private int computeSpace(int degree) {
        return (int) (Math.sin(Math.toRadians(degree)) * (double) this.mHalfWheelHeight);
    }

    private int computeDepth(int degree) {
        return (int) ((double) this.mHalfWheelHeight - Math.cos(Math.toRadians((double) degree)) * (double) this.mHalfWheelHeight);
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (null != this.getParent()) {
                    this.getParent().requestDisallowInterceptTouchEvent(true);
                }

                if (null == this.mTracker) {
                    this.mTracker = VelocityTracker.obtain();
                } else {
                    this.mTracker.clear();
                }

                this.mTracker.addMovement(event);
                if (!this.mScroller.isFinished()) {
                    this.mScroller.abortAnimation();
                    this.isForceFinishScroll = true;
                }

                this.mDownPointY = this.mLastPointY = (int) event.getY();
                break;
            case MotionEvent.ACTION_UP:
                if (null != this.getParent()) {
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                }

                if (!this.isClick) {
                    this.mTracker.addMovement(event);
                    if (VERSION.SDK_INT >= 4) {
                        this.mTracker.computeCurrentVelocity(1000, (float) this.mMaximumVelocity);
                    } else {
                        this.mTracker.computeCurrentVelocity(1000);
                    }

                    this.isForceFinishScroll = false;
                    int velocity = (int) this.mTracker.getYVelocity();
                    if (Math.abs(velocity) > this.mMinimumVelocity) {
                        this.mScroller.fling(0, this.mScrollOffsetY, 0, velocity, 0, 0, this.mMinFlingY, this.mMaxFlingY);
                        this.mScroller.setFinalY(this.mScroller.getFinalY() + this.computeDistanceToEndPoint(this.mScroller.getFinalY() % this.mItemHeight));
                    } else {
                        this.mScroller.startScroll(0, this.mScrollOffsetY, 0, this.computeDistanceToEndPoint(this.mScrollOffsetY % this.mItemHeight));
                    }

                    if (!this.isCyclic) {
                        if (this.mScroller.getFinalY() > this.mMaxFlingY) {
                            this.mScroller.setFinalY(this.mMaxFlingY);
                        } else if (this.mScroller.getFinalY() < this.mMinFlingY) {
                            this.mScroller.setFinalY(this.mMinFlingY);
                        }
                    }

                    this.mHandler.post(this);
                    if (null != this.mTracker) {
                        this.mTracker.recycle();
                        this.mTracker = null;
                    }
                }
                // 这里是否需要移动一段距离, 距离修正
                float moveFixUp = event.getY() - (float) this.mLastPointY;
                if (!(Math.abs(moveFixUp) < 1.0F)) {
                    this.mScrollOffsetY = (int) ((float) this.mScrollOffsetY + moveFixUp);
                    this.mLastPointY = (int) event.getY();
                    this.invalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (Math.abs((float) this.mDownPointY - event.getY()) < (float) this.mTouchSlop) {
                    this.isClick = true;
                } else {
                    this.isClick = false;
                    this.mTracker.addMovement(event);
                    if (null != this.mOnWheelChangeListener) {
                        this.mOnWheelChangeListener.onWheelScrollStateChanged(1);
                    }

                    // 这里是否需要移动一段距离, 距离修正
                    float moveFixMove = event.getY() - (float) this.mLastPointY;
                    if (!(Math.abs(moveFixMove) < 1.0F)) {
                        this.mScrollOffsetY = (int) ((float) this.mScrollOffsetY + moveFixMove);
                        this.mLastPointY = (int) event.getY();
                        this.invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                if (null != this.getParent()) {
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                }

                if (null != this.mTracker) {
                    this.mTracker.recycle();
                    this.mTracker = null;
                }
        }

        return true;
    }

    public void setCenterLineColor(int centerLineColor) {
        this.centerLineColor = centerLineColor;
    }

    public void setCenterRectColor(int centerRectColor) {
        this.centerRectColor = centerRectColor;
    }

    public void setCenterLineWidth(int centerLineWidth) {
        this.centerLineWidth = centerLineWidth;
    }

    public void setCenterLineIsShow(boolean centerLineIsShow) {
        this.centerLineIsShow = centerLineIsShow;
    }

    public void setCenterRectIsShow(boolean centerRectIsShow) {
        this.centerRectIsShow = centerRectIsShow;
    }

    private int computeDistanceToEndPoint(int remainder) {
        if (Math.abs(remainder) > this.mHalfItemHeight) {
            return this.mScrollOffsetY < 0 ? -this.mItemHeight - remainder : this.mItemHeight - remainder;
        } else {
            return -remainder;
        }
    }

    public void run() {
        if (null != this.mData && this.mData.size() != 0) {
            if (this.mScroller.isFinished() && !this.isForceFinishScroll) {
                if (this.mItemHeight == 0) {
                    return;
                }

                int position = (-this.mScrollOffsetY / this.mItemHeight + this.mSelectedItemPosition) % this.mData.size();
                position = position < 0 ? position + this.mData.size() : position;


                this.mCurrentItemPosition = position;
                if (null != this.mOnItemSelectedListener) {
                    this.mOnItemSelectedListener.onItemSelected(this, this.mData.get(position), position);
                }

                if (null != this.mOnWheelChangeListener) {
                    this.mOnWheelChangeListener.onWheelSelected(position);
                    this.mOnWheelChangeListener.onWheelScrollStateChanged(0);
                }
            }

            if (this.mScroller.computeScrollOffset()) {
                if (null != this.mOnWheelChangeListener) {
                    this.mOnWheelChangeListener.onWheelScrollStateChanged(2);
                }

                this.mScrollOffsetY = this.mScroller.getCurrY();
                this.postInvalidate();
                this.mHandler.postDelayed(this, 16L);
            }

        }
    }

    // dp转px
    private int dp2px(Context context, float value) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (value * scale + 0.5f);
    }

    public int getVisibleItemCount() {
        return this.mVisibleItemCount;
    }

    public void setVisibleItemCount(int count) {
        this.mVisibleItemCount = count;
        this.updateVisibleItemCount();
        this.requestLayout();
    }

    public boolean isCyclic() {
        return this.isCyclic;
    }

    public void setCyclic(boolean isCyclic) {
        this.isCyclic = isCyclic;
        this.computeFlingLimitY();
        this.invalidate();
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public void setOnItemSelectedListener(WheelPicker.OnItemSelectedListener listener) {
        this.mOnItemSelectedListener = listener;
    }

    public int getSelectedItemPosition() {
        return this.mSelectedItemPosition;
    }

    public void setSelectedItemPosition(int position) {
        position = Math.min(position, this.mData.size() - 1);
        position = Math.max(position, 0);
        this.mSelectedItemPosition = position;
        this.mCurrentItemPosition = position;
        this.mScrollOffsetY = 0;
        this.computeFlingLimitY();
        this.requestLayout();
        this.invalidate();
    }

    public int getCurrentItemPosition() {
        return this.mCurrentItemPosition;
    }

    public List<WheelBean> getData() {
        return this.mData;
    }

    public void setData(List<WheelBean> data) {
        if (null == data) {
            throw new NullPointerException("WheelPicker's data can not be null!");
        } else {
            this.mData = data;
            if (this.mSelectedItemPosition <= data.size() - 1 && this.mCurrentItemPosition <= data.size() - 1) {
                this.mSelectedItemPosition = this.mCurrentItemPosition;
            } else {
                this.mSelectedItemPosition = this.mCurrentItemPosition = data.size() - 1;
            }

            this.mScrollOffsetY = 0;
            this.computeTextSize();
            this.computeFlingLimitY();
            this.requestLayout();
            this.invalidate();
        }
    }

    public void setSameWidth(boolean hasSameWidth) {
        this.hasSameWidth = hasSameWidth;
        this.computeTextSize();
        this.requestLayout();
        this.invalidate();
    }

    public boolean hasSameWidth() {
        return this.hasSameWidth;
    }

    public void setOnWheelChangeListener(WheelPicker.OnWheelChangeListener listener) {
        this.mOnWheelChangeListener = listener;
    }

    public String getMaximumWidthText() {
        return this.mMaxWidthText;
    }

    public void setMaximumWidthText(String text) {
        if (null == text) {
            throw new NullPointerException("Maximum width text can not be null!");
        } else {
            this.mMaxWidthText = text;
            this.computeTextSize();
            this.requestLayout();
            this.invalidate();
        }
    }

    public int getMaximumWidthTextPosition() {
        return this.mTextMaxWidthPosition;
    }

    public void setMaximumWidthTextPosition(int position) {
        if (!this.isPosInRang(position)) {
            throw new ArrayIndexOutOfBoundsException("Maximum width text Position must in [0, " + this.mData.size() + "), but current is " + position);
        } else {
            this.mTextMaxWidthPosition = position;
            this.computeTextSize();
            this.requestLayout();
            this.invalidate();
        }
    }

    public int getSelectedItemTextColor() {
        return this.mSelectedItemTextColor;
    }

    public void setSelectedItemTextColor(int color) {
        this.mSelectedItemTextColor = color;
        this.computeCurrentItemRect();
        this.invalidate();
    }

    public int getItemTextColor() {
        return this.mItemTextColor;
    }

    public void setItemTextColor(int color) {
        this.mItemTextColor = color;
        this.invalidate();
    }

    public int getItemTextSize() {
        return this.mItemTextSize;
    }

    public void setItemTextSize(int size) {
        this.mItemTextSize = size;
        this.mPaint.setTextSize((float) this.mItemTextSize);
        this.computeTextSize();
        this.requestLayout();
        this.invalidate();
    }

    public int getItemSpace() {
        return this.mItemSpace;
    }

    public void setItemSpace(int space) {
        this.mItemSpace = space;
        this.requestLayout();
        this.invalidate();
    }

    public void setIndicator(boolean hasIndicator) {
        this.hasIndicator = hasIndicator;
        this.computeIndicatorRect();
        this.invalidate();
    }

    public boolean hasIndicator() {
        return this.hasIndicator;
    }

    public int getIndicatorSize() {
        return this.mIndicatorSize;
    }

    public void setIndicatorSize(int size) {
        this.mIndicatorSize = size;
        this.computeIndicatorRect();
        this.invalidate();
    }

    public int getIndicatorColor() {
        return this.mIndicatorColor;
    }

    public void setIndicatorColor(int color) {
        this.mIndicatorColor = color;
        this.invalidate();
    }

    public void setCurtain(boolean hasCurtain) {
        this.hasCurtain = hasCurtain;
        this.computeCurrentItemRect();
        this.invalidate();
    }

    public boolean hasCurtain() {
        return this.hasCurtain;
    }

    public int getCurtainColor() {
        return this.mCurtainColor;
    }

    public void setCurtainColor(int color) {
        this.mCurtainColor = color;
        this.invalidate();
    }

    public void setAtmospheric(boolean hasAtmospheric) {
        this.hasAtmospheric = hasAtmospheric;
        this.invalidate();
    }

    public boolean hasAtmospheric() {
        return this.hasAtmospheric;
    }

    public boolean isCurved() {
        return this.isCurved;
    }

    public void setCurved(boolean isCurved) {
        this.isCurved = isCurved;
        this.requestLayout();
        this.invalidate();
    }

    public int getItemAlign() {
        return this.mItemAlign;
    }

    public void setItemAlign(int align) {
        this.mItemAlign = align;
        this.updateItemTextAlign();
        this.computeDrawnCenter();
        this.invalidate();
    }

    public Typeface getTypeface() {
        return null != this.mPaint ? this.mPaint.getTypeface() : null;
    }

    public void setTypeface(Typeface tf) {
        if (null != this.mPaint) {
            this.mPaint.setTypeface(tf);
        }

        this.computeTextSize();
        this.requestLayout();
        this.invalidate();
    }

    public interface OnWheelChangeListener {
        void onWheelScrolled(int var1);

        void onWheelSelected(int var1);

        void onWheelScrollStateChanged(int var1);
    }

    public interface OnItemSelectedListener {
        void onItemSelected(WheelPicker wheelPicker, WheelBean wheelBean, int position);
    }
}








第02节 实体类 WheelBean

位置

src/java/view.wheel.WheelBean.java

代码

package view.wheel;

import androidx.annotation.NonNull;

public class WheelBean {

    private int itemNumber;
    private String itemLabel;

    public WheelBean() {
    }

    public WheelBean(int itemNumber, String itemLabel) {
        this.itemNumber = itemNumber;
        this.itemLabel = itemLabel;
    }

    public int getItemNumber() {
        return itemNumber;
    }

    public void setItemNumber(int itemNumber) {
        this.itemNumber = itemNumber;
    }

    public String getItemLabel() {
        return itemLabel;
    }

    public void setItemLabel(String itemLabel) {
        this.itemLabel = itemLabel;
    }

    @NonNull
    @Override
    public String toString() {
        return itemNumber + itemLabel;
    }
}








第03节 接口类 IWheelPicker

位置

src/java/view.wheel.IWheelPicker.java

代码

package view.wheel;

import android.graphics.Typeface;

import java.util.List;

public interface IWheelPicker {
    int getVisibleItemCount();

    void setVisibleItemCount(int var1);

    boolean isCyclic();

    void setCyclic(boolean var1);

    void setOnItemSelectedListener(WheelPicker.OnItemSelectedListener var1);

    void setSelectedItemPosition(int var1);

    int getCurrentItemPosition();

    List<WheelBean> getData();

    void setData(List<WheelBean> var1);

    void setMaximumWidthText(String var1);

    int getSelectedItemTextColor();

    void setSelectedItemTextColor(int var1);

    int getItemTextColor();

    void setItemTextColor(int var1);

    int getItemTextSize();

    void setItemTextSize(int var1);

    int getItemSpace();

    void setItemSpace(int var1);

    void setIndicator(boolean var1);

    boolean hasIndicator();

    int getIndicatorSize();

    void setIndicatorSize(int var1);

    void setIndicatorColor(int var1);

    void setCurtain(boolean var1);

    boolean hasCurtain();

    int getCurtainColor();

    void setCurtainColor(int var1);

    void setAtmospheric(boolean var1);

    boolean hasAtmospheric();

    boolean isCurved();

    void setCurved(boolean var1);

    int getItemAlign();

    void setItemAlign(int var1);

    Typeface getTypeface();

    void setTypeface(Typeface var1);
}








第04节 原子时间类 DateTimePickerView

位置

src/java/view.wheel.atom.time.DateTimePickerView.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class DateTimePickerView extends LinearLayout implements WheelPicker.OnItemSelectedListener {
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.getDefault());
    private PickerYear mPickerYear;
    private PickerMonth mPickerMonth;
    private PickerDay mPickerDay;
    private PickerHour mPickerHour;
    private PickerMinute mPickerMinute;
    private PickerSecond mPickerSecond;


    private DateTimePickerView.OnDateSelectedListener onDateSelectedListener;

    private int mYear;
    private int mMonth;
    private int mDay;
    private int mHour;
    private int mMinute;
    private int mSecond;

    public void setOnDateSelectedListener(OnDateSelectedListener onDateSelectedListener) {
        this.onDateSelectedListener = onDateSelectedListener;
    }

    public DateTimePickerView(Context context) {
        this(context, null);
    }

    public DateTimePickerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.view_picker_time_date, this);
        this.mPickerYear = findViewById(R.id.picker_year);
        this.mPickerMonth = findViewById(R.id.picker_month);
        this.mPickerDay = findViewById(R.id.picker_day);
        this.mPickerHour = findViewById(R.id.picker_hour);
        this.mPickerMinute = findViewById(R.id.picker_minute);
        this.mPickerSecond = findViewById(R.id.picker_second);


        this.setMaximumWidthTextYear();
        this.mPickerMonth.setMaximumWidthText("00");
        this.mPickerDay.setMaximumWidthText("00");
        this.mPickerHour.setMaximumWidthText("00");
        this.mPickerMinute.setMaximumWidthText("00");
        this.mPickerSecond.setMaximumWidthText("00");


        this.mYear = this.mPickerYear.getCurrentYear();
        this.mMonth = this.mPickerMonth.getCurrentMonth();
        this.mDay = this.mPickerDay.getCurrentDay();
        this.mHour = this.mPickerHour.getCurrentHour();
        this.mMinute = this.mPickerMinute.getCurrentMinute();
        this.mSecond = this.mPickerSecond.getCurrentSecond();

        this.mPickerYear.setOnItemSelectedListener(this);
        this.mPickerMonth.setOnItemSelectedListener(this);
        this.mPickerDay.setOnItemSelectedListener(this);
        this.mPickerHour.setOnItemSelectedListener(this);
        this.mPickerMinute.setOnItemSelectedListener(this);
        this.mPickerSecond.setOnItemSelectedListener(this);
    }

    private void setMaximumWidthTextYear() {
        List<WheelBean> years = this.mPickerYear.getData();
        String lastYear = String.valueOf(years.get(years.size() - 1));
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < lastYear.length(); ++i) {
            sb.append("0");
        }

        this.mPickerYear.setMaximumWidthText(sb.toString());
    }

    @Override
    public void onItemSelected(WheelPicker picker, WheelBean wheelBean, int position) {
        if (picker.getId() == R.id.picker_year) {
            this.mYear = this.mPickerYear.getCurrentYear();
            this.mPickerDay.setYear(this.mYear);
        } else if (picker.getId() == R.id.picker_month) {
            this.mMonth = this.mPickerMonth.getCurrentMonth();
            this.mPickerDay.setMonth(this.mMonth);
        } else if (picker.getId() == R.id.picker_day) {
            this.mDay = this.mPickerDay.getCurrentDay();
        } else if (picker.getId() == R.id.picker_hour) {
            this.mHour = this.mPickerHour.getCurrentHour();
        } else if (picker.getId() == R.id.picker_minute) {
            this.mMinute = this.mPickerMinute.getCurrentMinute();
        } else if (picker.getId() == R.id.picker_second) {
            this.mSecond = this.mPickerSecond.getCurrentSecond();
        }

        String dateTime = this.mYear + "年" + this.mMonth + "月" + this.mDay + "日 " + this.mHour + ":" + this.mMinute + ":" + this.mSecond;

        if (onDateSelectedListener != null) {
            try {
                onDateSelectedListener.onDateSelected(this, SDF.parse(dateTime), dateTime);
            } catch (ParseException parseException) {
                parseException.printStackTrace();
            }
        }
    }

    // 设置显示的类型
    public void setShowType(boolean[] array) {
        if (array == null || array.length != 6) {
            throw new IllegalArgumentException("数组的长度必须为6");
        }
        this.mPickerYear.setVisibility(array[0] ? View.VISIBLE : View.GONE);
        this.mPickerMonth.setVisibility(array[1] ? View.VISIBLE : View.GONE);
        this.mPickerDay.setVisibility(array[2] ? View.VISIBLE : View.GONE);
        this.mPickerHour.setVisibility(array[3] ? View.VISIBLE : View.GONE);
        this.mPickerMinute.setVisibility(array[4] ? View.VISIBLE : View.GONE);
        this.mPickerSecond.setVisibility(array[5] ? View.VISIBLE : View.GONE);

    }

    public void setVisibleItemCount(int count) {
        this.mPickerYear.setVisibleItemCount(count);
        this.mPickerMonth.setVisibleItemCount(count);
        this.mPickerDay.setVisibleItemCount(count);
        this.mPickerHour.setVisibleItemCount(count);
        this.mPickerMinute.setVisibleItemCount(count);
        this.mPickerSecond.setVisibleItemCount(count);
    }

    public boolean isCyclic() {
        boolean cyclicYear = this.mPickerYear.isCyclic();
        boolean cyclicMonth = this.mPickerMonth.isCyclic();
        boolean cyclicDay = this.mPickerDay.isCyclic();
        boolean cyclicHour = this.mPickerHour.isCyclic();
        boolean cyclicMinute = this.mPickerMinute.isCyclic();
        boolean cyclicSecond = this.mPickerSecond.isCyclic();
        boolean result = cyclicYear && cyclicMonth && cyclicDay && cyclicHour && cyclicMinute && cyclicSecond;
        return result;
    }

    public void setCenterLineColor(int centerLineColor) {
        this.mPickerYear.setCenterLineColor(centerLineColor);
        this.mPickerMonth.setCenterLineColor(centerLineColor);
        this.mPickerDay.setCenterLineColor(centerLineColor);
        this.mPickerHour.setCenterLineColor(centerLineColor);
        this.mPickerMinute.setCenterLineColor(centerLineColor);
        this.mPickerSecond.setCenterLineColor(centerLineColor);
    }

    // 这里需要设置透明度, 才能有效果。不能用全色, 否则UI效果异常
    public void setCenterRectColor(int centerRectColor) {
        this.mPickerYear.setCenterRectColor(centerRectColor);
        this.mPickerMonth.setCenterRectColor(centerRectColor);
        this.mPickerDay.setCenterRectColor(centerRectColor);
        this.mPickerHour.setCenterRectColor(centerRectColor);
        this.mPickerMinute.setCenterRectColor(centerRectColor);
        this.mPickerSecond.setCenterRectColor(centerRectColor);
    }

    public void setCenterRectIsShow(boolean centerRectIsShow) {
        this.mPickerYear.setCenterRectIsShow(centerRectIsShow);
        this.mPickerMonth.setCenterRectIsShow(centerRectIsShow);
        this.mPickerDay.setCenterRectIsShow(centerRectIsShow);
        this.mPickerHour.setCenterRectIsShow(centerRectIsShow);
        this.mPickerMinute.setCenterRectIsShow(centerRectIsShow);
        this.mPickerSecond.setCenterRectIsShow(centerRectIsShow);
    }


    public void setCenterLineWidth(int centerLineWidth) {
        this.mPickerYear.setCenterLineWidth(centerLineWidth);
        this.mPickerMonth.setCenterLineWidth(centerLineWidth);
        this.mPickerDay.setCenterLineWidth(centerLineWidth);
        this.mPickerHour.setCenterLineWidth(centerLineWidth);
        this.mPickerMinute.setCenterLineWidth(centerLineWidth);
        this.mPickerSecond.setCenterLineWidth(centerLineWidth);
    }

    public void setCenterLineIsShow(boolean centerLineIsShow) {
        this.mPickerYear.setCenterLineIsShow(centerLineIsShow);
        this.mPickerMonth.setCenterLineIsShow(centerLineIsShow);
        this.mPickerDay.setCenterLineIsShow(centerLineIsShow);
        this.mPickerHour.setCenterLineIsShow(centerLineIsShow);
        this.mPickerMinute.setCenterLineIsShow(centerLineIsShow);
        this.mPickerSecond.setCenterLineIsShow(centerLineIsShow);
    }

    public void setCyclic(boolean isCyclic) {
        this.mPickerYear.setCyclic(isCyclic);
        this.mPickerMonth.setCyclic(isCyclic);
        this.mPickerDay.setCyclic(isCyclic);
        this.mPickerHour.setCyclic(isCyclic);
        this.mPickerMinute.setCyclic(isCyclic);
        this.mPickerSecond.setCyclic(isCyclic);
    }

    public void setItemTextColorSelected(int color) {
        this.mPickerYear.setSelectedItemTextColor(color);
        this.mPickerMonth.setSelectedItemTextColor(color);
        this.mPickerDay.setSelectedItemTextColor(color);
        this.mPickerHour.setSelectedItemTextColor(color);
        this.mPickerMinute.setSelectedItemTextColor(color);
        this.mPickerSecond.setSelectedItemTextColor(color);
    }


    public void setItemTextColorUnSelect(int color) {
        this.mPickerYear.setItemTextColor(color);
        this.mPickerMonth.setItemTextColor(color);
        this.mPickerDay.setItemTextColor(color);
        this.mPickerHour.setItemTextColor(color);
        this.mPickerMinute.setItemTextColor(color);
        this.mPickerSecond.setItemTextColor(color);
    }

    public void setItemTextSize(int size) {
        this.mPickerYear.setItemTextSize(size);
        this.mPickerMonth.setItemTextSize(size);
        this.mPickerDay.setItemTextSize(size);
        this.mPickerHour.setItemTextSize(size);
        this.mPickerMinute.setItemTextSize(size);
        this.mPickerSecond.setItemTextSize(size);
    }

    public void setItemSpace(int space) {
        this.mPickerYear.setItemSpace(space);
        this.mPickerMonth.setItemSpace(space);
        this.mPickerDay.setItemSpace(space);
        this.mPickerHour.setItemSpace(space);
        this.mPickerMinute.setItemSpace(space);
        this.mPickerSecond.setItemSpace(space);
    }

    public void setIndicator(boolean hasIndicator) {
        this.mPickerYear.setIndicator(hasIndicator);
        this.mPickerMonth.setIndicator(hasIndicator);
        this.mPickerDay.setIndicator(hasIndicator);
        this.mPickerHour.setIndicator(hasIndicator);
        this.mPickerMinute.setIndicator(hasIndicator);
        this.mPickerSecond.setIndicator(hasIndicator);
    }

    public boolean hasIndicator() {
        boolean indicatorYear = this.mPickerYear.hasIndicator();
        boolean indicatorMonth = this.mPickerMonth.hasIndicator();
        boolean indicatorDay = this.mPickerDay.hasIndicator();
        boolean indicatorHour = this.mPickerHour.hasIndicator();
        boolean indicatorMinute = this.mPickerMinute.hasIndicator();
        boolean indicatorSecond = this.mPickerSecond.hasIndicator();
        boolean result = indicatorYear && indicatorMonth && indicatorDay && indicatorHour && indicatorMinute && indicatorSecond;
        return result;
    }

    public void setIndicatorSize(int size) {
        this.mPickerYear.setIndicatorSize(size);
        this.mPickerMonth.setIndicatorSize(size);
        this.mPickerDay.setIndicatorSize(size);
        this.mPickerHour.setIndicatorSize(size);
        this.mPickerMinute.setIndicatorSize(size);
        this.mPickerSecond.setIndicatorSize(size);
    }

    public void setIndicatorColor(int color) {
        this.mPickerYear.setIndicatorColor(color);
        this.mPickerMonth.setIndicatorColor(color);
        this.mPickerDay.setIndicatorColor(color);
        this.mPickerHour.setIndicatorColor(color);
        this.mPickerMinute.setIndicatorColor(color);
        this.mPickerSecond.setIndicatorColor(color);
    }

    public void setCurtain(boolean hasCurtain) {
        this.mPickerYear.setCurtain(hasCurtain);
        this.mPickerMonth.setCurtain(hasCurtain);
        this.mPickerDay.setCurtain(hasCurtain);
        this.mPickerHour.setCurtain(hasCurtain);
        this.mPickerMinute.setCurtain(hasCurtain);
        this.mPickerSecond.setCurtain(hasCurtain);
    }

    public boolean isCurtain() {
        boolean curtainYear = this.mPickerYear.hasCurtain();
        boolean curtainMonth = this.mPickerMonth.hasCurtain();
        boolean curtainDay = this.mPickerDay.hasCurtain();
        boolean curtainHour = this.mPickerHour.hasCurtain();
        boolean curtainMinute = this.mPickerMinute.hasCurtain();
        boolean curtainSecond = this.mPickerSecond.hasCurtain();
        boolean result = curtainYear && curtainMonth && curtainDay && curtainHour && curtainMinute && curtainSecond;
        return result;
    }

    public void setCurtainColor(int color) {
        this.mPickerYear.setCurtainColor(color);
        this.mPickerMonth.setCurtainColor(color);
        this.mPickerDay.setCurtainColor(color);
        this.mPickerHour.setCurtainColor(color);
        this.mPickerMinute.setCurtainColor(color);
        this.mPickerSecond.setCurtainColor(color);
    }

    public void setAtmospheric(boolean hasAtmospheric) {
        this.mPickerYear.setAtmospheric(hasAtmospheric);
        this.mPickerMonth.setAtmospheric(hasAtmospheric);
        this.mPickerDay.setAtmospheric(hasAtmospheric);
        this.mPickerHour.setAtmospheric(hasAtmospheric);
        this.mPickerMinute.setAtmospheric(hasAtmospheric);
        this.mPickerSecond.setAtmospheric(hasAtmospheric);
    }

    public boolean hasAtmospheric() {
        boolean hasAtmosphericYear = this.mPickerYear.hasAtmospheric();
        boolean hasAtmosphericMonth = this.mPickerMonth.hasAtmospheric();
        boolean hasAtmosphericDay = this.mPickerDay.hasAtmospheric();
        boolean hasAtmosphericHour = this.mPickerHour.hasAtmospheric();
        boolean hasAtmosphericMinute = this.mPickerMinute.hasAtmospheric();
        boolean hasAtmosphericSecond = this.mPickerSecond.hasAtmospheric();
        boolean result = hasAtmosphericYear && hasAtmosphericMonth && hasAtmosphericDay && hasAtmosphericHour && hasAtmosphericMinute && hasAtmosphericSecond;
        return result;
    }

    // 判断是否存在弧度
    public boolean isCurved() {
        boolean curvedYear = this.mPickerYear.isCurved();
        boolean curvedMonth = this.mPickerMonth.isCurved();
        boolean curvedDay = this.mPickerDay.isCurved();
        boolean curvedHour = this.mPickerHour.isCurved();
        boolean curvedMinute = this.mPickerMinute.isCurved();
        boolean curvedSecond = this.mPickerSecond.isCurved();
        boolean result = curvedYear && curvedMonth && curvedDay && curvedHour && curvedMinute && curvedSecond;
        return result;
    }

    // 设置是否存在弧度
    public void setCurved(boolean isCurved) {
        this.mPickerYear.setCurved(isCurved);
        this.mPickerMonth.setCurved(isCurved);
        this.mPickerDay.setCurved(isCurved);
        this.mPickerHour.setCurved(isCurved);
        this.mPickerMinute.setCurved(isCurved);
        this.mPickerSecond.setCurved(isCurved);
    }

    // 设置字体样式
    public void setTypeface(Typeface typeface) {
        this.mPickerYear.setTypeface(typeface);
        this.mPickerMonth.setTypeface(typeface);
        this.mPickerDay.setTypeface(typeface);
        this.mPickerHour.setTypeface(typeface);
        this.mPickerMinute.setTypeface(typeface);
        this.mPickerSecond.setTypeface(typeface);
    }

    public interface OnDateSelectedListener {
        void onDateSelected(DateTimePickerView view, Date date, String format);
    }
}








第05节 原子时间类 PickerYear

位置

src/java/view.wheel.atom.time.PickerYear.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

// 选择器(年份)
public class PickerYear extends WheelPicker {
    private int mYearStart;
    private int mYearEnd;
    private int mSelectedYear;

    public PickerYear(Context context) {
        this(context, null);
    }

    public PickerYear(Context context, AttributeSet attrs) {
        super(context, attrs);
        mYearStart = 1000;
        mYearEnd = 3000;
        updateYears();
        mSelectedYear = Calendar.getInstance().get(Calendar.YEAR);
        setSelectedItemPosition(mSelectedYear - this.mYearStart);
    }

    private void updateYears() {
        List<WheelBean> data = new ArrayList<>();
        for (int i = this.mYearStart; i <= this.mYearEnd; ++i) {
            WheelBean item = new WheelBean(i, label);
            data.add(item);
        }
        super.setData(data);
    }

    public int getYearStart() {
        return this.mYearStart;
    }

    public void setYearStart(int start) {
        this.mYearStart = start;
        this.mSelectedYear = this.getCurrentYear();
        this.updateYears();
        this.setSelectedItemPosition(this.mSelectedYear - this.mYearStart);
    }

    public int getCurrentYear() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }
}








第06节 原子时间类 PickerMonth

位置

src/java/view.wheel.atom.time.PickerMonth.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

// 选择器(月份)
public class PickerMonth extends WheelPicker {

    private int mSelectedMonth;

    public PickerMonth(Context context) {
        this(context, null);
    }

    public PickerMonth(Context context, AttributeSet attrs) {
        super(context, attrs);
        List<WheelBean> data = new ArrayList<>();

        for (int i = 1; i <= 12; i++) {
            WheelBean item = new WheelBean(i, label);
            data.add(item);
        }
        super.setData(data);
        int mSelectedMonth = Calendar.getInstance().get(Calendar.MONTH) + 1;
        setSelectedItemPosition(mSelectedMonth - 1);
    }

    public void setSelectedMonth(int month) {
        this.mSelectedMonth = month;
        this.setSelectedItemPosition(this.mSelectedMonth - 1);
    }

    public int getCurrentMonth() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }
}








第07节 原子时间类 PickerDay

位置

src/java/view.wheel.atom.time.PickerDay.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 选择器(日期)
public class PickerDay extends WheelPicker {
    private static final Map<Integer, List<WheelBean>> mapData = new HashMap<>();
    private Calendar mCalendar;
    private int mYear;
    private int mMonth;
    private int mSelectedDay;

    public PickerDay(Context context) {
        this(context, null);
    }

    public PickerDay(Context context, AttributeSet attrs) {
        super(context, attrs);
        mCalendar = Calendar.getInstance();
        mYear = mCalendar.get(Calendar.YEAR);
        mMonth = mCalendar.get(Calendar.MONTH);
        updateMapData();
        mSelectedDay = this.mCalendar.get(Calendar.DAY_OF_MONTH);
        updateSelectedDay();
    }

    private void updateMapData() {
        this.mCalendar.set(Calendar.YEAR, this.mYear);
        this.mCalendar.set(Calendar.MONTH, this.mMonth);
        int mDate = this.mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        List<WheelBean> dateList = mapData.get(mDate);
        if (null == dateList) {
            dateList = new ArrayList<>();
            for (int i = 1; i <= mDate; i++) {
                WheelBean item = new WheelBean(i, label);
                dateList.add(item);
            }
            mapData.put(mDate, dateList);
        }
        super.setData(dateList);
    }

    private void updateSelectedDay() {
        this.setSelectedItemPosition(this.mSelectedDay - 1);
    }

    public int getCurrentDay() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }

    private void updateDays() {
        this.mCalendar.set(Calendar.YEAR, this.mYear);
        this.mCalendar.set(Calendar.MONTH, this.mMonth);
        int days = this.mCalendar.getActualMaximum(5);
        List<WheelBean> data = mapData.get(days);
        if (null == data) {
            data = new ArrayList<>();
            for (int i = 1; i <= days; ++i) {
                WheelBean item = new WheelBean(i, label);
                data.add(item);
            }
            mapData.put(days, data);
        }
        super.setData(data);
    }

    public void setYear(int year) {
        this.mYear = year;
        this.updateDays();
    }

    public void setMonth(int month) {
        this.mMonth = month - 1;
        this.updateDays();
    }
}








第08节 原子时间类 PickerHour

位置

src/java/view.wheel.atom.time.PickerHour.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

// 选择器(小时)
public class PickerHour extends WheelPicker {
    private int mHourStart;
    private int mHourEnd;
    private int mSelectedHour;

    public PickerHour(Context context) {
        this(context, null);
    }

    public PickerHour(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHourStart = 0;
        mHourEnd = 23;
        updateHour();
        mSelectedHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        setSelectedItemPosition(mSelectedHour - this.mHourStart);
    }

    private void updateHour() {
        List<WheelBean> data = new ArrayList<>();
        for (int i = this.mHourStart; i <= this.mHourEnd; ++i) {
            WheelBean item = new WheelBean(i, label);
            data.add(item);
        }
        super.setData(data);
    }

    public int getHourStart() {
        return this.mHourStart;
    }

    public void setHourStart(int start) {
        this.mHourStart = start;
        this.mSelectedHour = this.getCurrentHour();
        this.updateHour();
        this.setSelectedItemPosition(this.mSelectedHour - this.mHourStart);
    }

    public int getCurrentHour() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }
}








第09节 原子时间类 PickerMinute

位置

src/java/view.wheel.atom.time.PickerMinute.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

// 选择器(分钟)
public class PickerMinute extends WheelPicker {
    private int mMinuteStart;
    private int mMinuteEnd;
    private int mSelectedMinute;

    public PickerMinute(Context context) {
        this(context, null);
    }

    public PickerMinute(Context context, AttributeSet attrs) {
        super(context, attrs);
        mMinuteStart = 0;
        mMinuteEnd = 59;
        updateMinute();
        mSelectedMinute = Calendar.getInstance().get(Calendar.MINUTE);
        setSelectedItemPosition(mSelectedMinute - this.mMinuteStart);
    }

    private void updateMinute() {
        List<WheelBean> data = new ArrayList<>();
        for (int i = this.mMinuteStart; i <= this.mMinuteEnd; ++i) {
            WheelBean item = new WheelBean(i, label);
            data.add(item);
        }
        super.setData(data);
    }

    public int getMinuteStart() {
        return this.mMinuteStart;
    }

    public void setMinuteStart(int start) {
        this.mMinuteStart = start;
        this.mSelectedMinute = this.getCurrentMinute();
        this.updateMinute();
        this.setSelectedItemPosition(this.mSelectedMinute - this.mMinuteStart);
    }

    public int getCurrentMinute() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }
}








第10节 原子时间类 PickerSecond

位置

src/java/view.wheel.atom.time.PickerSecond.java

代码

package view.wheel.atom.time;

import android.content.Context;
import android.util.AttributeSet;

import view.wheel.WheelBean;
import view.wheel.WheelPicker;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

// 选择器(秒钟)
public class PickerSecond extends WheelPicker {
    private int mSecondStart;
    private int mSecondEnd;
    private int mSelectedSecond;

    public PickerSecond(Context context) {
        this(context, null);
    }

    public PickerSecond(Context context, AttributeSet attrs) {
        super(context, attrs);
        mSecondStart = 0;
        mSecondEnd = 59;
        updateSecond();
        mSelectedSecond = Calendar.getInstance().get(Calendar.SECOND);
        setSelectedItemPosition(mSelectedSecond - this.mSecondStart);
    }


    private void updateSecond() {
        List<WheelBean> data = new ArrayList<>();
        for (int i = this.mSecondStart; i <= this.mSecondEnd; i++) {
            WheelBean item = new WheelBean(i, label);
            data.add(item);
        }
        super.setData(data);
    }

    public int getSecondStart() {
        return this.mSecondStart;
    }

    public void setSecondStart(int start) {
        this.mSecondStart = start;
        this.mSelectedSecond = this.getCurrentSecond();
        this.updateSecond();
        this.setSelectedItemPosition(this.mSelectedSecond - this.mSecondStart);
    }

    public int getCurrentSecond() {
        return this.getData().get(this.getCurrentItemPosition()).getItemNumber();
    }
}








第11节 测试Activity

位置

src/java/DemoActivity.java

代码

public class DemoActivity extends AppCompatActivity {

    private DateTimePickerView mDateTimePickerView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);

        this.mDateTimePickerView = findViewById(R.id.date_time_picker_view);

        // 定义相关的属性状态
        mDateTimePickerView.setAtmospheric(true);    // 条目颜色是否执行衔接处理, 效果更好
        mDateTimePickerView.setCurved(false);        // 是否显示弧度
        mDateTimePickerView.setItemTextColorUnSelect(Color.BLUE);   // 未选中的条目颜色
        mDateTimePickerView.setItemTextColorSelected(Color.RED);   // 选中条目的颜色
        mDateTimePickerView.setCyclic(true);            // 设置是否循环

        mDateTimePickerView.setCenterLineColor(Color.BLUE);     // 设置中间线的颜色
        mDateTimePickerView.setCenterLineWidth(2);      // 设置中间线的宽度
        mDateTimePickerView.setCenterLineIsShow(false);  // 设置中间线是否显示

        mDateTimePickerView.setCenterRectColor(Color.parseColor("#66666666"));     // 设置中间矩形的颜色
        mDateTimePickerView.setCenterRectIsShow(true);  // 设置中间矩形是否显示


        // 设置显示的类型(数组的长度必须是6,分别表示 "年", "月", "日", "时", "分", "秒")
        boolean[] array = new boolean[]{
                true, true, true, true, true, false
        };
        mDateTimePickerView.setShowType(array);
    }
}








第12节 布局文件

位置

res/layout/view_picker_time_date.xml

代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal">

    <view.wheel.atom.time.PickerYear
        android:id="@+id/picker_year"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

    <view.wheel.atom.time.PickerMonth
        android:id="@+id/picker_month"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

    <view.wheel.atom.time.PickerDay
        android:id="@+id/picker_day"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

    <view.wheel.atom.time.PickerHour
        android:id="@+id/picker_hour"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

    <view.wheel.atom.time.PickerMinute
        android:id="@+id/picker_minute"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

    <view.wheel.atom.time.PickerSecond
        android:id="@+id/picker_second"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        app:wheel_label="" />

</LinearLayout>




位置

res/layout/activity_demo.xml

代码

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <view.wheel.atom.time.DateTimePickerView
        android:id="@+id/date_time_picker_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>








第13节 属性文件

位置

res/values/attrs.xml

代码

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="WheelPicker">
        <attr name="wheel_data" format="reference" />
        <attr name="wheel_selected_item_position" format="integer" />
        <attr name="wheel_item_text_size" format="dimension" />
        <attr name="wheel_item_text_color" format="color" />
        <attr name="wheel_selected_item_text_color" format="color" />
        <attr name="wheel_same_width" format="boolean" />
        <attr name="wheel_maximum_width_text" format="string" />
        <attr name="wheel_label" format="string" />
        <attr name="wheel_maximum_width_text_position" format="integer" />
        <attr name="wheel_visible_item_count" format="integer" />
        <attr name="wheel_item_space" format="dimension" />
        <attr name="wheel_cyclic" format="boolean" />
        <attr name="wheel_indicator" format="boolean" />
        <attr name="wheel_indicator_color" format="color" />
        <attr name="wheel_indicator_size" format="dimension" />
        <attr name="wheel_curtain" format="boolean" />
        <attr name="wheel_curtain_color" format="color" />
        <attr name="wheel_atmospheric" format="boolean" />
        <attr name="wheel_curved" format="boolean" />
        <attr name="wheel_item_align" format="enum">
            <enum name="center" value="0" />
            <enum name="left" value="1" />
            <enum name="right" value="2" />
        </attr>
    </declare-styleable>

</resources>








本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/251234.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络(七)路由协议以及相关配置

目录 一、路由器的工作原理 二、路由表的形成 2.1 直连网段 2.2 非直连网 2.3 路由表解析 2.3.1 查看路由表 2.3.2 解析 三、静态路由和默认路由 1. 静态路由 1.1 定义 1.2 特点 2. 默认路由 2.1 定义 2.2 特点 四、静态路由和默认路由的配置 1. 静态路由配置…

maui中实现加载更多 RefreshView跟ListView(1)

效果如图&#xff1a; MainPage.xaml.cs: using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using Microsoft.Maui.Controls; using Microsoft.Maui.Controls.Xaml; using System.ComponentModel; using System.Runtime.CompilerServices…

visual stdio code运行js没有输出

visual code运行js没有输出 先Debug file 然后右键直接run code就会输出了 插件的安装 visual stdio code插件安装 c qt wordle游戏实现

知识图谱之关键实体数据爬取

目录 爬取实体概览 爬取技术介绍 requests_html Selenium 两者比较 学习路径 代码结构 高可用爬取策略 基于文件记录位点 请求失败指数退避重试 爬取代码 品牌数据 车系数据 车型数据 车型配置数据 代码地址 爬取实体概览 一个品牌有多个车系,一个车系有多个…

C语言:猜数字游戏

#include<stdio.h> #include<time.h> #include<stdlib.h> void menu() {printf("********************************\n");printf("****** 1.开始 2.退出 ******\n");printf("********************************\n"); } voi…

论文阅读笔记(12月15)--DialogXL

论文阅读笔记(12月15)–DialogXL 基本情况介绍&#xff1a; 作者&#xff1a;Weizhou Shen等 单位&#xff1a;中山大学 时间&期刊&#xff1a;AAAI 2021 主题&#xff1a;对话情绪识别(ERC)–文本模态 论文链接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article…

MX6ULL学习笔记(十二)Linux 自带的 LED 灯

前言 前面我们都是自己编写 LED 灯驱动&#xff0c;其实像 LED 灯这样非常基础的设备驱动&#xff0c;Linux 内 核已经集成了。Linux 内核的 LED 灯驱动采用 platform 框架&#xff0c;因此我们只需要按照要求在设备 树文件中添加相应的 LED 节点即可&#xff0c;本章我们就来学…

算法:二叉树的遍历

一、31种遍历方法 (1)先序法&#xff08;又称先根法&#xff09; 先序遍历&#xff1a;根&#xff0c;左子树&#xff0c;右子树 遍历的结果&#xff1a;A&#xff0c;B&#xff0c;C 遍历的足迹&#xff1a;沿途经过各结点的“左部” (2)中序法&#xff08;又称中根法&#…

【MySQL内置函数】

目录&#xff1a; 前言一、日期函数获取日期获取时间获取时间戳在日期上增加时间在日期上减去时间计算两个日期相差多少天当前时间案例&#xff1a;留言板 二、字符串函数查看字符串字符集字符串连接查找字符串大小写转换子串提取字符串长度字符串替换字符串比较消除左右空格案…

【ArkTS】Watch装饰器

Watch装饰器&#xff0c;相当于Vue中的监听器 以及 React中使用useEffect监听变量 使用Watch装饰器&#xff0c;可以监听一个数据的变化&#xff0c;并进行后续的响应。 使用方法&#xff1a; Watch(‘回调函数’)&#xff0c;写在State装饰器后&#xff08;其实写在前面也行&a…

在thinkphp5.1 自定义验证规则 获取get 传递的值的时候 传递了 值 能够获取到 验证出错

控制器: public function teamDetail(){if(request()->isGet()){$team_id $this->request->get(team_id, );$this->validate->scene(teamDetail)->check($team_id);if ($this->validate->getError()) {return resultArray(lang(strval($this->vali…

Matcap的原理和应用

一、概念和原理 2.1 什么是Matcap 什么是Matcap&#xff1f;Matcap实际上是Material Capture的缩写&#xff0c;即材质捕捉。实际上&#xff0c;这是一种离线渲染方案。类似光照烘焙&#xff0c;将光照或者其它更复杂环境下的渲染数据存储到一张2D贴图上&#xff0c; 再从这张…

Python读写arxml文件

文章目录 前言一、XML简介二、XML文件结构三、Python读取xml文件安装ElementTree库读取xml文件四、Python写入xml文件前言 本文主要通过介绍arxml文件,为后续python脚本开发奠定基础。 arxml是AUTOSAR XML的简称,是一个通用的配置/数据库文件,实质是一个xml文件。 ①更规范…

Swin-Transformer 在图像识别中的应用

1. 卷积神经网络简单介绍 图像识别任务主要利用神经网络对图像进行特征提取&#xff0c;最后通过全连接层将特征和分类个数进行映射。传统的网络是利用线性网络对图像进行分类&#xff0c;然而图像信息是二维的&#xff0c;一般来说&#xff0c;图像像素点和周围邻域像素点相关…

Kubernetes实战(十四)-k8s高可用集群扩容master节点

1 单master集群和多master节点集群方案 1.1 单Master集群 k8s 集群是由一组运行 k8s 的节点组成的&#xff0c;节点可以是物理机、虚拟机或者云服务器。k8s 集群中的节点分为两种角色&#xff1a;master 和 node。 master 节点&#xff1a;master 节点负责控制和管理整个集群…

iPhone 与三星手机:哪一款最好?

三星比苹果好吗&#xff1f;还是苹果比三星更好&#xff1f; 小米公司如何称霸全球智能手机市场&#xff1f;小米公司&#xff0c;由雷军创立于2010年&#xff0c;是一家领先的电子巨头。以其MIUI系统和互联网服务闻名&#xff0c;小米公司在全球智能手机市场中稳居前列。小米…

Mybatis 动态SQL的插入操作

需求 : 根据用户的输入情况进行插入 动态SQL:根据需求动态拼接SQL 用户往表中插入数据,有的数据可能不想插入,比如不想让别人知道自己的性别,性别就为空 insert into userinfo(username,password,age,gender,phone) values(?,?,?,?,?); insert into userinfo(username,…

Llama 架构分析

从代码角度进行Llama 架构分析 Llama 架构分析前言Llama 架构分析分词网络主干DecoderLayerAttentionMLP 下游任务因果推理文本分类 Llama 架构分析 前言 Meta 开发并公开发布了 Llama系列大型语言模型 (LLM)&#xff0c;这是一组经过预训练和微调的生成文本模型&#xff0c;参…

NVIDIA A100 PCIE 40GB k8s-device-plugin install in kubernetes

文章目录 1. 目标2. 简介2.1 英伟达 A100 技术规格2.2 架构优势2.3 显卡跑分对比2.4 英伟达 A100 与 kubernetes 3. 安装 NVIDIA A100 GPU 40G 硬件4. NVIDIA R450 datacenter driver5. NVIDIA Container Toolkit6. 创建 runtimeclass5. MIG Strategies6. 配置仓库7. 下载镜像8…

深度学习——第6章 浅层神经网络(NN)

第6章 浅层神经网络&#xff08;NN&#xff09; 目录 6.1 神经网络模型概述 6.2 神经网络正向传播 6.3 神经网络反向传播 6.4 W和b的初始化 6.5 总结 上一课主要介绍了一些神经网络必备的基础知识&#xff0c;包括Sigmoid激活函数、损失函数、梯度下降和计算图。这些知识对…