自定义View之时间滚轮(圆环状)

前言

想写这个好久了,这个本来也早就可以发出来了,因为懒癌,一直未能实现,以后尽量保持月更的劲头,欢迎监督.

效果

这里写图片描述

实现

功能简介: 一年以内的任意天和week是可以对应起来的,其他的日与月不限制年
实现原理:利用一个自定义的滚轮来写日周月相互对应的逻辑部分
自定义view的源码如下:

package com.lwyy.wheel.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;


import com.lwyy.wheel.R;

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

/**
 * Created by ll on 2017/9/25.
 */

public class CircleWheelView extends View {
   
    private static final String TAG = CircleWheelView.class.getSimpleName();
    private int mItemAlign;
    public static final int ALIGN_CENTER = 0, ALIGN_LEFT = 1, ALIGN_RIGHT = 2;
    private Paint mPaint;
    private OnItemSelectedListener mOnItemSelectedListener;
    private int mTextMaxWidth, mTextMaxHeight;

    private Rect mRectDrawn;
    private int mDrawnCenterX, mDrawnCenterY;                                                  //滚轮选择器绘制中心坐标
    private int mWheelCenterX, mWheelCenterY;                                                  //滚轮选择器中心坐标
    private int mItemTextColor, mSelectedItemTextColor;                                      //数据项文本颜色以及被选中的数据项文本颜色
    private int mItemHeight;
    private float mItemTextSize;

    private int mLastPointY;                                                                      //用户手指上一次触摸事件发生时事件Y坐标
    private float moveY;

    private List mData = new ArrayList();
    private List mDataCC = new ArrayList();
    private int mTurnToCenterX;

    private int mCurrentItemPosition;
    private int mDefaultHalfNum = 7, mDefaultVisibleNum = 13;                                         //设置当前view默认可见的item个数
    private int mVisibleHalfNum, mVisibleCount;                                                 //视图区域内的展示的item个数
    private int mDataSize;

    private boolean isCyclic;                                                                    //数据是否循环展示  针对list的数目小于mDefaultVisibleNum
    private boolean isLoopDisplay;                                                              //所有的数据是否是球形展示,即永远的头尾衔接,如果isCyclic是true,则该值也是true

    private float[] rates = null;
    private float[] textSizeRates = null;

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

    public CircleWheelView(Context context, AttributeSet attrs) {
   
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleWheelView);
        mItemTextSize = a.getDimensionPixelSize(R.styleable.CircleWheelView_wheel_item_text_size,
                getResources().getDimensionPixelSize(R.dimen.WheelItemTextSize_Default));
        mItemAlign = a.getInt(R.styleable.CircleWheelView_wheel_item_align, ALIGN_CENTER);
        mItemTextColor = a.getColor(R.styleable.CircleWheelView_wheel_item_text_color, 0xFF888888);
        mSelectedItemTextColor = a.getColor(R.styleable.CircleWheelView_wheel_selected_item_text_color, 0xFF888899);
        mTurnToCenterX = a.getInt(R.styleable.CircleWheelView_wheel_turn_to_centerx, 0);             //转向中间,偏移的距离
        isCyclic = a.getBoolean(R.styleable.CircleWheelView_wheel_cyclic, false);
        isLoopDisplay = a.getBoolean(R.styleable.CircleWheelView_wheel_loop_display, false);
        a.recycle();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mRectDrawn = new Rect();
    }

    @Override
    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 = mTextMaxWidth;
        int resultHeight = mTextMaxHeight * mVisibleCount;

        // 考虑内边距对尺寸的影响
        resultWidth += getPaddingLeft() + getPaddingRight();
        resultHeight += getPaddingTop();

        // 考虑父容器对尺寸的影响
        resultWidth = measureSize(modeWidth, sizeWidth, resultWidth);
        resultHeight = measureSize(modeHeight, sizeHeight, resultHeight);
        setMeasuredDimension(resultWidth, resultHeight);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   
        super.onSizeChanged(w, h, oldw, oldh);
        // 获取内容区域中心坐标
        mRectDrawn.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(),
                getHeight() - getPaddingBottom());
        mWheelCenterX = mRectDrawn.centerX();
        mWheelCenterY = mRectDrawn.centerY();
        computeDrawnCenter(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值