仿格瓦拉生活注册界面验证码滑动效果

2024-02-03 18:40

本文主要是介绍仿格瓦拉生活注册界面验证码滑动效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在项目当中有一个滑动验证码动画效果要实现,刚开始看到这个效果感觉还是可以的,但是要实现起来觉得有点麻烦,我想大家一定都和我一样拿到这个需求一定是一顿谷歌,百度啥的,但是搜索了很久都没找到相似的效果,又催的急没办法,卷起袖子干吧,就开始自己造轮子的过程,在做这个需求的过程中,还是很有收获的比如说复习了下高中的函数知识(开玩笑,重要的是复习了下自定义view),我想大家都和一样高中的数学知识应该都忘的差不多了吧,反正我是忘的差不多了,废话不多说了,直接上代码,里面使用到了的图片,大家可以自己搞一点图片进去试试

下图是我截取的一部分,效果就是这样

WX20171218-163655@2x.png

WX20171218-163642@2x.png

import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;import com.nineoldandroids.view.ViewHelper;public class MyFrameLayout extends FrameLayout {/*** 这里面所说的右边的距离,都是子view 距离父控件的距离,比例右边距离就是说是右边到父控件的距离*/private float down_x;//按下点的距离private ImageView imageView_8;//大框中变化的框private ImageView imageView_7;//第一个框private ImageView imageView_6;//最左边的小框,以下是从左到右private ImageView imageView_5;//第二个小框private ImageView imageView_4;//第三个小框private ImageView imageView_3;//第四个小框private ImageView imageView_2;//第五个小框private ImageView imageView_1;//第六个小框private float frist_left;//大框的左边private float frist_right;//大框的右边private float eight_right;//最右边框的右边距离,也就是第有个小框的右边距离private float frist_center;//最大框的中心点private float position;//表示变化的周期,也是从0-1的变化的距离private float position_key;//表示大框中心点移动到这个点的时候开始变化private float position_7;//大框的中点的位置private int width;//这个view 的宽度private float three_right;//第六个小框的右边距离private float position_center;//两个小框中间距离一半protected boolean isFrist = true;//这里作用就是只能滑动一次private int[] arr = {R.drawable.test_1,R.drawable.test_2,R.drawable.test_3,R.drawable.test_4,R.drawable.test_5,R.drawable.test_6,R.drawable.test_bg};private float five_right;//第5个小框的右边距离private float six_right;//第六个小框的右边距离private float seven_right;//第7个小框的右边距离private float four_right;//第八个小框的右边距离private static int KEY = 0;public MyFrameLayout(@NonNull Context context) {super(context);init(context);}public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(context);}public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}/*** 方便外部重置*/public void reset(){isFrist = true;ViewHelper.setTranslationX(imageView_7, 0);ViewHelper.setTranslationX(imageView_8, 0);}/*** 从外面传进来一个图片数组* 这里里面也可以传递一个数字的数字* @param arr*/public void inview(int[] arr) {this.arr = arr;imageView_1.setImageDrawable(this.getResources().getDrawable(R.drawable.test_1));imageView_2.setImageDrawable(this.getResources().getDrawable(R.drawable.test_2));imageView_3.setImageDrawable(this.getResources().getDrawable(R.drawable.test_3));imageView_4.setImageDrawable(this.getResources().getDrawable(R.drawable.test_4));imageView_5.setImageDrawable(this.getResources().getDrawable(R.drawable.test_5));imageView_6.setImageDrawable(this.getResources().getDrawable(R.drawable.test_6));}private void init(Context context) {View view = View.inflate(context, R.layout.my_framelayout, this);imageView_8 = (ImageView) view.findViewById(R.id.iv_8);imageView_7 = (ImageView) view.findViewById(R.id.iv_7);imageView_6 = (ImageView) view.findViewById(R.id.iv_6);imageView_5 = (ImageView) view.findViewById(R.id.iv_5);imageView_4 = (ImageView) view.findViewById(R.id.iv_4);imageView_3 = (ImageView) view.findViewById(R.id.iv_3);imageView_2 = (ImageView) view.findViewById(R.id.iv_2);imageView_1 = (ImageView) view.findViewById(R.id.iv_1);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (isFrist) {down_x = event.getX();if (down_x - frist_right >= 0 || down_x - frist_left <= 0) {//让其在这个大框的里面才能让其滑动return false;}} else {return false;}break;case MotionEvent.ACTION_MOVE:float currentX = event.getX();if (currentX != down_x) {setTranslation(currentX);}break;case MotionEvent.ACTION_UP:isFrist = false;lister.moveKey(KEY);//回调break;}return true;}/*** 随着手指的移动,一直会调用这个方法* @param transl*/public void setTranslation(float transl) {//实时的获取大框的中心点的位置float move_position = transl - down_x + position_7;//只有大框的中心点位置到达指定的关键点才让其变化,这里就是大框只变化的小框float scX = move_position - position_key;if (scX >= 0) {changeDrawable(move_position,scX);}else {imageView_8.setImageDrawable(null);//其余的地方就用不设置图片}if (transl <= down_x || transl - down_x + position_7 >= width - frist_center) {//这个就是边界点的设置} else {ViewHelper.setTranslationX(imageView_7, transl - down_x);ViewHelper.setTranslationX(imageView_8, transl - down_x);}}/*** 转变image_7的图片背景*/private void changeDrawable(float move_position,float scX){if (move_position <=three_right+position_center  && move_position >= 0) {//第一张图片的设置,以及变化的范围,下面也是相对应imageView_8.setImageDrawable(this.getResources().getDrawable(arr[5]));KEY = 1;} else if (move_position>three_right+position_center && move_position<=four_right+position_center){imageView_8.setImageDrawable(this.getResources().getDrawable(arr[4]));KEY = 2;}else if (move_position>four_right+position_center && move_position<=five_right+position_center){imageView_8.setImageDrawable(this.getResources().getDrawable(arr[3]));KEY = 3;}else if (move_position>five_right+position_center && move_position<=six_right+position_center){imageView_8.setImageDrawable(this.getResources().getDrawable(arr[2]));KEY = 4;}else if (move_position>six_right+position_center && move_position<=seven_right+position_center){imageView_8.setImageDrawable(this.getResources().getDrawable(arr[1]));KEY = 5;}else if (move_position>seven_right+position_center && move_position<=eight_right+position_center){imageView_8.setImageDrawable(this.getResources().getDrawable(arr[0]));KEY = 6;}else {imageView_8.setImageDrawable(null);KEY = 0;}//这就是这个项目的关键点,利用正弦函数,来达到这个效果,至于为啥是正弦我也是恶补了下高中的数学(开玩笑),才有想法//其实这个大家想明白了就很简单ViewHelper.setScaleX(imageView_8, (float) (Math.sin((double) (scX * Math.PI / (position * 2)))));ViewHelper.setScaleY(imageView_8, (float) (Math.sin((double) (scX * Math.PI / (position * 2)))));
//}private TransterListener lister;public interface TransterListener {void moveKey(int key);}public void setLister(TransterListener lister) {this.lister = lister;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getWidth();RelativeLayout childAt = (RelativeLayout) MyFrameLayout.this.getChildAt(0);int childCount = childAt.getChildCount();frist_left = childAt.getChildAt(childCount - 2).getLeft();frist_right = childAt.getChildAt(childCount - 2).getRight();//大框的半径frist_center = (frist_right - frist_left) / 2;float three_left = childAt.getChildAt(childCount - 3).getLeft();three_right = childAt.getChildAt(childCount - 3).getRight();four_right = childAt.getChildAt(childCount - 4).getRight();five_right = childAt.getChildAt(childCount - 5).getRight();six_right = childAt.getChildAt(childCount - 6).getRight();seven_right = childAt.getChildAt(childCount - 7).getRight();float center_6 = (three_right - three_left) / 2;//第二框的半径//大框的中心position_7 = frist_right - frist_center;//中间间距的半径position_center = (three_left - frist_right) / 2;position = center_6 + position_center;//表示变化的周期,也是从0-1的变化的距离position_key = three_left - position_center;//节点eight_right = childAt.getChildAt(childCount - 8).getRight();}
}

