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
원본 코드 다운로드
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 실험, 에피소드 1a String 의 중심에 있는 문자를 반환하는 메서드를 작성하려는 경우 Java에서 가장 좋은 옵션은 유틸리티 클래스를 정의하는 것입니다. Kotlin을 사용하면 을 통해 기존 클래스에 새 메서드를 추가할 수 있습...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.