package com.ifenglian.superapp1;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout; /**
* 可上下拖动且有浮沉动画的View
* create by shixm on 2017/5/17 15:11
*/
public class SHDrawerAnimLayerLayout extends FrameLayout { private static final String OBJECT_ANIMATION_PROPERTY_NAME = "translationY"; // 可拖动的顶部View
private View viewTopDragView;
// 可拖动的底部View
private View viewBottomDragView; // View在关状态,露出的高度
private int viewVisibleHeight = 50;
// 可识别触摸事件的高度
private int touchHeight = 50;
// 顶部View偏移Y
private int topViewTranslationY;
// 底部View偏移Y
private int bottomViewTranslationY;
// 顶部View是否在触摸范围
private boolean isTopViewInRect;
// 底部View是否在触摸范围
private boolean isBottomViewInRect; public SHDrawerAnimLayerLayout(Context context, View topView, View bottomView) {
this(context);
setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
addView(topView);
addView(bottomView);
viewTopDragView = topView;
viewBottomDragView = bottomView;
viewTopDragView.setAlpha(1);
viewBottomDragView.setAlpha(0);
} public SHDrawerAnimLayerLayout(Context context) {
super(context, null);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
topViewTranslationY = - viewVisibleHeight;
viewTopDragView.setY(topViewTranslationY);
bottomViewTranslationY = viewVisibleHeight;
viewBottomDragView.setY(bottomViewTranslationY);
} @Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float downX = event.getX();
float downY = event.getY();
if (!isInTopViewRect(downX, downY)) {
isTopViewInRect = false;
} else {
isTopViewInRect = true;
}
if (!isInBottomViewRect(downX, downY)) {
isBottomViewInRect = false;
} else {
isBottomViewInRect = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (isTopViewInRect) {
float moveY = event.getY();
if (moveY >= 0 && moveY < getHeight()) {
viewTopDragView.setY(-getHeight() + moveY);
float alpha = moveY / getHeight();
viewTopDragView.setAlpha(alpha);
viewBottomDragView.setAlpha(1 - alpha);
}
}
if (isBottomViewInRect) {
float moveY = event.getY();
if (moveY >= 0 && moveY < getHeight()) {
viewBottomDragView.setY(moveY);
float alpha = moveY / getHeight();
viewTopDragView.setAlpha(alpha);
viewBottomDragView.setAlpha(1 - alpha);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (isTopViewInRect) {
if (viewTopDragView.getTranslationY() < -getHeight() / 2) {
topViewScrollToTop();
} else {
topViewScrollToBottom();
}
isTopViewInRect = false;
}
if (isBottomViewInRect) {
if (viewBottomDragView.getTranslationY() < getHeight() / 2) {
bottomViewScrollToTop();
} else {
bottomViewScrollToBottom();
}
isBottomViewInRect = false;
}
break;
}
return true;
} private void bottomViewScrollToTop() {
ObjectAnimator topAnimation = ObjectAnimator.ofFloat(viewBottomDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewBottomDragView.getTranslationY(), viewVisibleHeight);
topAnimation.start();
} private void topViewScrollToTop() {
ObjectAnimator topAnimation = ObjectAnimator.ofFloat(viewTopDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewTopDragView.getTranslationY(), -getHeight() + viewVisibleHeight);
topAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
ObjectAnimator.ofFloat(viewTopDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewTopDragView.getTranslationY(), -viewVisibleHeight).setDuration(0).start();
viewTopDragView.setAlpha(0);
}
});
topAnimation.start();
} private void bottomViewScrollToBottom() {
ObjectAnimator bottomAnimation = ObjectAnimator.ofFloat(viewBottomDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewBottomDragView.getTranslationY(), getHeight() - bottomViewTranslationY);
bottomAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
viewBottomDragView.setAlpha(0);
ObjectAnimator.ofFloat(viewBottomDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewBottomDragView.getTranslationY(), bottomViewTranslationY).setDuration(0).start();
viewTopDragView.setAlpha(1);
}
});
bottomAnimation.start();
} private void topViewScrollToBottom() {
ObjectAnimator bottomAnimation = ObjectAnimator.ofFloat(viewTopDragView, OBJECT_ANIMATION_PROPERTY_NAME, viewTopDragView.getTranslationY(), (topViewTranslationY));
bottomAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
viewBottomDragView.setAlpha(0);
viewTopDragView.setAlpha(1);
}
});
bottomAnimation.start();
} private boolean isInTopViewRect(float downX, float downY) {
if (downX > viewTopDragView.getLeft() && downX < viewTopDragView.getRight()) {
if (downY >= viewTopDragView.getTranslationY() + getHeight() - touchHeight && downY <= viewTopDragView.getTranslationY() + getHeight()) {
return true;
}
}
return false;
} private boolean isInBottomViewRect(float downX, float downY) {
if (downX > viewBottomDragView.getLeft() && downX < viewBottomDragView.getRight()) {
if (downY >= viewBottomDragView.getTranslationY() && downY <= touchHeight + viewBottomDragView.getTranslationY()) {
return true;
}
}
return false;
}
} 使用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); LinearLayout lin = new LinearLayout(this);
lin.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); RelativeLayout relativeLayout1 = new RelativeLayout(this);
RelativeLayout.LayoutParams reParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(this, 310));
relativeLayout1.setLayoutParams(reParams);
relativeLayout1.setBackgroundColor(Color.parseColor("#00FF00")); RelativeLayout relativeLayout2 = new RelativeLayout(this);
RelativeLayout.LayoutParams reParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dip2px(this, 310));
relativeLayout2.setLayoutParams(reParams2);
relativeLayout2.setBackgroundColor(Color.parseColor("#0000FF")); SHDrawerAnimLayerLayout dragLayout = new SHDrawerAnimLayerLayout(this, relativeLayout1, relativeLayout2);
dragLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
dragLayout.setBackgroundColor(Color.parseColor("#000000"));
lin.addView(dragLayout); lin.setBackgroundColor(Color.WHITE);
setContentView(lin);
}

