PS: статья написана в основном для начинающих разработчиков.
Весь исходный код доступен на GitHub
Мы рассмотрим 2 вида переходных анимаций:
- анимируем старую Activity на фоне новой
- анимируем новую Activity на фоне старой
Для демонстрации были выбраны 2 типа анимации: одновременная анимация нескольких объектов (створки двери) и последовательная анимация нескольких объектов (сворачивание листа бумаги)
Анимация старой Activity
Итак, создадим 3 Activity: FirstActivity, SecondActivity и ThirdActivity.
Код FirstActivity:
first.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/click_layout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ff00" > <TextView android:layout_gravity="center" android:gravity="center" android:layout_width="wrap_content" android:layout_height="fill_parent" android:textColor="#FFFFFF" android:textSize="40sp" android:text="First" /> </LinearLayout>
FirstActivity.java:
public class FirstActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first); LinearLayout click = (LinearLayout) findViewById(R.id.click_layout); click.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bitmap bmp = getBitmap(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("picture", byteArray); startActivity(intent); overridePendingTransition(0,0); } }); } private Bitmap getBitmap(){ View root = getWindow().getDecorView().findViewById(android.R.id.content); root.setDrawingCacheEnabled(true); return root.getDrawingCache(); } }
Функция getBitmap возвращает Bitmap текущего окна. При клике по основному элементу Activity создаем новый Intent, и в качестве Extra задаем наш Bitmap, преобразованный в байтовый массив. После чего запускаем SecondActivity.
Код SecondActivity:
second.xml:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/click_layout" android:background="#ff0000" > <TextView android:layout_gravity="center" android:gravity="center" android:layout_width="wrap_content" android:layout_height="fill_parent" android:textColor="#FFFFFF" android:textSize="40sp" android:text="Second" /> <LinearLayout android:orientation="horizontal" android:weightSum="100" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_weight="50" android:layout_width="0dip" android:layout_height="fill_parent" android:id="@+id/left_image"/> <ImageView android:layout_weight="50" android:layout_width="0dip" android:layout_height="fill_parent" android:id="@+id/right_image"/> </LinearLayout> </FrameLayout>
В качестве главного элемента нашей Activity мы задаем FrameLayout, который содержит в себе 2 LinearLayout. В первом размещается весь необходимый контент(в нашем случае это TextView). Во втором находятся 2 ImageView, которые делят экран пополам. Онb необходимы нам для анимации.
Для анимации нам необходимо предпринять следующие шаги:
- Создать Bitmap из байтового массива, переданного из первыой Activity
- Разделить Bitmap на 2 части и загрузить их в соответствующий ImageView
- При помощи AnimatorSet одновременно воспроизвести анимацию поворота обоих ImageView
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second); Bundle extras = getIntent().getExtras(); byte[] byteArray = extras.getByteArray("picture"); Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); left = (ImageView) findViewById(R.id.left_image); right = (ImageView) findViewById(R.id.right_image); int centerWidth = bmp.getWidth()/2; Bitmap bmpLeft,bmpRight; bmpLeft = Bitmap.createBitmap(bmp,0,0,centerWidth,bmp.getHeight()); bmpRight = Bitmap.createBitmap(bmp,centerWidth,0,bmp.getWidth() - centerWidth,bmp.getHeight()); left.setImageBitmap(bmpLeft); right.setImageBitmap(bmpRight); ViewTreeObserver observer = left.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { left.getViewTreeObserver().removeOnPreDrawListener(this); startEnterAnimation(); return true; //To change body of implemented methods use File | Settings | File Templates. } }); }
В функции onCreate мы получаем Bitmap из Extras, делим его на 2 Bitmap при помощи Bitmap.createBitmap() и устанавливаем полученные изображения в ImageView. После этого регистрируем Observer, который будет следить за onDraw событием ImageView и вызываться только один раз перед первой отрисовкой объекта. В нем мы запускаем анимацию открытия Activity.
private void startEnterAnimation() { left.setPivotY(left.getHeight()/2); left.setPivotX(0); right.setPivotY(left.getHeight()/2); right.setPivotX(right.getWidth()); Animator leftAnim = ObjectAnimator.ofFloat(left, "rotationY", 0, 90); Animator rightAnim = ObjectAnimator.ofFloat(right, "rotationY", 0, -90); AnimatorSet set = new AnimatorSet(); set.setDuration(500); set.playTogether(leftAnim, rightAnim); set.start(); }
Непосредственно сама анимация описана в функции startEnterAnimation(). При помощи функций setPivotX() и setPivotY() мы устанавливаем точки, вокруг которых будут вращаться наши изображения. Далее мы задаем сами анимации вращения при помощи объекта ObjectAnimator.
ObjectAnimator — компонент системы, появившийся с Android 3.0. Он помогает анимировать какое-либо свойство любого объекта. В данном случае, мы анимируем свойство rotationX типа float объекта left.
Далее, мы создаем набор анимаций AnimatorSet, задаем длительность анимации в 500 мс и говорим ему, что будем одновременно проигрывать 2 анимации.
Анимация закрытия Activity задается аналогично. Для ее запуска мы переопределяем функцию Activity onBackPressed(). В ней мы запускаем анимацию закрытия, не забыв добавить listener с функцией finish().
Анимация новой Activity
Для того, чтобы анимировать новую Activity на фоне старой, нам не нужно ничего передавать в новую Activity. Нужно просто сделать фон ACtivity прозрачным. Для этого мы изменяем в файле AndroidManifest тему ThirdActivity на Transparent, и добавляем эту тему в styles.xml
<style name="Transparent"> <item name="android:windowNoTitle">true</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style>
Сам процесс анимации будет заключаться в следующем:
- при помощи наблюдателя OnPreDrawListener и функции getBitmap мы получаем Bitmap нашего Layout, после чего делаем его невидимым и запускаем анимацию открытия Activity
- делим полученный Bitmap на 4 части, устанавливаем каждую часть в соответствующий Bitmap, после чего делаем невидимыми все изображения кроме начального
- анимация открытия будет похожа на предыдущую, за исключением того, что после окончания анимации каждого куска изображения нам необходимо сделать видимым следующий кусок изображения
- ну и в конце всей анимации мы делаем видимым Layout с контентов этой Activity, а изображения скрываем
Вся анимация запускается при помощи все того-же AnimatorSet, только задаются они при помощи функции playSequentially. Это означает, что все анимации будут запускаться последовательно друг за другом.
Анимация закрытия Activity делается аналогично, только в обратном порядке.
Заключение
Мы рассмотрели 2 способа создания переходной анимации между Activity. Весь код в статье адаптирован под версию системы выше 3.0, однако его легко можно адаптировать и под более ранние версии, начиная с 1.6, при помощи библиотеки NineOldAndroids от всем известного Jake Wharton’а. Единственное, о чем хотелось бы заострить внимание — это на установке относительных точек для поворота и увеличения. В этой библиотеке они устанавливаются при помощи объекта AnimatorProxy.
На этом все, если понравится эта статья — продолжу публикации на тему создания анимаций в ОС Android.
ссылка на оригинал статьи http://habrahabr.ru/post/196224/
Добавить комментарий