自定义控件day02笔记

本文介绍了一种基于Android平台的滑动解锁功能实现方法。通过自定义View组件,结合Scroller进行平滑滚动效果处理,并利用TouchEvent监测用户交互,实现了滑动解锁功能。文章详细解释了如何设置滑动边界、移动距离及解锁逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SrollTo

view的显示坐标,其实就是无边界的坐标,控件的显示其实有固定的局域,但是在控件之外还有很多的坐标点,只不过是我们的控件没有显示出来而已

以控件的左上角为原点来计算 (0,0) , 如果是scrollTo(-50 , 0 ) , 那么将会把左边 负数坐标的内容给拽拉出来,放到这个控件的0,0来显示。 如果是 scrollTo(50 , 0 ) , 那么将会把右边 正数坐标的内容给拽拉过去,放到这个控件的0 ,0 来显示。

ScrollTo:如果是负数,那么将左边不可见的(x,y)坐标内容滑出来

SrcollTo:如果是正数,那么右边不可见的(x,y)坐标内容滑出来

左边边界判断:
如果是DownX-(BitMap.getwidth)/2=dx;
dx

SrollBy和SrollTo的区别

SroollTo是直接移动到设定的位置;

SrcollBy是在原先的基础上做增量移动(叠加);

getScollX是获取移动的距离–如果是负数表明滑块向右边移动,如果是正数则表明滑块向左边移动

Scroller

是一个工具类,能够平滑,柔顺的滑动页面,控件

使用步骤:

     1.定义一个Srocller对象
        Sroller mSroller=new Sroller(Context context);
     2.使用Sroller的startsroll开始移动
        /* 开始移动
         * 参数一: 开始移动的x坐标点
         * 参数二: 开始移动的y坐标点
         * 参数三: 水平方向移动的距离
         * 参数四: 垂直方向移动的距离
         * 参数五:  移动的时长。
         * /
    mSroller.startSroll(startX,startY,dx,dy,duration);  
    ////////////////////
    @Override
    public void computeScroll() {
        //0  -1  -2 -3 -4 。。。。。 -100
        //-50
    //早前的移动仍然没有做完
    if(mScroller.computeScrollOffset()){
        //重新获取目前移动的位置
        int currentX = mScroller.getCurrX();
        scrollTo(currentX, 0);
        //再一次重绘
        invalidate();
    }else{
        //判断是否已经移动到右边边界了
        if(isToRight){
            mListener.onUnLock();
            isToRight = false;
        }
    }
}

案例–滑动解锁

布局

<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"
android:background="#000000"
tools:context=".MainActivity" >

<com.lxk.slideunlock.view.SildeUnLockView
    android:id="@+id/slv"
    android:layout_alignParentBottom="true"
    <!--这里要在在drawable文件写一个shap布局shap_dg_open,设定半径radius:10dp,颜色背景#55FFFFFF-->
    android:background="@drawable/shap_dg_open"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
     />

</RelativeLayout>

代码 MainActivity

package com.lxk.slideunlock;

import com.lxk.slideunlock.view.SildeUnLockView;
import com.lxk.slideunlock.view.SildeUnLockView.OnUnLockListener;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity implements OnUnLockListener {

private SildeUnLockView mSlv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mSlv = (SildeUnLockView) findViewById(R.id.slv);
    mSlv.setOnUnLockListener(this);

}

@Override
public void UnLock() {
    //利用接口回调方法
    Toast.makeText(this,"成功解锁", 0).show();
    finish();
}


}

自定义 SildeUnLockView 代码

package com.lxk.slideunlock.view;
import com.lxk.slideunlock.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;
/**
 * 滑动解锁--View是表示显示在UI界面上面的
 *  自定义View的三个步骤:
 *  1.测量自己的大小
 *  2.设置自己现在在父控件的位置
 *  3.绘画该控件出来
 */