可上下拖动且有浮沉动画的View的更多相关文章

  1. Android 动画基础——视图动画(View Animation)

    本篇讲android 3.0之前被广泛的动画框架——ViewAnimation. 目录 我将分为六部分来讲: 概述 Alpha透明动画 Rotate旋转动画 Translate位移动画 Scale放缩 ...

  2. *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)

    最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画.之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来: 我的开发环境是在VS2017下进行 ...

  3. 动画效果 View控件的显示和隐藏效果

    显示动画: mShowAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f,     Animation.RELATIVE_ ...

  4. 【转】2D动画:view的Matrix

    Matrix,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 首先介绍一下矩阵运算.加法和减法就不用说了,太简单了,对应位相加就好.图像处理,主要用到的是乘法 ...

  5. 在Android中动画移动一个View的位置,采用Scroller类实现Android动画之 View移动

    在Android中动画移动一个View的位置,采用Scroller类实现 今天说最近自己遇到的一个问题,就是要用动画效果来移动一个VIew的位置. 这个具体的情况是,需要做一个SlidingMenu的 ...

  6. Android 用属性动画自定义view的渐变背景

    自定义view渐变背景,同时监听手势自动生成小圆球. 宿主Activity如下: package com.edaixi.tempbak; import java.util.ArrayList; imp ...

  7. Android 动画之View动画效果和Activity切换动画效果

    View动画效果: 1.>>Tween动画通过对View的内容进行一系列的图形变换(平移.缩放.旋转.透明度变换)实现动画效果,补间动画需要使用<set>节点作为根节点,子节点 ...

  8. ios假设写一个提示带动画的View,能够来引导用户行为

    先上图: 这个UIView能够这样写: -(id)initWithFrame:(CGRect)frame backImage:(UIImage*)image msgStr:(NSString*)txt ...

  9. 每日一问:到底为什么属性动画后 View 在新位置还能响应事件

    在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...

随机推荐

  1. iframe之间通信问题及iframe自适应高度问题

    下面本人来谈谈iframe之间通信问题及iframe自适应高度问题. 1. iframe通信 分为:同域通信 和 跨域通信.所谓同域通信是指 http://localhost/demo/iframe/ ...

  2. python学习笔记_week8

    一.Socket 当服务端传的东西大于客户端的最大值时怎么办?①改大buffer不行(有上限)②多传几次(用for循环必须要知道循环几次,所以不用for循环,用while) 服务端: import o ...

  3. 2. oracle创建表空间、用户并设置默认表空间、授权

    1.创建用户并设置默认表空间 create tablespace tablespacename datafile 'tablespacename.dbf' size 200m autoextend o ...

  4. [Writeup]百度一下,你就知道

    [Writeup]百度一下,你就知道 谢邀@宋雨田 人在607,刚下床 育才上网,信号不好 实名diss,能人宋雷 ---------------------- 以下是原答案 ------------ ...

  5. https://www.52pojie.cn/thread-688820-1-1.html

    https://www.52pojie.cn/thread-688820-1-1.html

  6. 浅谈 String 的 hashCode() 方法

    Java 中 hash 值的含义 hash 值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率,如HashMap.HashTable等: 如果两个对象相同,那么这两个对象的 hash ...

  7. Vue 修改dist 目录.

    前后端分析之后,前端 打包处理 2

  8. putty登录显示IP

    登陆服务器 cd vi .bashrc 在尾部加入如下代码 if [ "$SSH_CONNECTION" != '' -a "$TERM" != 'linux' ...

  9. Linux命令:chmod

    https://baijiahao.baidu.com/s?id=1616750933810368135&wfr=spider&for=pc

  10. Linux 中的定时处理 cron服务

    cron服务 在LINUX中,周期执行的任务一般由cron这个守护进程来处理 当安装完操作系统后默认会安装此服务工具并且会自动启动crond,该进程会每分钟定期检查是否有要执行的任务,若有则执行. c ...