Kotlin 사용자 정의 View 시리즈 튜 토리 얼 의 눈금 컨트롤(키,체중 등 선택)구현

머리말
이 글 은 키,몸무게 등 을 선택 하기 위해 Kotlin 사용자 정의 view 의 실현 자 컨트롤 러 를 다 루 고 있다.개발 과정 에서 사용자 의 키 와 체중 등 정 보 를 얻 을 필요 가 있 을 때 직접 입력 하 라 고 하면 체험 이 좋 지 않 은 것 이 분명 하 다.유품 회,가 벼 움 등 앱 은 눈금 자 와 유사 한 콘 솔 을 사용 해 사용자 가 미 끄 러 지 며 키 와 몸 무 게 를 선택 할 수 있 게 해 좋 았 다.인터넷 상에 서 이미 자바 언어 를 사용 하여 이러한 기능 을 실현 하 였 으 나,내 가 그 에 대한 학습 에 영향 을 주지 않 는 다.여느 때 와 마찬가지 로 사용자 정의 view 의 실현 자 컨트롤 개발 과정 과 주의해 야 할 부분 을 정리 하고 싶 습 니 다.
관례 에 따라 우 리 는 먼저 효과 도 를 살 펴 보 자.

1.사용자 정의 View 의 절 차 를 정리 합 니 다.
1.사용자 정의 View 의 속성
2.View 의 구조 방법 에서 사용자 정의 속성 을 얻 을 수 있 습 니 다.
3.onMesure 재 작성
4.다시 쓰기 onDraw
그 중에서 onMesure 방법 은 꼭 다시 쓰 지 는 않 지만 대부분 다시 써 야 합 니 다.
2.View 의 몇 가지 구조 함수
1、 constructor(mContext: Context)
―>자바 코드 가 new RulerView 인 스 턴 스 를 직접 사용 할 때 하나의 매개 변수 만 있 는 구조 함 수 를 호출 합 니 다.
2、 constructor(mContext: Context, attrs: AttributeSet)
->기본 XML 레이아웃 파일 에서 만 들 때 두 개의 인자 가 있 는 구조 함 수 를 호출 합 니 다.AttributeSet 형식의 인 자 는 XML 레이아웃 파일 에서 사용자 정의 속성 을 AttributeSet 을 통 해 View 에 가 져 옵 니 다.
3、 constructor(mContext: Context, attrs: AttributeSet,defStyleAttr:Int)
->구조 함수 에서 세 번 째 인 자 는 기본 Style 입 니 다.여기 서 기본 Style 은 현재 application 이나 Activity 에서 사용 하 는 Theme 의 기본 Style 을 말 하 며 명확 하 게 호출 될 때 만 호출 됩 니 다.
4、 constructor(mContext: Context, attrs: AttributeSet,defStyleAttr:Int,defStyleRes:Int)
―이 구조 함 수 는 API 21 에 추 가 된 것 이다
3.다음은 코드 를 살 펴 보 겠 습 니 다.
1.View 의 속성 을 사용자 정의 합 니 다.먼저 res/values/아래 에 attrs.xml 를 만 들 고 우리 가 필요 로 하 는 속성 과 해당 속성 을 설명 하 는 수치 유형 을 정의 합 니 다.

<android.support.constraint.ConstraintLayout 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">

 <TextView
  android:id="@+id/tv_weight_tip"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="  "
  android:textColor="@android:color/black"
  android:textSize="14dp"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toTopOf="parent"
  app:layout_constraintVertical_bias="0.132" />
 <RelativeLayout
  android:id="@+id/rl_weight_ruler"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  app:layout_constraintTop_toBottomOf="@+id/tv_weight_tip"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent">

  <per.lijuan.rulerdome.RulerView
   android:id="@+id/ruler_weight"
   android:layout_width="match_parent"
   android:layout_height="58dp"
   android:layout_marginTop="24dp"
   app:alphaEnable="true"
   app:lineColor="@android:color/darker_gray"
   app:lineMaxHeight="40dp"
   app:lineMidHeight="30dp"
   app:lineMinHeight="20dp"
   app:lineSpaceWidth="10dp"
   app:lineWidth="2.5dp"
   app:textColor="@android:color/black"
   app:minValue="20"
   app:maxValue="200"
   app:perValue="0.1"
   app:selectorValue="55"/>

  <ImageView
   android:layout_width="14dp"
   android:layout_height="46dp"
   android:layout_centerHorizontal="true"
   android:layout_marginTop="6dp"
   android:scaleType="fitXY"
   android:src="@mipmap/ic_arrow"/>
 </RelativeLayout>

 <TextView
  android:id="@+id/tv_weight"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_marginTop="11dp"
  android:maxHeight="30sp"
  android:textColor="@color/colorPrimary"
  android:textSize="24sp"
  app:layout_constraintTop_toBottomOf="@+id/rl_weight_ruler"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toStartOf="parent"/>
