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. scrapy之downloader执行流程

    Agent = client.Agent class ScrapyAgent(object): _Agent = Agent#为twisted的client.Agent类 _ProxyAgent = ...

  2. 白鹭引擎 - 资源文件的加载 ( RES, loadConfig, loadGroup )

    class Main extends egret.DisplayObjectContainer { public constructor() { super(); this.addEventListe ...

  3. hadoop的client搭建-即集群外主机访问hadoop

    1增加主机映射(与namenode的映射一样): 增加最后一行  [root@localhost ~]# su - root1 [root@localhost ~]# vi /etc/hosts 12 ...

  4. CRC16-CCITT C语言代码

    代码如下,使用空间换时间的方法 #define CRC16_CCITT_SEED 0xFFFF // 该位称为预置值,使用人工算法(长除法)时 需要将除数多项式先与该与职位 异或 ,才能得到最后的除数 ...

  5. golang执行shell命令

    ommand := "echo hello” cmd := exec.Command("/bin/bash", "-c", command) byte ...

  6. sql server 查看对象最后修改时间

    sql server 查看对象最后修改时间,根据最后修改时间排序 存储过程 SELECT * FROM sys.all_objects WHERE  TYPE='P' ORDER BY modify_ ...

  7. Installing PHP5 on Ubuntu Server

    When installing PHP 5 from source I ran into the following problems and solutions: Problem:configure ...

  8. php中显示数组与对象的实现代码

    1. 使用 print_r ( $array/$var ) print 是打印的意思,而r则取自Array的单词,那么该函数的功能就是打印数组内容,它既可以打印数组内容,也可以打印普通的变量. pri ...

  9. 【Noip模拟 20161005】公约数

    问题描述 小ww最近仔细研究了公约数,他想到了以下问题:现有nn个正整数,从中选k(2≤k≤n)k(2≤k≤n) 个,设这kk个数的最大公约数为gg,则这kk个数的价值为k×gk×g.求这个价值的最大 ...

  10. 处于ESTABLISHED 状态的socket 却没有进程信息

    接<一次docker中的nginx进程响应慢问题定位记录> 在排查这个问题的时候,我先使用netstat 去查看,看到底是内核协议栈的连接请求没给到进程,还是进程accept链路慢了,或者 ...