这个布局也是一个关键的一个地方,图片大家或者背景大家可以自己设置下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/ll_bg"android:layout_width="250dp"android:layout_height="50dp"android:background="@drawable/background_bg"android:gravity="center_vertical"><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_2"android:id="@+id/iv_1"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_1" /><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_3"android:id="@+id/iv_2"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_2" /><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_4"android:id="@+id/iv_3"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_3" /><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_5"android:id="@+id/iv_4"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_4" /><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_6"android:id="@+id/iv_5"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_5" /><ImageView
        android:layout_centerVertical="true"android:layout_marginLeft="12dp"android:layout_toRightOf="@+id/iv_7"android:id="@+id/iv_6"android:layout_width="19dp"android:layout_height="19dp"android:src="@drawable/test_6" /><ImageView
        android:layout_centerVertical="true"android:id="@+id/iv_7"android:layout_marginLeft="5dp"android:layout_width="38dp"android:layout_height="38dp"android:src="@drawable/test_bg" /><ImageView
        android:scaleType="fitCenter"android:layout_marginLeft="10dp"android:layout_centerVertical="true"android:id="@+id/iv_8"android:layout_width="28dp"android:layout_height="28dp"/></RelativeLayout>

这个地方就是显现自定义的地方

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;import com.facebook.common.util.UriUtil;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class WarmTipsDialog implements MyFrameLayout.TransterListener {private Context mContext;private Dialog dialog;private Display display;private RelativeLayout lLayout_bg;private FrameLayout rl_bg;private View view;private ImageView delete;private TextView mTv;private MyFrameLayout mSBV;public WarmTipsDialog(Context context) {this.mContext = context;WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);display = windowManager.getDefaultDisplay();}public WarmTipsDialog builder() {// 获取Dialog布局view = LayoutInflater.from(mContext).inflate(R.layout.view_warm_tip_layout, null);lLayout_bg = (RelativeLayout) view.findViewById(R.id.ll_bg);delete = (ImageView) view.findViewById(R.id.iv_delete);visibli(view);mSBV = (MyFrameLayout) view.findViewById(R.id.slid_block);mSBV.setLister(this);mTv = (TextView) view.findViewById(R.id.tv_title);
//        // 定义Dialog布局和参数dialog = new Dialog(mContext, R.style.AlertDialogStyle);dialog.setContentView(view);// 调整dialog背景大小lLayout_bg.setLayoutParams(new FrameLayout.LayoutParams((int) (display.getWidth() * 0.9), LinearLayout.LayoutParams.WRAP_CONTENT));delete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {dismissDialog();}});dialog.setCanceledOnTouchOutside(false);return this;}/*** 显示dialog*/public void showDialog(){if(mContext != null && !((Activity)mContext).isFinishing() && dialog != null){if(!dialog.isShowing()){dialog.show();}}}/*** 取消dialog*/public void dismissDialog(){dialog.dismiss();}@Overridepublic void moveKey(int key) {if (key == 0){mTv.setClickable(true);mTv.setFocusable(true);mTv.setText("验证码错误,点击这里重试");mTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mSBV.reset();}});}else {Toast.makeText(mContext, "我是" + key + "被点击了", Toast.LENGTH_SHORT).show();}}
}