</android.support.constraint.ConstraintLayout>
반드시 도입xmlns:app=”http://schemas.android.com/apk/res-auto” 해 야 합 니 다.Android Studio 에서 res-atuo 네 임 스페이스 를 사용 할 수 있 습 니 다.사용자 정의 View 전체 이름 을 추가 하지 않 아 도 됩 니 다.
3.View 의 구조 방법 에서 사용자 정의 스타일 을 얻 을 수 있 습 니 다.

private var mMinVelocity:Int = 0
 private var mScroller: Scroller? = null//Scroller                   mScroller  /  View     ,   View computeScroll(),       
 private var mVelocityTracker: VelocityTracker?=null//          (flinging     gestures    )   。
 private var mWidth:Int = 0
 private var mHeight:Int = 0

 private var mSelectorValue=50f  //                            
 private var mMaxValue=200f   //     
 private var mMinValue=100f   //     
 private var mPerValue=1f   //    (  1:   2     1;0.1:   2     0.1

 private var mLineSpaceWidth = 5f //     2       
 private var mLineWidth = 4f   //        
 private var mLineMaxHeight = 420f //       3      。 mLineMaxHeight       (    10       )
 private var mLineMidHeight = 30f // mLineMidHeight        (    5 15 25      )
 private var mLineMinHeight = 17f // mLineMinHeight          (    1 2 3 4      )

 private var mTextMarginTop = 10f
 private var mTextSize = 30f   //           
 private var mAlphaEnable=false  //                  `(       )
 private var mTextHeight = 0.toFloat()//           
 private var mTextPaint: Paint?=null //         (     10      )  
 private var mLinePaint: Paint?=null //         

 private var mTotalLine:Int = 0  //        
 private var mMaxOffset:Int = 0  //         
 private var mOffset:Float = 0.toFloat()//      ,mSelectorValue                
 private var mLastX:Int = 0
 private var mMove: Int = 0
 private lateinit var mListener: OnValueChangeListener//        

 private var mLineColor:Int= Color.GRAY //     
 private var mTextColor:Int= Color.BLACK//     

 constructor(mContext: Context) : super(mContext,null)

 constructor(mContext: Context, attrs: AttributeSet) : super(mContext, attrs,0)

 constructor(mContext: Context, attrs: AttributeSet,defStyleAttr:Int) : super(mContext, attrs,defStyleAttr) {
  init(mContext, attrs)
 }

 fun init(context: Context, attrs: AttributeSet){
  Log.d(TAG, "init")
  mScroller= Scroller(context)

  this.mLineSpaceWidth=myfloat(25.0f)
  this.mLineWidth=myfloat(2.0f)
  this.mLineMaxHeight=myfloat(100.0f)
  this.mLineMidHeight=myfloat(60.0f)
  this.mLineMinHeight=myfloat(40.0f)
  this.mTextHeight=myfloat(40.0f)

  val typedArray: TypedArray =context.obtainStyledAttributes(attrs,
    R.styleable.RulerView)

  mAlphaEnable= typedArray.getBoolean(R.styleable.RulerView_alphaEnable, mAlphaEnable)

  mLineSpaceWidth = typedArray.getDimension(R.styleable.RulerView_lineSpaceWidth, mLineSpaceWidth)
  mLineWidth = typedArray.getDimension(R.styleable.RulerView_lineWidth, mLineWidth)
  mLineMaxHeight = typedArray.getDimension(R.styleable.RulerView_lineMaxHeight, mLineMaxHeight)
  mLineMidHeight = typedArray.getDimension(R.styleable.RulerView_lineMidHeight, mLineMidHeight)
  mLineMinHeight = typedArray.getDimension(R.styleable.RulerView_lineMinHeight, mLineMinHeight)
  mLineColor = typedArray.getColor(R.styleable.RulerView_lineColor, mLineColor)

  mTextSize = typedArray.getDimension(R.styleable.RulerView_textSize, mTextSize)
  mTextColor = typedArray.getColor(R.styleable.RulerView_textColor, mTextColor)
  mTextMarginTop = typedArray.getDimension(R.styleable.RulerView_textMarginTop, mTextMarginTop)

  mSelectorValue = typedArray.getFloat(R.styleable.RulerView_selectorValue, 0.0f)
  mMinValue = typedArray.getFloat(R.styleable.RulerView_minValue, 0.0f)
  mMaxValue = typedArray.getFloat(R.styleable.RulerView_maxValue, 100.0f)
  mPerValue = typedArray.getFloat(R.styleable.RulerView_perValue, 0.1f)

  mMinVelocity= ViewConfiguration.get(getContext()).scaledMinimumFlingVelocity

  mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG)
  mTextPaint!!.textSize = mTextSize
  mTextPaint!!.color = mTextColor
  mTextHeight = getFontHeight(mTextPaint!!)

  mLinePaint = Paint(Paint.ANTI_ALIAS_FLAG)
  mLinePaint!!.strokeWidth = mLineWidth
  mLinePaint!!.color = mLineColor
 }
