Android 3.0系统上 解密GMail动画_gmail 3.0 安卓-程序员宅基地

技术标签: Android  

3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中又引入了一个新的动画系统:property animation,这三种动画模式在SDK中被称为property animation,view animation,drawable animation。

这篇文章主要使用ObjectAnimator来实现动画的效果。

使用ObjectAnimator这个对象限制性比较多,要满足一定的条件才可以使用,不然动画没有效果。ObjectAnimator继承ValueAnimator,其实就是指定一个对象以及该对象的一个属性,当属性值计算完成自动设置该对象的相关属性,即完成propety Antimation的全部两个操作。

条件为:

1.对象应该有get<属性名> ;set<属性名>方法。

2.ofInt或者ofFloat方法第一个参数是对象名,第二个参数是属性值,后面的参数为可变参数,如果可变参数为1个值,会假定目的值,获取当前值会调用get<属性值>这个方法。

这边用一个简单的例子实现这个动画

首先有3个xml,一个主Activity的main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/l1"
    android:baselineAligned="false" >
    <FrameLayout
        android:id="@+id/fragment1"
        android:layout_width="300dp"
        android:background="#FF0000"
        android:layout_height="fill_parent" />
    <FrameLayout
        android:id="@+id/fragment2"
        android:layout_width="980dp"
        android:background="#00FF00"
        android:layout_height="fill_parent" />
</LinearLayout>
然后定义一个f1.xml和f2.xml作为fragment1和fragment2的布局,然后替换main.xml中的framelayout1和framgelayout2。fragment的操作,大家在网上一搜一大片,怎么使用就不讲了。

f1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#30000000"
    android:gravity="center"
    android:baselineAligned="false" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:text="F1" />
</LinearLayout>

f2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:baselineAligned="false" >
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="go" />
</LinearLayout>
fragment1.java

public class Fragment1 extends Fragment {
    public static Fragment1 newInstance() {
        return new Fragment1();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.f1, container, false);
        return root;
    }
}
fragment2.java

public class Fragment2 extends Fragment {

    private WeakReference<FragmentResultListener> mFragmentResultListenerRef;

    public interface FragmentResultListener {
        public void onBtnClick();
    }

    public static Fragment2 newInstance(FragmentResultListener listener) {
        Fragment2 f = new Fragment2();
        f.setFragmentResultListener(listener);
        return f;
    }

    private void setFragmentResultListener(FragmentResultListener listener) {
        mFragmentResultListenerRef = new WeakReference<FragmentResultListener>(listener);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.f2, container, false);
        root.findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentResultListener fragmentResultListener = mFragmentResultListenerRef.get();
                if (fragmentResultListener != null) {
                    fragmentResultListener.onBtnClick();
                }
            }
        });
        return root;
    }
}

这边实现动画的操作需要点击fragment2中的按钮,所以这边使用了回调,先在fragment2中定义个点击的接口,然后再把接口的方法放在按钮的监听事件里面,然后外边调用的时候实现接口的操作,把接口对象传递过来就ok了。

这边是主要的程序,也是主Acitvity的实现逻辑,动画的定义,都在里面。

public class FragmentAnimationTestActivity extends Activity implements Fragment2.FragmentResultListener {

    private static final TimeInterpolator sCollapseInterpolator = new DecelerateInterpolator(2.5F);

    private View mPanel1;
    private View mPanel2;
    private View mLayout;

