上一个效果图:

====================================

先上布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" > <RelativeLayout
android:id="@+id/red"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/switch2blue"
android:layout_centerHorizontal="true"
android:text="首页" /> <Button
android:id="@+id/switch2blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="置换位蓝色" />
</RelativeLayout> <RelativeLayout
android:id="@+id/blue"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0000ff" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/switch2red"
android:layout_centerHorizontal="true"
android:text="第二页" /> <Button
android:id="@+id/switch2red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="置换位红色" />
</RelativeLayout> </RelativeLayout>

代码:

import java.lang.reflect.Field;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.TranslateAnimation;
import android.view.animation.Animation.AnimationListener;
import android.widget.Button;
import android.widget.RelativeLayout; public class MainActivity extends Activity implements OnClickListener,
OnTouchListener, OnGestureListener { private RelativeLayout red, blue;
private Button switch2blue, switch2red; private float thisDelta = 0.05f;
private static boolean hasEverPulled = false;
private boolean pulled = false;
private static int height;
private GestureDetector gestureDetector;
private static int statusHeight = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); DisplayMetrics metrics = getResources().getDisplayMetrics();
height = metrics.heightPixels; statusHeight = getStatusHeight(); initView(); // 跳动提示可以上拉
final Handler handler = new Handler();
handler.postDelayed(new Runnable() { @Override
public void run() {
jump(thisDelta);
// handler.postDelayed(this, 3000);
}
}, 3000); } private void initView() {
red = (RelativeLayout) findViewById(R.id.red);
blue = (RelativeLayout) findViewById(R.id.blue); switch2blue = (Button) findViewById(R.id.switch2blue);
switch2red = (Button) findViewById(R.id.switch2red); switch2blue.setOnClickListener(this);
switch2red.setOnClickListener(this);
blue.setOnTouchListener(this);
blue.setLongClickable(true);
gestureDetector = new GestureDetector(this, this);
} @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.switch2blue: red2BlueUI();
break; case R.id.switch2red:
blue2RedUI();
break;
}
} // 从红页面转到蓝页面
private void red2BlueUI() {
blue.bringToFront();
blue.requestLayout();
blue.invalidate();
} // 从蓝页面转到红页面
private void blue2RedUI() {
red.bringToFront();
red.requestLayout();
red.invalidate();
} // 获取状态栏的高度
private int getStatusHeight() {
Class<?> c = null;
Object obj = null;
Field field = null;
int x = 0;
int height = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
height = getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
} return height;
} // 主页面跳动
private void jump(float delta) {
if (thisDelta - 0.03f < 0.001f) {
thisDelta = 0.05f;
return;
}
thisDelta = delta; if (hasEverPulled) {
return;
}
playJumpAnimation(thisDelta);
} // 上拉/下拉主页面
private void pull(boolean upward) {
if (upward && pulled) {
return;
}
if (!upward && !pulled) {
return;
} float originalY;
float finalY;
if (!pulled) {
originalY = 0;
finalY = (float) (0 - height + 0.4 * height);
} else {
originalY = (float) (0 - height + 0.4 * height);
finalY = 0;
}
pulled = !pulled; AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(new TranslateAnimation(0, 0, originalY,
finalY)); animationSet.setDuration(300);
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.setFillAfter(true); animationSet.setAnimationListener(new AnimationListener() { @Override
public void onAnimationStart(Animation animation) {
if (!pulled) {
red2BlueUI();
}
} @Override
public void onAnimationRepeat(Animation animation) { } @Override
public void onAnimationEnd(Animation animation) {
// if (pulled) {
// blue2RedUI();
// }
}
}); blue.startAnimation(animationSet); hasEverPulled = true;
} // 跳起动画
private void playJumpAnimation(final float delta) {
float originalY = 0;
float finalY = 0 - height * delta;
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(new TranslateAnimation(0, 0, originalY,
finalY)); animationSet.setDuration(300);
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.setFillAfter(true); animationSet.setAnimationListener(new AnimationListener() { @Override
public void onAnimationStart(Animation animation) {
} @Override
public void onAnimationRepeat(Animation animation) {
} @Override
public void onAnimationEnd(Animation animation) {
playLandAnimation(delta);
}
}); blue.startAnimation(animationSet);
} // 落下动画
private void playLandAnimation(final float delta) {
float originalY = 0 - height * delta;
float finalY = 0;
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(new TranslateAnimation(0, 0, originalY,
finalY)); animationSet.setDuration(200);
animationSet.setInterpolator(new AccelerateInterpolator());
animationSet.setFillAfter(true); animationSet.setAnimationListener(new AnimationListener() { @Override
public void onAnimationStart(Animation animation) {
} @Override
public void onAnimationRepeat(Animation animation) {
} @Override
public void onAnimationEnd(Animation animation) {
jump(0.03f);
}
}); blue.startAnimation(animationSet);
} @Override
public boolean onDown(MotionEvent e) {
pull(false); return false;
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// 手势滑动达到100才触发
if (e1.getY() - e2.getY() > 100) {
pull(true);
} else if (e2.getY() >= e1.getY()) {
pull(false);
} return false;
} @Override
public void onLongPress(MotionEvent e) {
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
} @Override
public void onShowPress(MotionEvent e) {
} @Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
} @Override
public boolean onTouch(View v, MotionEvent event) {
if (pulled) {
// 首张页可触控点
if (event.getY() > height * 0.4 - statusHeight) {
return false;
}
} return gestureDetector.onTouchEvent(event);
}
}