우 리 는 세 가지 구조 방법 을 다시 썼 다.위의 구조 방법 에서 기본 적 인 구조 파일 은 두 개의 매개 변수의 구조 방법 을 호출 하 는 것 이 라 고 말 했 기 때문에 모든 구조 방법 에 세 개의 매개 변수의 구조 방법 을 호출 한 다음 에 세 개의 매개 변수의 구조 방법 에서 자정 의 속성 을 얻 도록 하 는 것 을 기억 해 야 한다.
처음에 하나의 매개 변수의 구조 방법 과 두 개의 매개 변수의 구조 방법 은 다음 과 같다.

constructor(mContext: Context) : super (mContext)

 constructor(mContext: Context, attrs: AttributeSet?) : super(mContext, attrs)
한 가지 주의해 야 할 것 은 슈퍼 가 this 로 바 꾼 다음 에 하나의 매개 변수의 구조 방법 으로 두 매개 변수의 구조 방법 을 인용 하 게 해 야 한 다 는 것 이다.두 매개 변수의 구조 방법 은 세 개의 매개 변수의 구조 방법 을 인용 하고 코드 는 다음 과 같다.

constructor(mContext: Context) : this(mContext,null)

 constructor(mContext: Context, attrs: AttributeSet?) : this(mContext, attrs!!,0)

 constructor(mContext: Context, attrs: AttributeSet,defStyleAttr:Int) : super(mContext, attrs,defStyleAttr) {
  init(mContext, attrs)
 }
4,다시 쓰기 onDraw 방법

override fun onDraw(canvas: Canvas) {
  super.onDraw(canvas)
  var left: Float
  var height: Float
  var value: String
  var alpha = 0
  var scale: Float
  val srcPointX = mWidth / 2
  for (i in 0 until mTotalLine) {
   left = srcPointX.toFloat() + mOffset + i * mLineSpaceWidth

   if (left < 0 || left > mWidth) {
    continue //         ,      view。        (          ,         )
   }

   if (i % 10 == 0) {
    height = mLineMaxHeight
   } else if (i % 5 == 0) {
    height = mLineMidHeight
   } else {
    height = mLineMinHeight
   }
   if (mAlphaEnable) {
    scale = 1 - Math.abs(left - srcPointX) / srcPointX
    alpha = (255f * scale * scale).toInt()

    mLinePaint!!.setAlpha(alpha)
   }
   canvas.drawLine(left, 0f, left, height, mLinePaint)

   if (i % 10 == 0) {
    value = (mMinValue + i * mPerValue / 10).toInt().toString()
    if (mAlphaEnable) {
     mTextPaint!!.alpha = alpha
    }
    canvas.drawText(value, left - mTextPaint!!.measureText(value) / 2,
      height + mTextMarginTop + mTextHeight, mTextPaint) //      ,    
   }
  }
 }
