学习安卓小码哥自定义控件的笔记(五)

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

    <com.example.wtz.verticalslideview.VerticalSlideView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00f">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/tabicon"/>
    </com.example.wtz.verticalslideview.VerticalSlideView>
</RelativeLayout>

package com.example.wtz.verticalslideview;

import android.content.Context;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

public class VerticalSlideView extends ViewGroup {

    private View mChildView;
    private float mStartY,mStartX;

    public VerticalSlideView(Context context) {
        super(context);
    }

    public VerticalSlideView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //确定控件的大小
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //1 获得mode和size
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        mChildView = getChildAt(0);
        //测量下子控件
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        //2 判断mode,通过mode去设置对应的合理的size
        switch (widthMode) {
            case MeasureSpec.AT_MOST:
                //宽度如果是wrap_content的话,设置宽度为子控件的宽度
                widthSize = mChildView.getMeasuredWidth();
                break;
            case MeasureSpec.EXACTLY:

                break;
        }
        switch (heightMode) {
            case MeasureSpec.AT_MOST:
                //高度如果是wrap_content的话,设置高度为整个页面的高度
                heightSize = getResources().getDisplayMetrics().heightPixels/2;
                break;
            case MeasureSpec.EXACTLY:

                break;
        }
        //3 setMeasuredDimension  设置控件的大小
        setMeasuredDimension(widthSize, heightSize);
    }

    int mTop = 0;
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //去布局内部的子控件(就是那个图片滑块)
        Log.d(getClass().getSimpleName(), "onLayout: mTop: " + mTop);
        //判断一下是否超过边界
        if(mTop<0){
            //上边界
            mTop = 0;
        }
        Log.d(getClass().getSimpleName(), "onLayout: 下边界" + (getMeasuredHeight()-mChildView.getMeasuredHeight()));
        if(mTop>getMeasuredHeight()-mChildView.getMeasuredHeight()){
            //下边界
            mTop = getMeasuredHeight()-mChildView.getMeasuredHeight();
        }
        mChildView.layout(0, mTop, mChildView.getMeasuredWidth(), mTop+mChildView.getMeasuredHeight());
    }


    //写一下触摸事件逻辑
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //触摸的几种常见类型:按下   移动   抬起
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                //按下
                mStartY = event.getY();
                mStartX = event.getX();

                Log.d(getClass().getSimpleName(), "onTouchEvent:按下 "
                        +" startY: "+ mStartY);

                //如果按在空白的地方,就不再继续往下面做处理了,直接return false
                //拿到图片子控件所在的位置矩形,如果按下的坐标不在子控件位置矩形内,认为是按在空白的地方
                RectF rectF = new RectF(0, mTop, mChildView.getMeasuredWidth(), mTop + mChildView.getMeasuredHeight());
                if(!rectF.contains(mStartX,mStartY)){
                    return false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //移动
                float moveY = event.getY();
                float dy = moveY - mStartY;
                mTop+=dy;
                //以前的终点作为现在的起点
                mStartY = moveY;
//                Log.d(getClass().getSimpleName(), "onTouchEvent:移动 "
//                        +" moveY: "+moveY);
                break;
            case MotionEvent.ACTION_UP:
                //抬起
                break;
            default:
                break;
        }

        //需要让控件重新去布局一下
        requestLayout();
        //按下时 ,记录坐标,作为起点

        //移动,不断去获得坐标,终点-起点,获得偏移量(位移值),拿着位移值,去在其他地方去使用

        //抬起

        //如果不为true,那么就只会执行down逻辑,后面的move啥的就不走了
        return true;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值