    boolean isCollapsed;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mLayout = findViewById(R.id.l1);
        mPanel1 = findViewById(R.id.fragment1);
        mPanel2 = findViewById(R.id.fragment2);
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.fragment1, Fragment1.newInstance(), "f1");
        ft.replace(R.id.fragment2, Fragment2.newInstance(this), "f2");
        ft.commit();
    }

    public int getPanelLeft() {
        return ((ViewGroup.MarginLayoutParams) mLayout.getLayoutParams()).leftMargin;
    }

    public void setPanelLeft(int paramInt) {
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mLayout.getLayoutParams();
        lp.leftMargin = paramInt;
        mLayout.setLayoutParams(lp);
    }

    public int getPanel2W() {
        return ((ViewGroup.MarginLayoutParams) mPanel2.getLayoutParams()).width;
    }

    public void setPanel2W(int paramInt) {
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mPanel2.getLayoutParams();
        lp.width = paramInt;
        mPanel2.setLayoutParams(lp);
    }

    @Override
    public void onBtnClick() {
        if (isCollapsed) {
            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[2];
            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofInt("PanelLeft", -300, 0);
            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofInt("Panel2W", 1280, 980);
            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
                    arrayOfPropertyValuesHolder).setDuration(400);
            localObjectAnimator.setInterpolator(sCollapseInterpolator);
            localObjectAnimator.start();
        } else {
            PropertyValuesHolder[] arrayOfPropertyValuesHolder = new PropertyValuesHolder[2];
            arrayOfPropertyValuesHolder[0] = PropertyValuesHolder.ofInt("PanelLeft", 0, -300);
            arrayOfPropertyValuesHolder[1] = PropertyValuesHolder.ofInt("Panel2W", 980, 1280);
            ObjectAnimator localObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
                    arrayOfPropertyValuesHolder).setDuration(400);
            localObjectAnimator.setInterpolator(sCollapseInterpolator);
            localObjectAnimator.start();
        }
        isCollapsed = !isCollapsed;
    }

上面主要使用了ObjectAnimator动画对象,其中ofInt使用了“panelLef'和”panel2W“这2个属性,这2个属性的set和get方法以及ofInt的使用。条件已经满足可以使用ObjectAnimaor对象。

上面还使用一个对象TimeInterplator,这个属相定义了属性值变化的范围,如线性均匀变化,开始慢然后快等等。timeInterplator是propertyAnimation中使用,在这边列举一些简单的实现对象。

  • AccelerateInterpolator        加速,开始时慢中间加速
  • DecelerateInterpolator       减速,开始时快然后减速
  • AccelerateDecelerateInterolator  先加速后减速,开始结束时慢,中间加速
  • AnticipateInterpolator      反向 ,先向相反方向改变一段再加速播放
  • AnticipateOvershootInterpolator  反向加超越,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值
  • BounceInterpolator       跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
  • CycleIinterpolator         循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)
  • LinearInterpolator        线性,线性均匀改变
  • OvershottInterpolator        超越,最后超出目的值然后缓慢改变到目的值
  • TimeInterpolator          一个接口,允许你自定义interpolator,以上几个都是实现了这个接口

    后面再把这三种动画对象的区别讲解下吧。

    相关知识参考:

    http://www.open-open.com/lib/view/open1329994048671.html

    http://android.amberfog.com/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lonely_fireworks/article/details/7943221

智能推荐

size_t和int的区别-程序员宅基地

size_t与平台无关,int与平台有关,size_t无符号,int有符号。一般情况下size_t和int可以通用,但最好用size_t

Python爬虫学习笔记_DAY_13_Python爬虫之urllib库的基本使用(中)【Python爬虫】_跳探戈的小龙虾的博客-程序员宅基地

目录I.定制请求:请求头II.GET请求的爬虫操作I.定制请求:请求头首先,承接上一次的内容,我们可以爬取百度首页的源码,当时的url是这样的:http://www.baidu.com当我们想要爬取带有SSL加密协议的url时,例如这样的url:https://www.baidu.com此时需要定制我们的请求,也即要开始伪装,下面介绍最基本是一种伪装的方式,也即添加请求头:# 请求对象的定制:为了解决反爬虫的第一种手段url = 'https://www.ba

2018整理最全的100道Redis面试题!转自(风云社区:www.scoee.com)_风云社区(scoee)-程序员宅基地

以下内容转自风云社区:www.scoee.com1、什么是Redis?Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。 Redis的出色之处不仅..._风云社区(scoee)

iOS集成IJKPlayer编译 FFmpeg编译 播放视频有画面没有声音 IJKPlayer AC3_ijkplayer没有声音_天空好像要下雨的博客-程序员宅基地

IJKPlayer集成,ffmpeg编译,部分MP4视频播放有画面没有声音,IJKPlayer支持AC3_ijkplayer没有声音

jenkins 运行守护进程_jenkins守护进程_40kuai的博客-程序员宅基地