View 의 그리 기 프로 세 스 는 ViewRoot 의 permTravarsals 방법 에서 시 작 된 것 으로 measure,layot 와 draw 세 가지 과정 을 거 쳐 야 최종 적 으로 하나의 View 를 그 릴 수 있 습 니 다.그 중에서:
측정―onMeasure():View 의 너비 와 높이 를 측정 하여 View 의 크기 를 결정 한다.
레이아웃-onLayout():View 가 부모 용기 View Group 에 있 는 위 치 를 확인 하 는 데 사용 합 니 다.
화면 에 View 를 그립 니 다.
5.onTouchEvent 방법 재 작성
onTouchEvent()는 View 자체 테이프 의 인터페이스 로 Android 시스템 은 터치 이 벤트 를 처리 하 는 기본 구현 을 제공 합 니 다.우리 가 자 컨트롤 을 왼쪽으로 오른쪽으로 미 끄 러 뜨 릴 때 이 방법 은 호출 될 것 이다.

override fun onTouchEvent(event: MotionEvent): Boolean {
    Log.d(TAG, "onTouchEvent")

    val action = event.action
    val xPosition = event.x.toInt()

    if (mVelocityTracker == null) {
      mVelocityTracker = VelocityTracker.obtain()
    }
    mVelocityTracker!!.addMovement(event)

    when (action) {
      MotionEvent.ACTION_DOWN -> {
        mScroller!!.forceFinished(true)
        mLastX = xPosition
        mMove = 0
      }
      MotionEvent.ACTION_MOVE -> {
        mMove = mLastX - xPosition
        changeMoveAndValue()
      }
      MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
        countMoveEnd()
        countVelocityTracker()
        return false
      }
      else -> {
      }
    }

    mLastX = xPosition
    return true
  }
지금 나 는 완전한 코드 를 붙 였 다.

package per.lijuan.rulerdome

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
import android.view.ViewConfiguration
import android.widget.Scroller

/**
 * Created by juan on 2018/5/11.
 */
class RulerView: View {
  private val TAG : String = "RulerView"

  private var mMinVelocity:Int = 0
  private var mScroller: Scroller? = null//Scroller                    mScroller  /  View     ,   View computeScroll(),       
  private var mVelocityTracker: VelocityTracker?=null//          (flinging     gestures    )   。
  private var mWidth:Int = 0
  private var mHeight:Int = 0

  private var mSelectorValue=50f   //                            
  private var mMaxValue=200f     //     
  private var mMinValue=100f     //     
  private var mPerValue=1f      //    (  1:   2     1;0.1:   2     0.1

  private var mLineSpaceWidth = 5f  //     2       
  private var mLineWidth = 4f     //        
  private var mLineMaxHeight = 420f  //       3      。 mLineMaxHeight       (    10       )
  private var mLineMidHeight = 30f  // mLineMidHeight        (    5 15 25      )
  private var mLineMinHeight = 17f  // mLineMinHeight          (    1 2 3 4      )

  private var mTextMarginTop = 10f
  private var mTextSize = 30f     //           
  private var mAlphaEnable=false    //                  `(       )
  private var mTextHeight = 0.toFloat()//           
  private var mTextPaint: Paint?=null  //         (     10      )  
  private var mLinePaint: Paint?=null  //         

  private var mTotalLine:Int = 0    //        
  private var mMaxOffset:Int = 0    //         
  private var mOffset:Float = 0.toFloat()//      ,mSelectorValue                
  private var mLastX:Int = 0
  private var mMove: Int = 0
  private lateinit var mListener: OnValueChangeListener//        

  private var mLineColor:Int= Color.GRAY //     
  private var mTextColor:Int= Color.BLACK//     

  constructor(mContext: Context) : this(mContext,null)

  constructor(mContext: Context, attrs: AttributeSet?) : this(mContext, attrs!!,0)

  constructor(mContext: Context, attrs: AttributeSet,defStyleAttr:Int) : super(mContext, attrs,defStyleAttr) {
    init(mContext, attrs)
  }

