Android如何自定View实现滑动验证效果
导读:本文共4645字符,通常情况下阅读需要15分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 效果图自定义属性代码<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="My... ...
音频解说
目录
(为您整理了一些要点),点击可以直达。
效果图
自定义属性代码
<?xmlversion="1.0"encoding="utf-8"?><resources><declare-styleablename="MyCheckView"><attrname="m_blockBg"format="reference"/><!--滑块背景图片--><attrname="m_blockColor"format="color"/><!--滑块颜色--><attrname="m_blockShadowLayer"format="color"/><!--滑块阴影颜色--><attrname="m_proColor"format="color"/><!--进度条颜色--><attrname="m_recColor"format="color"/><!--矩形背景色--><attrname="m_circleSize"format="integer"/><!--圆角角度值--></declare-styleable></resources>
自定义View代码
publicclassMyCheckViewextendsView{privatebooleanisBlockArea=false;privatebooleanisMove=false;privatebooleanisFinish=false;privatebooleanisDown=false;privateintmRight;privateintstartX=0;/***滑块边距*/privatefinalintblockSize=SizeUtils.dp2px(5);/***相关属性*/privateintm_blockColor=Color.WHITE;//默认滑块颜色privateintm_blockShadowLayer=Color.parseColor("#D8D8D8");//默认滑块阴影色privateintm_proColor=Color.parseColor("#ff3159");//默认进度条颜色privateintm_recColor=Color.parseColor("#D8D8D8");//默认矩形颜色privateintblockDrawableId;//默认滑块背景图/***矩形画笔*/privatefinalPaintrecPaint=newPaint();/***进度条画笔*/privatefinalPaintproPaint=newPaint();/***滑块画笔*/privatefinalPaintblockPaint=newPaint();/***圆角角度*/privateintcircleSize=SizeUtils.dp2px(20);/***记录父控件宽度*/privatefloatparentWidth=0f;/***矩形高度*/privateintproHeight;/***默认高度*/privatefinalintDEFAULT_HEIGHT=SizeUtils.dp2px(45);/***滑块宽度*/privatefinalintblockWidth=SizeUtils.dp2px(60);/***手指落下位置*/privateintdX;/***偏移距离*/privateintmX;/***接口回调*/privateFinishListenerfinishListener;publicvoidsetFinishListener(FinishListenerfinishListener){this.finishListener=finishListener;}publicMyCheckView(@NonNullContextcontext){super(context);init();}publicMyCheckView(@NonNullContextcontext,@NullableAttributeSetattrs){super(context,attrs);initParams(context,attrs);init();}publicMyCheckView(@NonNullContextcontext,@NullableAttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);initParams(context,attrs);init();}/***初始化自定义属性**@paramcontext上下文*@paramattrs属性参数*/privatevoidinitParams(Contextcontext,AttributeSetattrs){TypedArraytypedArray=context.obtainStyledAttributes(attrs,R.styleable.MyCheckView);if(typedArray!=null){//获取滑块背景图片blockDrawableId=typedArray.getResourceId(R.styleable.MyCheckView_m_blockBg,-1);//获取滑块颜色m_blockColor=typedArray.getColor(R.styleable.MyCheckView_m_blockColor,m_blockColor);//滑块阴影色m_blockShadowLayer=typedArray.getColor(R.styleable.MyCheckView_m_blockColor,m_blockShadowLayer);//进度条颜色m_proColor=typedArray.getColor(R.styleable.MyCheckView_m_blockColor,m_proColor);//矩形颜色m_recColor=typedArray.getColor(R.styleable.MyCheckView_m_blockColor,m_recColor);//圆角角度值circleSize=typedArray.getInt(R.styleable.MyCheckView_m_blockColor,circleSize);typedArray.recycle();}}/***初始化画笔*/privatevoidinit(){//设置矩形背景色recPaint.setColor(m_recColor);recPaint.setStyle(Paint.Style.FILL);recPaint.setAntiAlias(true);//设置进度条背景色proPaint.setColor(m_proColor);proPaint.setStyle(Paint.Style.FILL);recPaint.setAntiAlias(true);//判断是否使用了背景图if(blockDrawableId!=-1){//设置滑块背景色blockPaint.setColor(m_blockColor);blockPaint.setStyle(Paint.Style.FILL_AND_STROKE);blockPaint.setAntiAlias(true);//给滑块添加阴影blockPaint.setShadowLayer(35,1,1,m_blockShadowLayer);}else{blockPaint.setStyle(Paint.Style.FILL_AND_STROKE);blockPaint.setAntiAlias(true);}}publicvoidblockReset(){mX=0;reset(startX);}@OverrideprotectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){super.onMeasure(widthMeasureSpec,heightMeasureSpec);parentWidth=getMyWSize(widthMeasureSpec);proHeight=getMyHSize(heightMeasureSpec);setMeasuredDimension((int)parentWidth,proHeight);}@SuppressLint("DrawAllocation")@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);//绘制矩形RectFrectF=newRectF();rectF.left=1;rectF.right=parentWidth-1;rectF.top=1;rectF.bottom=proHeight-1;//绘制圆角矩形canvas.drawRoundRect(rectF,circleSize,circleSize,recPaint);if(isMove||isDown){//绘制进度条RectFrectP=newRectF();rectP.left=1;rectP.right=blockWidth+blockSize+mX;rectP.top=1;rectP.bottom=proHeight-1;canvas.drawRoundRect(rectP,circleSize,circleSize,proPaint);}//绘制滑块RectFrectB=newRectF();rectB.left=blockSize+mX;rectB.right=blockWidth+mX;rectB.top=blockSize;rectB.bottom=proHeight-blockSize;mRight=(int)rectB.right;//判断是否使用了背景图if(blockDrawableId!=-1){//绘制背景图Bitmapbitmap=BitmapFactory.decodeResource(getResources(),blockDrawableId);Rectrect=newRect(0,0,bitmap.getWidth(),bitmap.getHeight());canvas.drawBitmap(bitmap,rect,rectB,blockPaint);}else{//绘制滑块canvas.drawRoundRect(rectB,circleSize,circleSize,blockPaint);}}@SuppressLint("ClickableViewAccessibility")@OverridepublicbooleanonTouchEvent(MotionEventevent){switch(event.getAction()){caseMotionEvent.ACTION_DOWN:dX=(int)event.getX();intdY=(int)event.getY();inttop=getTop();intbottom=getBottom();//判断区域是否为滑块if(dX>blockSize&&dX<blockWidth&&dY>blockSize&&dY<(bottom-top)){isBlockArea=true;}returntrue;caseMotionEvent.ACTION_MOVE:if(isBlockArea){mX=(int)event.getX()-dX;//设置范围if((blockWidth+blockSize+mX)<parentWidth&&(blockSize+mX)>=blockSize){//计算偏移量invalidate();startX=(int)event.getX()-blockWidth/2;}elseif((blockSize+mX)>=blockSize){//超出复位mX=(int)parentWidth-blockWidth-blockSize;invalidate();}isMove=true;}returntrue;caseMotionEvent.ACTION_UP:caseMotionEvent.ACTION_CANCEL:isBlockArea=false;isFinish=mRight==parentWidth-blockSize;if(isFinish){//监听回调if(finishListener!=null){finishListener.finish();}}if(!isFinish&&isMove){reset(startX);}break;}returnsuper.onTouchEvent(event);}/***松手回弹动画效果*/privatevoidreset(intstart){ValueAnimatorvalueAnimator=ValueAnimator.ofInt(start,0);valueAnimator.setDuration(500);valueAnimator.start();valueAnimator.addUpdateListener(animation->{mX=(int)animation.getAnimatedValue();//刷新invalidate();});valueAnimator.addListener(newAnimatorListenerAdapter(){@OverridepublicvoidonAnimationEnd(Animatoranimation){isMove=false;isFinish=false;startX=0;}});}/***获取测量大小*/privateintgetMyWSize(intmeasureSpec){intresult;intspecMode=MeasureSpec.getMode(measureSpec);intspecSize=MeasureSpec.getSize(measureSpec);if(specMode==MeasureSpec.EXACTLY){result=specSize;//确切大小,所以将得到的尺寸给view}elseif(specMode==MeasureSpec.AT_MOST){result=Math.min(getScreenWidth()-20,specSize);}else{result=getScreenWidth()-20;}returnresult;}/***获取测量大小*/privateintgetMyHSize(intmeasureSpec){intresult;intspecMode=MeasureSpec.getMode(measureSpec);intspecSize=MeasureSpec.getSize(measureSpec);if(specMode==MeasureSpec.EXACTLY){result=specSize;//确切大小,所以将得到的尺寸给view}elseif(specMode==MeasureSpec.AT_MOST){result=Math.min(DEFAULT_HEIGHT,specSize);}else{result=DEFAULT_HEIGHT-20;}returnresult;}/***获取屏幕宽度*/privateintgetScreenWidth(){WindowManagerwindowManager=(WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);DisplayMetricsdisplayMetrics=newDisplayMetrics();windowManager.getDefaultDisplay().getMetrics(displayMetrics);returndisplayMetrics.widthPixels;}/***接口回调方法*/publicinterfaceFinishListener{voidfinish();}}
使用方法
<com.guanwei.globe.view.MyCheckViewandroid:id="@+id/checkView"android:layout_width="200dp"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintTop_toTopOf="parent"app:m_blockBg="@mipmap/block"/>
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:
Android如何自定View实现滑动验证效果的详细内容,希望对您有所帮助,信息来源于网络。