如果您的构建想要让守护程序在后面运行…实现此目的的便捷方法是更改​​Jenkins的ProcessTreeKiller正在寻找的环境变量BUILD_ID。这将使Jenkins假定您的守护进程不是由Jenkins构建生成的。例如:BUILD_ID=dontKillMe /usr/apache/bin/httpd如果是Jenkins Pipeline,请使用JENKINS_NODE_COOKIE代替BUILD_ID..._jenkins守护进程

eclipse快速定位到错误处-程序员宅基地

见:http://blog.csdn.net/howlaa/article/details/8923900?_t_t_t=0.9804393942499768以前都是按着滚动条往下拉,找到错误的地方,有时比较多的时候就很麻烦。其实eclipse是可以直接快速定位的,CTRL+.(点)。试试看。反正我的行。哈哈....

随便推点

linux修复mysql_Linux下修复损坏的MySQL数据库_唐枫燃的博客-程序员宅基地

在Linux下由于断电或非正常关机而导致MySQL数据库出现错误是非常常见的问题。MySQL分别针对不同的数据表类型提供了多个数据检测恢复工具,这些工具是:myisamchkisamchk其中myisamchk适用于MYISAM类型的数据表,而isamchk适用于ISAM类型的数据表。这两条命令的主要参数相同,一般新的系统都使用MYISAM作为缺省的数据表类型,这里以myisamchk为例子进行说..._linux修复mysql补丁

(转载)【笨木头Lua专栏】基础补充15:也许很强大的__newindex元方法-程序员宅基地

好吧,我写文章的进度已经赶不上看书的进度了,简单的几段文字就够我唠叨一篇文章了。今天继续来说说元方法,与__index有点相似的__newindex元方法。笨木头花心贡献,哈?花心?不,是用心~转载请注明,原文地址:http://www.benmutou.com/archives/1777文章来源:笨木头与游戏开发1.查询与更新上一篇文章我们介绍了...

CTF自学笔记_ctf笔记-程序员宅基地

CTF自学笔记第一章:课程介绍与环境搭建1.课程介绍2.环境搭建第二章:CTF训练 SSH服务1.CTF-SSH私钥泄露信息探测分析探测结果探测大端口的信息第一章:课程介绍与环境搭建1.课程介绍CTF比较中涉及内容比较复杂,我们要利用所有可以利用的资源获取flag。2.环境搭建安装软件:(都是数据库软件)vmware workstation 14Virtual box测试靶场网络环境:1.使用 netdiscover -r ip/netmask 嗅探靶场IP(例:netdiscove_ctf笔记

基于知识图谱的知识推理_知识图谱推理的几种方式_lsz冲呀的博客-程序员宅基地

论文笔记整理:知识图谱,NLP方向本文是一篇综述性的文章,主要是关于基于知识图谱推理的最新研究进展与主要方法介绍。知识推理知识推理的定义分类:本文将知识图谱推理分为三类:1.基于规则的推理2.基于分布式表示的推理3.基于神经网络的推理模型总结下面主要关注基于逻辑规则的知识推理:1.一阶谓词逻辑规则:搜索KG中的所有关系,并获取每个关系的Horn子句集作为预测对应是否存在的特征模式;2.规则:基于规则的知识推理模型的基本思想是通过应用简单的规则或统计特征对._知识图谱推理的几种方式

什么好的计算机专业的专A院校,2010山东职高生,高考服装专业325分,能上啥学校?..._姜兴的博客-程序员宅基地

就上大学网为您推荐类似问题答案问题1:2010广东高考理科517分能上啥学校啊?各位大侠帮帮忙,谢专A,老兄我们同病相啊!问题2:2009高考150-200分能上啥学校,我山东的,哪位大哥帮忙啊像你这种分数 统招是没有希望的了 只能选择一些计划外的专 本学校就读了 如果有意向来北京这边的话 我给你个计划外院校咨询老师的Q Q 你向他了解吧 并让他为你推荐一所适合 你的优势院校 9 4 4 5 1 ..._专a是什么

windows中oracle自动备份_oracle自动备份 windows-程序员宅基地

一、创建一个目录,比如:oraclebackup二、创建一个txt,比如:beifen.txt三、在txt中写入备份脚本(网上参考的0.0):@echo off echo ================================================ echo Windows环境下Oracle11.2g数据库的自动备份脚本 echo 1. 使用..._oracle自动备份 windows