对话框布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/ll_bg"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#fff"android:orientation="vertical"><ImageView
            android:id="@+id/iv_delete"android:layout_width="20dp"android:layout_height="20dp"android:layout_alignParentRight="true"android:layout_marginRight="15dp"android:layout_marginTop="15dp"android:src="@drawable/x" /><TextView
            android:id="@+id/tv_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/iv_delete"android:layout_marginTop="50dp"android:gravity="center_horizontal"android:text="@string/tv_title"android:textColor="#333333"android:textSize="20dp" /><MyFrameLayout
            android:id="@+id/slid_block"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/tv_title"android:layout_centerHorizontal="true"android:layout_marginBottom="70dp"android:layout_marginTop="55dp" /></RelativeLayout>

这篇关于仿格瓦拉生活注册界面验证码滑动效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/675036

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

Nacos注册中心和配置中心的底层原理全面解读

《Nacos注册中心和配置中心的底层原理全面解读》:本文主要介绍Nacos注册中心和配置中心的底层原理的全面解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录临时实例和永久实例为什么 Nacos 要将服务实例分为临时实例和永久实例?1.x 版本和2.x版本的区别

Python验证码识别方式(使用pytesseract库)

《Python验证码识别方式(使用pytesseract库)》:本文主要介绍Python验证码识别方式(使用pytesseract库),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1、安装Tesseract-OCR2、在python中使用3、本地图片识别4、结合playwrigh

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

Kotlin Compose Button 实现长按监听并实现动画效果(完整代码)

《KotlinComposeButton实现长按监听并实现动画效果(完整代码)》想要实现长按按钮开始录音,松开发送的功能,因此为了实现这些功能就需要自己写一个Button来解决问题,下面小编给大... 目录Button 实现原理1. Surface 的作用(关键)2. InteractionSource3.

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细