仿格瓦拉生活注册界面验证码滑动效果
来源:互联网 发布:c语言生成lib库 编辑:程序博客网 时间:2024/06/07 11:09
最近在项目当中有一个滑动验证码动画效果要实现,刚开始看到这个效果感觉还是可以的,但是要实现起来觉得有点麻烦,我想大家一定都和我一样拿到这个需求一定是一顿谷歌,百度啥的,但是搜索了很久都没找到相似的效果,又催的急没办法,卷起袖子干吧,就开始自己造轮子的过程,在做这个需求的过程中,还是很有收获的比如说复习了下高中的函数知识(开玩笑,重要的是复习了下自定义view),我想大家都和一样高中的数学知识应该都忘的差不多了吧,反正我是忘的差不多了,废话不多说了,直接上代码,里面使用到了的图片,大家可以自己搞一点图片进去试试
下图是我截取的一部分,效果就是这样
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); } @Override public 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; } @Override protected 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() { @Override public 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(); } @Override public void moveKey(int key) { if (key == 0){ mTv.setClickable(true); mTv.setFocusable(true); mTv.setText("验证码错误,点击这里重试"); mTv.setOnClickListener(new View.OnClickListener() { @Override public 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>
阅读全文
0 0
- 仿格瓦拉生活注册界面验证码滑动效果
- 注册界面验证
- iOS滑动解锁/滑动获取验证码效果实现
- 界面滑动效果的制作
- Android 界面 左右滑动效果
- android Scroller 界面滑动效果
- 注册界面无刷新验证
- 注册界面及短信验证
- javaweb项目登录注册界面验证码动态生成展示
- 仿微信首次启动滑动界面效果
- Android 高仿QQ 界面滑动效果
- 仿微信首次启动滑动界面效果
- Android 高仿QQ 界面滑动效果
- Android 高仿QQ 界面滑动效果
- Android界面篇【ViewFlipper 左右滑动效果】
- 仿微信首次启动滑动界面效果
- android 仿天猫商品详情界面滑动效果
- ScrollView滑动监听实现界面动画效果
- 大数据时代的算法(一)算法基础
- python yaml用法详解
- 使用后端云服务稳定吗?这TM是我的亲身经历
- ros控制虚拟和实际ur机械臂
- 牛牛的Gate One的安装指南
- 仿格瓦拉生活注册界面验证码滑动效果
- 一致性Hash算法
- 写给自己的JAVA工程师之路-基础类库
- jQuery学习笔记
- Python建立本地服务器
- 指针和数组相关运算
- valueOf()方法
- JavaWeb自主学习--css(一),day2
- Linux多线程之基本编程