Android之一种很有趣的界面跳动提示动画的更多相关文章

  1. Android学习系列(23)--App主界面实现

    在上篇文章<Android学习系列(22)--App主界面比较>中我们浅略的分析了几个主界面布局,选了一个最大众化的经典布局.今天我们就这个经典布局,用代码具体的实现它. 1.预览图先看下 ...

  2. Android系统编程入门系列之界面Activity绘制展示

    上篇文章介绍了界面Activity的启动方式和生命周期,本篇将继续介绍在界面Activity中的内容是如何绘制展示给用户的. 在Android系统上运行新创建的界面Activtiy,给用户展示的是空白 ...

  3. Android 三种动画详解

    [工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.点我开始Android技术交流] 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让 ...

  4. Android五种数据存储方式

    android 五种数据存储 :SharePreferences.SQLite.Contert Provider.File.网络存储 Android系统提供了四种存储数据方式.分别为:SharePre ...

  5. (转) 机器学习很有趣Part6:怎样使用深度学习进行语音识别

    本文转自:http://www.jiqizhixin.com/article/2321 机器学习很有趣Part6:怎样使用深度学习进行语音识别 2017-02-19 13:20:47    机器学习  ...

  6. iOS中三种方式实现登录界面播放视频或gif效果

    现在app都做的越来越炫酷,各种动画效果,各种特效很好的提高了用户的体验.很多app在登录界面都使用了动画效果,比如Uber,Keep,QQ等等.这些动画效果基本都是使用gif或者MP4来实现的. 效 ...

  7. Android studio 开发一个用户登录界面

    Android studio 开发一个用户登录界面 activity_main.xml <?xml version="1.0" encoding="utf-8&qu ...

  8. Android 四种加载方式详解(standard singleTop singleTask singleInstance) .

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  9. Android系统编程入门系列之界面Activity响应丝滑的传统动画

    上篇文章介绍了应用程序内对用户操作响应的相关方法位置,简单的响应逻辑可以是从一个界面Activity跳转到另一个界面Activity,也可以是某些视图View的相对变化.然而不管是启动一个界面执行新界 ...

随机推荐

  1. 无root或sudo权限,安装mysql

    这其实才是真正的linux,恰当使用权限. 网上找到的中文博客,基本上就那么几篇原创,都要编译源码.但89服务器性能太差编译一次大约半小时无法忍受,在本机上创建了standard用户去尝试几篇博客所言 ...

  2. T-SQL语句4

    一.插入数据 1.insert语句介绍 insert into table_name(column1,column2……column)values(value1,value2,……valueN)//c ...

  3. 《Java多线程编程核心技术》学习笔记

    第2章 对象及变量的并发访问 2.1 synchronized同步方法 方法内的变量为线程安全: 方法内部的变量是线程私有的 方法中有一个变量num,后面对它赋值 两个线程同时调用这个方法,对其赋不同 ...

  4. VisualSVN Server搭建SVN服务器<转>

    使用 VisualSVN Server来搭建本地的代码管理库是非常方便的.svn的那些“检查修改”.“代码版本自由回滚”.“版本日志”等等很多比较牛逼的功能. 在开发当中可谓是理想的开发助手.而且人脑 ...

  5. curl命令大全

    curl 命令行工具的使用及命令参数说明 curl是一个开源的用于数据传输的命令行工具与库,它使用URL语法格式,支持众多传输协议,包括:HTTP.HTTPS.FTP.FTPS.GOPHER.TFTP ...

  6. java的线程安全、单例模式、JVM内存结构等知识学习和整理

    知其然,不知其所以然 !在技术的海洋里,前路漫漫,我一直在迷失着自我. 欢迎访问我的csdn博客,我们一同成长! "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!" 博 ...

  7. Xamarin iOS教程之显示和编辑文本

    Xamarin iOS教程之显示和编辑文本 Xamarin iOS显示和编辑文本 在一个应用程序中,文字是非常重要的.它就是这些不会说话的设备的嘴巴.通过这些文字,可以很清楚的指定这些应用程序要表达的 ...

  8. 【BZOJ 1061】 1061: [Noi2008]志愿者招募 (线性规划与网络流)**

    1061: [Noi2008]志愿者招募 Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短 ...

  9. AFO 我的oi生涯 大结局

    今儿个哥几个一屋子退役了,这两天也许会写一个生涯大结局留作纪念吧. 今天就写了吧. 由于在机房的原因比一般同学获得的知识更多一些.进来总是看新闻,感慨颇多.自从两会开的第一天起,我就对我们政府采取的一 ...

  10. vuessr nuxt入门指南

    nuxt.js 官网地址:https://zh.nuxtjs.org/guide/installation 1.安装 vue init nuxt-community/starter-template ...