Training—Adding Animations
阅读:https://developer.android.com/training/animation/index.html
接下来学学怎么自定义动画。
首先学的是渐变,效果打开https://developer.android.com/training/animation/crossfade.html 就能看到了。
在这里假设有两个页面交错渐变替换。
首先,先获得两个view的引用,然后将要通过渐变显示的view隐藏,然后通过res文件的value来获得动画显示时间:
public class CrossfadeActivity extends Activity { private View mContentView; private View mLoadingView; private int mShortAnimationDuration; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_crossfade); mContentView = findViewById(R.id.content); mLoadingView = findViewById(R.id.loading_spinner); // Initially hide the content view. mContentView.setVisibility(View.GONE); // Retrieve and cache the system's default "short" animation time. mShortAnimationDuration = getResources().getInteger( android.R.integer.config_shortAnimTime); }
接下来,把要渐变出现的view设置为可见但是透明度被百分百,然后开始动画渐变动画。而要隐藏不见的view则开始渐变动画开始隐藏并且绑定监听器当动画结束时隐藏自己:
private View mContentView; private View mLoadingView; private int mShortAnimationDuration; ... private void crossfade() { // Set the content view to 0% opacity but visible, so that it is visible // (but fully transparent) during the animation. mContentView.setAlpha(0f); mContentView.setVisibility(View.VISIBLE); // Animate the content view to 100% opacity, and clear any animation // listener set on the view. mContentView.animate() .alpha(1f) .setDuration(mShortAnimationDuration) .setListener(null); // Animate the loading view to 0% opacity. After the animation ends, // set its visibility to GONE as an optimization step (it won't // participate in layout passes, etc.) mLoadingView.animate() .alpha(0f) .setDuration(mShortAnimationDuration) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLoadingView.setVisibility(View.GONE); } }); }
接下来学习使用ViewPagers。
首先创建基本的布局和实现,Fragment那个较为简单只有一个文本框,它的实现也很简单,直接返回。而Activity则需要使用一个带有<android.support.v4.view.ViewPager
>标签的布局,PagerAdapter 继承抽象类 FragmentStatePagerAdapter 并覆盖 getItem() 获得页面内容以及getCount获得页面数量,把PagerAdapter 勾在 ViewPager,当用户返回键的时候跳回上一页若是第一页则跳回Activity的back stack。
public class ScreenSlidePagerActivity extends FragmentActivity { /** * The number of pages (wizard steps) to show in this demo. */ private static final int NUM_PAGES = 5; /** * The pager widget, which handles animation and allows swiping horizontally to access previous * and next wizard steps. */ private ViewPager mPager; /** * The pager adapter, which provides the pages to the view pager widget. */ private PagerAdapter mPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_screen_slide_pager); // Instantiate a ViewPager and a PagerAdapter. mPager = (ViewPager) findViewById(R.id.pager); mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager()); mPager.setAdapter(mPagerAdapter); } @Override public void onBackPressed() { if (mPager.getCurrentItem() == 0) { // If the user is currently looking at the first step, allow the system to handle the // Back button. This calls finish() on this activity and pops the back stack. super.onBackPressed(); } else { // Otherwise, select the previous step. mPager.setCurrentItem(mPager.getCurrentItem() - 1); } } /** * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in * sequence. */ private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { public ScreenSlidePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return new ScreenSlidePageFragment(); } @Override public int getCount() { return NUM_PAGES; } } }
自定义动画很有趣,需要实现ViewPager.PageTransformer
的transformPage方法,不过要有好看的效果内部代码很复杂。不过下面使用了两个很好的例子进行了说明和使用。
其中position是个很重要的东西,它是针对每一个view而言的动态属性,它指的是相对于屏幕中间的位置。如果position<=-1,则说明在屏幕左边完全看不到的区域,position>=1则说明都在右边看不见的区域,如果view偏右view的值大于0,偏左则小于0.
接下来试试Card Flip.
这个例子包含了许多XML,比较特别的就是四个关于动画的XML,详细的定义内容官方文档并无说明,只是进行了大概的描述。
整个过程很简单,整个Fragment的使用和之前的教程几乎一模一样,唯一区别的地方在于,在FragmentTransaction 中使用了 setCustomAnimations(int enter, int exit),其实整个FragmentTransaction就是一个过程,而里面的参数就是之前的动画XML,setCustomAnimations定义了进入以及离开的动画。
接下来还介绍了放大缩小的动画,有兴趣的可以自行前往查看。
还有比较重要的一点就是如何动态的在view中添加删除item,很简单,只要在布局文件中的容器里添加android:animateLayoutChanges="true",并且在使用ViewGroup引用该容器,再声明完newView之后直接执行ViewGroup的addView即可。