  fun init(context: Context, attrs: AttributeSet){
    Log.d(TAG, "init")
    mScroller= Scroller(context)

    this.mLineSpaceWidth=myfloat(25.0f)
    this.mLineWidth=myfloat(2.0f)
    this.mLineMaxHeight=myfloat(100.0f)
    this.mLineMidHeight=myfloat(60.0f)
    this.mLineMinHeight=myfloat(40.0f)
    this.mTextHeight=myfloat(40.0f)

    val typedArray: TypedArray =context.obtainStyledAttributes(attrs,
        R.styleable.RulerView)

    mAlphaEnable= typedArray.getBoolean(R.styleable.RulerView_alphaEnable, mAlphaEnable)

    mLineSpaceWidth = typedArray.getDimension(R.styleable.RulerView_lineSpaceWidth, mLineSpaceWidth)
    mLineWidth = typedArray.getDimension(R.styleable.RulerView_lineWidth, mLineWidth)
    mLineMaxHeight = typedArray.getDimension(R.styleable.RulerView_lineMaxHeight, mLineMaxHeight)
    mLineMidHeight = typedArray.getDimension(R.styleable.RulerView_lineMidHeight, mLineMidHeight)
    mLineMinHeight = typedArray.getDimension(R.styleable.RulerView_lineMinHeight, mLineMinHeight)
    mLineColor = typedArray.getColor(R.styleable.RulerView_lineColor, mLineColor)

    mTextSize = typedArray.getDimension(R.styleable.RulerView_textSize, mTextSize)
    mTextColor = typedArray.getColor(R.styleable.RulerView_textColor, mTextColor)
    mTextMarginTop = typedArray.getDimension(R.styleable.RulerView_textMarginTop, mTextMarginTop)

    mSelectorValue = typedArray.getFloat(R.styleable.RulerView_selectorValue, 0.0f)
    mMinValue = typedArray.getFloat(R.styleable.RulerView_minValue, 0.0f)
    mMaxValue = typedArray.getFloat(R.styleable.RulerView_maxValue, 100.0f)
    mPerValue = typedArray.getFloat(R.styleable.RulerView_perValue, 0.1f)

    mMinVelocity= ViewConfiguration.get(getContext()).scaledMinimumFlingVelocity

    mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    mTextPaint!!.textSize = mTextSize
    mTextPaint!!.color = mTextColor
    mTextHeight = getFontHeight(mTextPaint!!)

    mLinePaint = Paint(Paint.ANTI_ALIAS_FLAG)
    mLinePaint!!.strokeWidth = mLineWidth
    mLinePaint!!.color = mLineColor
  }

  private fun myfloat(paramFloat:Float):Float{
    return 0.5f+paramFloat*1.0f
  }

  private fun getFontHeight(paint: Paint):Float{
    val fm = paint.fontMetrics
    return fm.descent - fm.ascent
  }

  /**
   *        
   * @param selectorValue                            
   * @param minValue      
   * @param maxValue       
   * @param per      ( 1:   2     1;0.1:   2     0.1;    mPerValue 1,  mPerValue  0.1)
   */
  fun setValue(selectorValue: Float, minValue: Float, maxValue: Float, per: Float) {
    this.mSelectorValue = selectorValue
    this.mMaxValue = maxValue
    this.mMinValue = minValue
    this.mPerValue = per * 10.0f
    this.mTotalLine = ((mMaxValue * 10 - mMinValue * 10) / mPerValue).toInt() + 1


    mMaxOffset = (-(mTotalLine - 1) * mLineSpaceWidth).toInt()
    mOffset = (mMinValue - mSelectorValue) / mPerValue * mLineSpaceWidth * 10f
    Log.d(TAG, "mOffset:" + mOffset + ",mMaxOffset:" + mMaxOffset
        + ",mTotalLine:" + mTotalLine)
    invalidate()
    visibility = View.VISIBLE
  }

  fun setOnValueChangeListener(listener: OnValueChangeListener) {
    mListener = listener
  }

  override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

