Kotlin 自定义View之实现标尺控件(选择身高、体重等)

本篇文章讲的是Kotlin 自定义view之实现标尺控件Ruler,以选择身高、体重等。开发中,当我们需要获取用户的身高和体重等信息时,如果直接让他们输入,显然体验不够好。像类似于唯品会、好轻等APP都是使用了类似于刻度尺的控件让用户滑动选择身高体重,觉得很棒。网上已有人使用Java语言实现这样的功能,但不影响我对其的学习。和往常一样,主要还是想总结一下自定义view之实现标尺控件的开发过程以及一些需要注意的地方。

按照惯例,我们先来看看效果图
这里写图片描述

一、先总结下自定义View的步骤:
1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
3、重写onMesure
4、重写onDraw
其中onMesure方法不一定要重写,但大部分情况下还是需要重写的

二、View 的几个构造函数
1、constructor(mContext: Context)
—>java代码直接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)
—>该构造函数是在API21的时候才添加上的

三、下面我们就开始来看看代码啦
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条刻度差为
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值