public class SildeUnLockView  extends View{

private static  boolean isRight = false;
private Paint mPaint;
private Scroller mScroller;
private Bitmap mBitmap;

public SildeUnLockView(Context context, AttributeSet attrs) {
    super(context, attrs);
    //创建一个画笔
    mPaint = new Paint();
    //创建一个滑动效果的工具类Scroller(context)---
    mScroller = new Scroller(context);
    //加载一个图片
    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_button);

}

//测量自己的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //super.onMeasure(widthMeasureSpec, heightMeasureSpec);//这个是使用父类布局的大小
        //设置图片的宽度跟父类一样
        int width = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(width, mBitmap.getHeight());
}

//绘画
@Override
protected void onDraw(Canvas canvas) {

    //绘画该图片出来
    canvas.drawBitmap(mBitmap, 0, 0, mPaint);
}

float mDownX,mMoveX,mUpX;
//重写父类的onTuchEvent(MotionEvent event)方法来监听触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN://监听按下的动作
        //开始规定如果鼠标按下的X坐标不在图片的宽度/2和图片的宽度之间,就不允许滑动
        mDownX=event.getX();
        if (mDownX<mBitmap.getWidth()/2||mDownX>mBitmap.getWidth()) {
            return false;//false则交给系统处理 不需要我们处理,相当不允许图片滑动了
        }
        //执行按下的操作方法
        performDown();

        break;
    case MotionEvent.ACTION_MOVE://鼠标触摸移动的动作
        //获取移动的X的位置
        mMoveX=event.getX();
        performMove();
        break;
    case MotionEvent.ACTION_UP://鼠标抬起的动作
        mUpX=event.getX();
        performUp();
        break;


    }



    return true;//true表示事件发生的改变,都由我们自己处理,不需要别人
}

//执行抬起的动作方法
private void performUp() {
    //规定如果抬起来的X坐标大于控件背景一般则直接移动到右边的边界处,否则直接移动到左边的边界
    int dx=0;
    if (mUpX>getMeasuredWidth()/2) {
        isRight=true;
         dx=(int) (mBitmap.getWidth()-getMeasuredWidth()-getScrollX());
         System.out.println("dx=== 1"+dx);

    } else {
         dx=-getScrollX();
         System.out.println("dx===2 "+dx);
    }
    int durantion=dx*7;
    //如果时间太长则就按1000毫秒来算
    if (durantion>1000) {
        durantion=1000;
    }

    //利用Scroller类来来滑动==参数一二表示:开始移动的xy坐标,参数三四:表示水平和垂直移动的距离,参数五:移动的时间
    mScroller.startScroll(getScrollX(), 0, dx, 0,durantion);
    //重新绘制
    invalidate();
}
//当前没有移动完则继续移动
@Override
public void computeScroll() {
    super.computeScroll();
    if (mScroller.computeScrollOffset()) {
        //获取当前的移动X坐标
        int currX = mScroller.getCurrX();
        //继续移动完
        scrollTo(currX, 0);
        //重新绘制
        invalidate();
    } else {
        //判断是否是向右边移动如果是且超过背景一半则解锁
        if (isRight) {
            mListener.UnLock();
            //重置状态
            isRight=false;
        }
    }

}


//执行移动的距离
private void performMove() {

    int dx=Math.round(mDownX-mMoveX);
    //界定边界--判断移动过程是否超过边界
    if (-dx>getMeasuredWidth()-mBitmap.getWidth()) {//判断右边的边界

        dx=mBitmap.getWidth()-getMeasuredWidth();


    } else if (dx>0) {//判断左边的边界
        dx=0;
    }

    scrollTo(dx, 0);//SroollTo是直接移动到设定的位置


}


OnUnLockListener mListener;//定义一个成员的变量:mListener
public void setOnUnLockListener(OnUnLockListener listener){
    mListener=listener;//通过MainActivity传过来的参数
    }

//创建一个接口回调
public interface OnUnLockListener{
    public void UnLock();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值