Android携程高级用法,Android真正仿携程首页view实现
一 需求:实现view的点击缩放效果,类似于携程首页。
二 需求分析:对于单纯的view的缩放还是比较简单的,我们使用单纯的android缩放动画就可以实现。但是按照携程首页的view来做的话,里面是有很多细节是我们需要处理的。
1 对于一张图片,当我们按下然后左右滑动时它应该仍然处于缩放状态,直到我们的手指脱离开view的边界才回到初始状态。
2 如果说我们的view的父控件是scrollview的话,这里就需要用到android中事件分发的相关知识了。
当我们按下view时,需要view来处理接下来的事件,但如果我们是向上或者向下滑动的话,当滑出一小段距离时,我们需要把view重置为
初始状态,同时把事件交给scrollview来处理使其可以进行上下滑动。
三 说了这么多,相信大家还是有点摸不着头脑的,没关系,我们先来张屏幕截图,然后我们直接贴出源码。
运行效果:
缩放view源码:
package com.example.asiatravel.ctriphomescaleview.view;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
/**
* Created by kuangxiaoguo on 16/8/30.
*/
public class CTripHomeScaleView extends ImageView {
/**
* 动画持续时长
*/
private static final int DURATION = 100;
/**
* 快速点击的时间间隔
*/
private static final int TIME_DELAY = 500;
/**
* 滑动最小距离
*/
private static final int MIN_MOVE_DPI = 10;
/**
* 缩放的scale
*/
private static final float SMALL_SCALE = 0.95f;
/**
* 初始scale
*/
private static final float ONE_SCALE = 1f;
/**
* 判断缩小动画有没有执行过
*/
private boolean hasDoneAnimation;
/**
* 点击事件监听
*/
private OnClickListener listener;
/**
* 开始动画
*/
private AnimatorSet beginAnimatorSet;
/**
* scale返回动画
*/
private AnimatorSet backAnimatorSet;
private int downX;
private int downY;
private long lastClickTime;
public CTripHomeScaleView(Context context) {
this(context, null);
}
public CTripHomeScaleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CTripHomeScaleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAnimation();
}
/**
* Init scale animation
*/
private void initAnimation() {
ObjectAnimator beginXAnimation = ObjectAnimator.ofFloat(this, "scaleX", ONE_SCALE, SMALL_SCALE).setDuration(DURATION);
beginXAnimation.setInterpolator(new LinearInterpolator());
ObjectAnimator beginYAnimation = ObjectAnimator.ofFloat(this, "scaleY", ONE_SCALE, SMALL_SCALE).setDuration(DURATION);
beginYAnimation.setInterpolator(new LinearInterpolator());
ObjectAnimator backXAnimation = ObjectAnimator.ofFloat(this, "scaleX", SMALL_SCALE, ONE_SCALE).setDuration(DURATION);
backXAnimation.setInterpolator(new LinearInterpolator());
ObjectAnimator backYAnimation = ObjectAnimator.ofFloat(this, "scaleY", SMALL_SCALE, ONE_SCALE).setDuration(DURATION);
backYAnimation.setInterpolator(new LinearInterpolator());
beginAnimatorSet = new AnimatorSet();
beginAnimatorSet.play(beginXAnimation).with(beginYAnimation);
backAnimatorSet = new AnimatorSet();
backAnimatorSet.play(backXAnimation).with(backYAnimation);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
/**
* 判断是不是快速点击
*/
if (isFastClick()) {
return true;
}
/**
* 请求父类不要拦截我的事件,意思是让我来处理接下来的滑动或别的事件
*/
getParent().requestDisallowInterceptTouchEvent(true);
downX = (int) event.getX();
downY = (int) event.getY();
hasDoneAnimation = false;
post(new Runnable() {
@Override
public void run() {
beginAnimatorSet.start();
}
});
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) event.getX();
int moveY = (int) event.getY();
int moveDistanceX = Math.abs(moveX) - downX;
int moveDistanceY = Math.abs(moveY) - downY;
/**
* 这里是判断是向左还是向右滑动,然后用view的宽度计算出一个距离compareWidth,当滑动距离超出compareWidth时,需要执行返回动画.
*/
int compareWidth = moveDistanceX > 0 ? getWidth() - downX : downX;
/**
* 第一个条件:判断向上或向下滑动距离大于滑动最小距离
* 第二个条件:判断向左或向右的滑动距离是否超出(compareWidth-最小距离)
* 第三个条件:判断有没有执行过返回动画并在执行过一次后置为true.
*/
if ((Math.abs(moveDistanceY) > dip2px(MIN_MOVE_DPI) || Math.abs(moveDistanceX) >= compareWidth - dip2px(MIN_MOVE_DPI)) && !hasDoneAnimation) {
/**
* 一 只要满足上述条件,就代表用户不是点击view,而是执行了滑动操作,这个时候我们就需要父类以及我们的最上层的控件来
* 拦截我们的事件,让最外层控件处理接下来的事件,比如scrollview的滑动.
* 二 因为我们执行了滑动操作,所以要执行view的返回动画
*/
getParent().requestDisallowInterceptTouchEvent(false);
hasDoneAnimation = true;
post(new Runnable() {
@Override
public void run() {
backAnimatorSet.start();
}
});
}
break;
case MotionEvent.ACTION_UP:
/**
* 这里如果我们是单纯的点击事件就会执行
*/
if (!hasDoneAnimation) {
hasDoneAnimation = true;
post(new Runnable() {
@Override
public void run() {
backAnimatorSet.start();
}
});
post(new Runnable() {
@Override
public void run() {
/**
* 接口回调点击事件
*/
if (listener != null) {
listener.onClick(CTripHomeScaleView.this);
}
}
});
}
break;
}
return true;
}
public void setOnClickListener(OnClickListener l) {
listener = l;
}
public interface OnClickListener {
void onClick(View v);
}
/**
* Make dp to px
*
* @param dipValue dp you need to change
* @return Get px according to your dp value.
*/
public int dip2px(float dipValue) {
final float scale = getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* Judge is fast click event.
*
* @return Is fast click or not.
*/
public boolean isFastClick() {
long time = System.currentTimeMillis();
long timeD = time - lastClickTime;
if (timeD < TIME_DELAY) {
return true;
} else {
lastClickTime = time;
return false;
}
}
}
总结:代码量不多,主要的逻辑是在处理view的onTouch事件时,注释在代码里写的还算清晰,所以这里就不在做赘述了,不懂的童鞋可以在下面留言,或者可以发邮件:kuangxiaoguo@163.com。
Android携程高级用法,Android真正仿携程首页view实现相关推荐
- android工具am的用法,Android am/pm命令用法
am命令的参数介绍: usage: am [subcommand] [options] start an Activity: am start [-D] -D: enable debugging se ...
- android五大布局的用法,android:stretchColumns用法
TableLayout是一个使用复杂的布局,最简单的用法就仅仅是拖拉控件做出个界面,但实际上,会经常在代码里使用TableLayout,例如做出表格的效果.本文主要介绍TableLayout的基本使用 ...
- android工具am的用法,Android中AM、PM、dumpsys命令使用总结
在平时开发中,通过命令行有时候能够快速的帮我们实现一些功能,这里对常用的命令做一些总结. 1.AM命令用法 1.1.简单介绍 am指令是 activity manager的缩写,可以启动Service ...
- android中tag的用法,Android中setTag的用法
首先我们要知道setTag 是干什么的,官方给的api解释是: Tags Unlike IDs,tags are not used to identify views,Tags are essenti ...
- android 携程日历控件,仿携程酒店日历组件for小程序
仿携程酒店日历 接受日历组件开发之前,本来是拒绝的,日历组件,表单组件绝逼是前端开发的一个噩梦,尤其要做好一个旅游项目的日历,产品的收货标准只有一条,你看携程都实现了哦, MMP的.要在小程序中实现携 ...
- android 携程页面,android 仿携程首页源码(自定义button)
[实例简介] [实例截图] [核心代码] package com.example.xiechengdemo; import android.content.Context; import androi ...
- Android列表用法之二:实战ListView高级用法
在我们的项目中,并不是所有列表都是简单的使用.类似于新闻列表.QQ聊天列表等,具有图文并排的列表,每个item都有它不同的布局类型,都有其不同的实现方式.这类复杂的列表表现形式,在各类知名应用当中,不 ...
- (转)Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[-] ValueAnimator的高级用法 ObjectAnimator的高级用法 转载请注明出处:http://blog.csdn.ne ...
- android 属性动画实例,Android属性动画完全解析 中 ,ValueAnimator和ObjectAnimator的高级用法...
大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画进行了 ...
最新文章
- MySQL is running but PID file is not found
- PHP聚微商货源网源码
- 2021年中国单硝酸异山梨酯市场趋势报告、技术动态创新及2027年市场预测
- 观看杨老师(杨旭)Asp.Net Core MVC入门教程记录
- 开关电源和LDO的区别
- ucore Lab 1 系统软件启动过程
- UBUNTU内核升级后,如何更新 kernel headers
- HDU 4415 Assassin’s Creed 苦逼的贪心
- 百练1724ROADS
- 滚动抽奖html怎么做的,抽奖.html
- Minkowski不等式
- 原来3DMAX入门应该这样学!
- 如何成为优秀的前端程序员?
- 大理石在哪【搜索排序】
- Python一些可能用的到的函数系列11 本地哈希和服务器哈希比对
- java单元测试自动生成测试用例插件diffblue cover和evosuite
- android迅雷包名,迅雷(com.xunlei.downloadprovider) - 7.21.1.7474 - 应用 - 酷安
- 基于HTML的SEO
- C#实现具有Aero效果的窗体
- 量化交易策略六_动量和反转策略