    super.onSizeChanged(w, h, oldw, oldh)
    if (w > 0 && h > 0) {
      mWidth = w
      mHeight = h
    }
  }

  override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    var left: Float
    var height: Float
    var value: String
    var alpha = 0
    var scale: Float
    val srcPointX = mWidth / 2
    for (i in 0 until mTotalLine) {
      left = srcPointX.toFloat() + mOffset + i * mLineSpaceWidth

      if (left < 0 || left > mWidth) {
        continue //         ,      view。        (          ,         )
      }

      if (i % 10 == 0) {
        height = mLineMaxHeight
      } else if (i % 5 == 0) {
        height = mLineMidHeight
      } else {
        height = mLineMinHeight
      }
      if (mAlphaEnable) {
        scale = 1 - Math.abs(left - srcPointX) / srcPointX
        alpha = (255f * scale * scale).toInt()

        mLinePaint!!.setAlpha(alpha)
      }
      canvas.drawLine(left, 0f, left, height, mLinePaint)

      if (i % 10 == 0) {
        value = (mMinValue + i * mPerValue / 10).toInt().toString()
        if (mAlphaEnable) {
          mTextPaint!!.alpha = alpha
        }
        canvas.drawText(value, left - mTextPaint!!.measureText(value) / 2,
            height + mTextMarginTop + mTextHeight, mTextPaint)  //      ,    
      }
    }
  }

  override fun onTouchEvent(event: MotionEvent): Boolean {
    Log.d(TAG, "onTouchEvent")

    val action = event.action
    val xPosition = event.x.toInt()

    if (mVelocityTracker == null) {
      mVelocityTracker = VelocityTracker.obtain()
    }
    mVelocityTracker!!.addMovement(event)

    when (action) {
      MotionEvent.ACTION_DOWN -> {
        mScroller!!.forceFinished(true)
        mLastX = xPosition
        mMove = 0
      }
      MotionEvent.ACTION_MOVE -> {
        mMove = mLastX - xPosition
        changeMoveAndValue()
      }
      MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
        countMoveEnd()
        countVelocityTracker()
        return false
      }
      else -> {
      }
    }

    mLastX = xPosition
    return true
  }

  private fun countVelocityTracker() {
    Log.d(TAG, "countVelocityTracker")
    mVelocityTracker!!.computeCurrentVelocity(1000) //        
    val xVelocity = mVelocityTracker!!.xVelocity //     
    if (Math.abs(xVelocity) > mMinVelocity) {
      mScroller!!.fling(0, 0, xVelocity.toInt(), 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0)
    }
  }

  /**
   *      ,     2      ,  mOffset          。
   */
  private fun countMoveEnd() {
    mOffset -= mMove.toFloat()
    if (mOffset <= mMaxOffset) {
      mOffset = mMaxOffset.toFloat()
    } else if (mOffset >= 0) {
      mOffset = 0f
    }

    mLastX = 0
    mMove = 0

    mSelectorValue = mMinValue + Math.round(Math.abs(mOffset) * 1.0f / mLineSpaceWidth) * mPerValue / 10.0f
    mOffset = (mMinValue - mSelectorValue) * 10.0f / mPerValue * mLineSpaceWidth

    notifyValueChange()
    postInvalidate()
  }

  /**
   *       
   */
  private fun changeMoveAndValue() {
    mOffset -= mMove.toFloat()

    if (mOffset <= mMaxOffset) {
      mOffset = mMaxOffset.toFloat()
      mMove = 0
      mScroller!!.forceFinished(true)
    } else if (mOffset >= 0) {
      mMove = 0
      mScroller!!.forceFinished(true)
    }
    mSelectorValue = mMinValue + Math.round(Math.abs(mOffset) * 1.0f / mLineSpaceWidth) * mPerValue / 10.0f


    notifyValueChange()
    postInvalidate()
  }

  private fun notifyValueChange() {
    if (null != mListener) {
      mListener.onValueChange(mSelectorValue)
    }
  }

  /**
   *       
   */
  interface OnValueChangeListener{
    fun onValueChange(value: Float)
  }

  override fun computeScroll() {
    Log.d(TAG, "computeScroll")
    super.computeScroll()
    if (mScroller!!.computeScrollOffset()) {//mScroller.computeScrollOffset()  true         
      if (mScroller!!.currX == mScroller!!.finalX) {
        countMoveEnd()
      } else {
        val xPosition = mScroller!!.currX
        mMove = mLastX - xPosition
        changeMoveAndValue()
        mLastX = xPosition
      }
    }
  }
}
페이지 에서 저 희 는 사용자 정의 눈금 자 에 기본 인 자 를 설정 해 야 합 니 다.선택 하지 않 았 을 때 기본 값,최대 수치,최소 수치 와 최소 단 위 를 설정 해 야 합 니 다.

//   view
    mWeightRuler!!.setOnValueChangeListener(object : RulerView.OnValueChangeListener {
      override fun onValueChange(value: Float) {
        weight = value
        mTvWeight!!.text = weight.toString() + "kg"
      }
    })
    mWeightRuler!!.setValue(55f, 20f, 200f, 0.1f)
참고 자료:
https://github.com/panacena/RuleView
원본 코드 다운로드
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기