zoukankan      html  css  js  c++  java
  • 用开源项目ActivityOptionsICS让ActivityOptions的动画实现兼容

    我之前写过一篇文章是讲解ActivityOption的api方法的(http://www.cnblogs.com/tianzhijiexian/p/4087917.html),当时吐槽各种动画不兼容,完全无视我们4.x或者2.x用户嘛,好在有开源库来帮助我们实现动画。

    开源项目地址:https://github.com/tianzhijiexian/ActivityOptionsICS

    零、修改style

    用这些动画之前,需要对应用的style进行修改,添加一个属性

    <item name="android:windowIsTranslucent">true</item>  

        <!-- Application theme. -->
        <style name="AppTheme" parent="AppBaseTheme">
            <!-- 允许使用transitions -->  
             <item name="android:windowIsTranslucent">true</item>  
            <!-- All customizations that are NOT specific to a particular API-level can go here. -->
        </style>

    一、ActivityOptionsCompatICS

    提供了和ActivityOptions、ActivityCompat基本一致的方法来实现相同的动画效果,总共有如下方法。

    【注意】这个类必须在view都显示完成后才能使用,可以在点击事件中中或者是用post一个runnable来用。

    (1)public static ActivityOptionsCompatICS makeCustomAnimation(Context context,

    int enterResId, int exitResId)

    参数:

    enterId:进入动画的资源ID

    exitId:退出动画的资源ID

    设置自定义的Activity动画,出入的是动画资源的id。

    这个方法和overridePendingTransition(R.anim.slide_bottom_in, android.R.anim.fade_out);十分类似,传入一个进入的动画和一个退出的动画即可

        public void customAnim() {
            ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeCustomAnimation(this,
                    R.anim.slide_right_in, R.anim.slide_bottom_out);
            ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
        }

    (2)public static ActivityOptionsCompatICS makeScaleUpAnimation(View source, int startX,

    int startY, int width, int height)

    参数:

    source:一个view对象,用户确定新activity启动的初始坐标

    startX:新activity出现的初始X坐标,这个坐标是相对于source的左上角X坐标

    startY:新activity出现的初始Y坐标,这个坐标相对于source的左上角Y坐标

    width:新activity初始的宽度

    height:新activity初始的高度

    通过看源码可以很容易理解这些参数的意义

            int[] pts = new int[2];//ps = position,目的得到当前view相对于屏幕的坐标
            source.getLocationOnScreen(pts);
            // 设置起始坐标和起始宽高
            opts.mStartX = pts[0] + startX;
            opts.mStartY = pts[1] + startY;
            opts.mWidth = width;
            opts.mHeight = height;

    实现的效果是:新的Activity从某个位置以某个大小出现,然后慢慢拉伸渐变到整个屏幕

    public void scaleUpAnim(View view) {
            ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeScaleUpAnimation(view,
                     0, 0, //拉伸开始的坐标
                     view.getMeasuredWidth(), view.getMeasuredHeight());//初始的宽高
            ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
        }

    (3)public static ActivityOptionsCompatICS makeThumbnailScaleUpAnimation(View source, 

    Bitmap thumbnail, int startX, int startY) 

    参数:

    source:一个view对象,用来确定起始坐标

    thumbnail:一个bitmap对象,新的activity将通过这个bitmap渐变拉伸出现,新的activity初始大小就是这个bitmap的大小

    startX:新activity初始的X坐标,相对于source左上角的X来说的

    startY:新的activity初始的Y坐标,相对于source左上角Y坐标来说的

    效果是:一个bitmap慢慢从某个位置拉伸渐变新的activity

    public void thumbNailScaleAnim(ImageView view) {
            view.setDrawingCacheEnabled(true);
             Bitmap bitmap = view.getDrawingCache();
              ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeThumbnailScaleUpAnimation(
                view, bitmap, 0, 0);
              // Request the activity be started, using the custom animation options.
              ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
              //view.setDrawingCacheEnabled(false);
        }

    (4)public static ActivityOptionsCompatICS makeSceneTransitionAnimation(Activity activity, 

    final View sharedElement,int sharedElementId)

    参数:

    activity:当前activity的对象

    sharedElement:一个view对象,用来和新的activity中的一个view对象产生动画

    sharedElemetId:新的activity中的view的Id,这个view是用来和原始activity中的view产生动画的

    效果是:原始activity中的一个view随着新activity的慢慢启动而移动到新的activity中,实现补间动画

    public void screenTransitAnim(View v,int id) {
            ActivityOptionsCompatICS options = ActivityOptionsCompatICS.
                    makeSceneTransitionAnimation(this, v,id);
            ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
        }

    (5)public static ActivityOptionsCompatICS makeSceneTransitionAnimation(Activity activity,

    Pair<View, Integer>... sharedElements)

    参数:

    activity:当前的activity

    sharedElements:Pair对象,上面的一个方法是实现单一view的动画,这里可以有多个view对象进行动画

    screenTransitAnimByPair(
                        Pair.create((View)orginalImageView, R.id.target_imageView),
                        Pair.create((View)orginalTextView, R.id.target_textView),
                        Pair.create((View)chromeIView, R.id.target_chrome_imageView));
        @SuppressWarnings("unchecked")
        public void screenTransitAnimByPair(Pair<View, Integer>... views) {
            ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeSceneTransitionAnimation(
                    MainActivity.this, views);
            ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
        }

    二、ActivityCompatICS

    这个类仅仅提供了启动activity的方法,很简单就一个静态方法

    public static void startActivity(Activity activity, Intent intent, Bundle bundle) 

    传入的bundle是ActivityOptionsCompatICS通过toBundle()方法产生的bundle对象

    三、TransitionCompat

    这个类是用在新的activity中接收动画的,在新的activity的setContentView()后写

    TransitionCompat.startTransition(this, R.layout.activity_target);即可。

    这里的参数一个是activity对象,一个是当前activity的布局文件

    在新activity的onBackPressed()方法中写上TransitionCompat.finishAfterTransition(this);就可以实现退出时的动画了。

    当然这个类提供了各种设置方法:

         TransitionCompat.addListener(transitionListener);
            TransitionCompat.addViewAnimListener(viewAnimListener);
            TransitionCompat.setEnterTransition(new SceneFade(this, true));// use to scale Up animation
         TransitionCompat.setExitTransition(animation)//在onBackPressed中设置
    TransitionCompat.setAnimDuration(300);// default TransitionCompat.setAnimStartDelay(0);// default
         TransitionCompat.setTimeInterpolator(new AccelerateDecelerateInterpolator());// default

    1.设置屏幕动画监听器

    2.设置view动画的监听器(用于bitmap,sharedElements动画),监听器中可以得到view的对象和id

    3.设置屏幕进入时的效果,这里传入的是个继承自TransitionAnims的实现类,这个我们下面再说

    4.设置屏幕退出时的效果,这里传入的是个继承自TransitionAnims的实现类

    5.设置动画的持续时间

    6.设置动画的延迟时间

    7.设置动画的变化效果

    四、TransitionAnims

    这个TransitionAnims是一个实现屏幕动画的抽象类,里面实现了各种初始化和收尾操作,并且添加了常用的监听器。如果我们想自己对屏幕进行动画效果的设定,只需要继承这个类然后实现方法即可。

    package com.example.activityoptionsjbtest;
    
    import android.app.Activity;
    
    import com.kale.activityoptions.transition.TransitionAnims;
    
    public class SceneAnimTest extends TransitionAnims{
    
        public SceneAnimTest(Activity activity) {
            super(activity);
            // TODO 自动生成的构造函数存根
        }
    
        @Override
        public void playScreenEnterAnims() {
            // TODO 自动生成的方法存根
            
        }
    
        @Override
        public void playScreenExitAnims() {
            // TODO 自动生成的方法存根
            
        }
    
    }

    我们来看看这个类中我们可以得到什么东西。

            getActivity();//得到要启动动画的activity
            getAnimsDuration();//得到通过transitionCompatICS设置的动画持续时间
            getAnimsInterpolator();//得到通过transitionCompatICS设置的动画效果
            getBackground();//得到当前activity默认的背景图片,这个是开源项目中默认设置的,是一个#eeeeee的drawable。仅仅用于收尾操作
            getAnimsStartDelay();////得到通过transitionCompatICS设置的动画延迟时间
            //废弃//getIsEntireScreenAnim();////得到当前是否是让整个屏幕执行动画,如果不是那么就是让activity的actionbar下方的view执行动画
            getSceneRoot();//重要:执行动画的view对象。

    这里面还有一个动画监听器,我们继承这个类后可以直接用这个监听器来实现动画监听操作。比如原始项目中用于屏幕渐变操作的类就用到了这个监听器。如果不用这个监听器,那么transitionCompatICS设置的屏幕监听器是监听不到动画的。

    其中还有两个收尾方法:

    enterAnimsEnd(); // 在进入动画结束后请自行调用

    exitAnimsEnd(); // 在退出动画结束后请自行调用

    片段:

    AnimatorSet set = new AnimatorSet();
            ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(getSceneRoot(), "alpha", fromAlpha, toAlpha);
            set.addListener(new TransitionAnimsListener() {
                @Override
                public void onAnimationEnd(Animator animator) {
                    // TODO 自动生成的方法存根
                    super.onAnimationEnd(animator);
                    if (isEnter) {
                        enterAnimsEnd();
                    }else {
                        exitAnimsEnd();
                    }
                }
            });

    原始项目中使用这个类的例子(渐变效果):

    package com.kale.activityoptions.anim;
    
    import android.animation.Animator;
    import android.animation.AnimatorSet;
    import android.animation.ObjectAnimator;
    import android.app.Activity;
    
    import com.kale.activityoptions.transition.TransitionAnims;
    
    public class SceneFade extends TransitionAnims{
        
        public SceneFade(Activity activity) {
            super(activity);
            // TODO 自动生成的构造函数存根
        }
    
        public void playScreenAnims(final boolean isEnter) {
            float fromAlpha,toAlpha;
            if (isEnter) {
                fromAlpha = 0f;
                toAlpha = 1f;
            }else {
                fromAlpha = 1f;
                toAlpha = 0f;
            }
            
            // TODO 自动生成的方法存根
            AnimatorSet set = new AnimatorSet();
            ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(getSceneRoot(), "alpha", fromAlpha, toAlpha);
            set.addListener(new TransitionAnimsListener() {
                @Override
                public void onAnimationEnd(Animator animator) {
                    // TODO 自动生成的方法存根
                    super.onAnimationEnd(animator);
                    if (isEnter) {
                        enterAnimsEnd();
                    }else {
                        exitAnimsEnd();
                    }
                }
            });
            set.play(alphaAnim);
            set.setDuration(getAnimsDuration());
            set.setStartDelay(getAnimsStartDelay());
            set.setInterpolator(getAnimsInterpolator());
            set.start();
        }
        
        @Override
        public void playScreenEnterAnims() {
            // TODO 自动生成的方法存根
            playScreenAnims(true);
        }
    
        @Override
        public void playScreenExitAnims() {
            // TODO 自动生成的方法存根
            playScreenAnims(false);
        }
    
        
    }

     设置方式:

    TransitionCompat.setEnterTransition(new SceneFade(this, true));

    @Override
    public void onBackPressed() {

      TransitionCompat.setExitTransition(new SceneFade(this, true));
      // 这段代码必须放在TransitionCompat各种设置之后
      TransitionCompat.finishAfterTransition(this);
    }

    五、小例子

    MainActivity.java

    package com.example.activityoptionsjbtest;
    
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.v4.util.Pair;
    import android.support.v7.app.ActionBarActivity;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.kale.activityoptions.ActivityCompatICS;
    import com.kale.activityoptions.ActivityOptionsCompatICS;
    
    
    public class MainActivity extends ActionBarActivity {
        private ImageView chromeIView;
        private Intent intent;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            intent = new Intent(MainActivity.this, TargetActivity.class);
            chromeIView = (ImageView)findViewById(R.id.chrome_imageView);
            
        }
        public void buttonListener(View views) {
            switch (views.getId()) {
    case R.id.thumbnail_button:
                thumbNailScaleAnim(chromeIView);
                break;default:
                break;
            }
        }public void thumbNailScaleAnim(ImageView view) {
            view.setDrawingCacheEnabled(true);
             Bitmap bitmap = view.getDrawingCache();
              ActivityOptionsCompatICS options = ActivityOptionsCompatICS.makeThumbnailScaleUpAnimation(
                view, bitmap, 0, 0);
              // Request the activity be started, using the custom animation options.
              ActivityCompatICS.startActivity(MainActivity.this, intent, options.toBundle());
              //view.setDrawingCacheEnabled(false);
        }
    }

    TargetActivity.java

    package com.example.activityoptionsjbtest;
    
    import android.animation.Animator;
    import android.animation.ValueAnimator;
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.animation.AccelerateDecelerateInterpolator;
    import android.view.animation.Animation;
    
    import com.kale.activityoptions.anim.SceneFade;
    import com.kale.activityoptions.anim.ViewAnimationListenerAdapter;
    import com.kale.activityoptions.transition.TransitionCompat;
    import com.kale.activityoptions.transition.TransitionListenerAdapter;
    
    
    public class TargetActivity extends Activity{
    
        boolean isShowed = false;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO 自动生成的方法存根
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_target);// 这段代码必须放在TransitionCompatICS各种设置之后
            TransitionCompat.startTransition(this, R.layout.activity_target);
        }
        
        
        
        @Override
        public void onBackPressed() {
            //super.onBackPressed();// 这段代码必须放在TransitionCompatICS各种设置之后
            TransitionCompat.finishAfterTransition(this);
            
        }
    }

    这个项目兼容到3.1,对于2.x我试着兼容了一部分,但还有几个小问题。所以就只做了一个高版本的。毕竟目前4.x才是主流。

    下载地址https://github.com/tianzhijiexian/ActivityOptionsICS

  • 相关阅读:
    121. Best Time to Buy and Sell Stock
    分页查询
    ViewPager
    SharedPreferences
    android 动画
    display~
    stringBuffer拼接有规律字符串
    修改placehosder
    this Activity.this Activity.class
    Windows基础编程SDK复习知识点
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4128045.html
Copyright © 2011-2022 走看看