Hoạt ảnh Android xml về chuyển động của đối tượng. Tạo hoạt ảnh chuyển tiếp giữa Hoạt động trong Android
Bắt đầu từ Android 4.4, các nhà phát triển có thêm một công cụ để tạo hoạt ảnh - Transitions Framework. Ban đầu nó được thiết kế để tạo hoạt ảnh thay đổi trạng thái của ứng dụng bằng cách thao tác trên nhiều Chế độ xem. VỚI Bản phát hành Android 5.0, bộ hoạt ảnh có sẵn để sử dụng đã được mở rộng để tương ứng với khái niệm Thiết kế Vật liệu được giới thiệu cùng lúc.
Transitions Framework cho phép bạn tạo nhiều hình ảnh động khác nhau một cách nhanh chóng và dễ dàng. Vì vậy, trong quá trình làm việc trên i Funny thì không thể bỏ qua bộ công cụ này. Mời bạn đọc tham gia một trường hợp đặc biệt về việc sử dụng Transitions API - tạo hoạt ảnh chuyển đổi giữa các Hoạt động với hiệu ứng “liền mạch”.
Từ quan điểm trực quan, hoạt ảnh chuyển tiếp giữa các Hoạt động được trình bày trong Khung chuyển tiếp có thể được chia thành hai loại: hoạt ảnh thông thường và hoạt ảnh có thành phần chung. Khái niệm hoạt hình với một yếu tố chung được thể hiện bằng một hình ảnh bị đánh cắp một cách trung thực từ dev.android.com. 1. Các thành phần phổ biến trên đó là hình đại diện và tên liên hệ.
Cơm. 1. Hoạt ảnh chuyển tiếp giữa Hoạt động với các thành phần chung
Nhưng không ai thích những lời giới thiệu dài dòng cả, vì vậy hãy chuyển thẳng sang câu chuyện về cách tạo ra các hoạt ảnh thuộc loại này trong ứng dụng i Funny. Ví dụ đầu tiên, hãy xem xét hoạt ảnh được hiển thị trong Hình. 2. Để sử dụng nó, chúng ta cần có phiên bản Android 5.0 trở lên.
Cơm. 2. Ảnh động chuyển đổi giữa Hoạt động trên màn hình xác thực người dùng
Từ quan điểm của người dùng, không có gì bất thường ở đây: một màn hình, hoạt ảnh đơn giản. Tuy nhiên, như bạn có thể đoán, “dưới mui xe” là sự chuyển tiếp giữa hai màn hình với một thành phần chung.
Kỳ lạ thay, bước đầu tiên để tạo ra sự chuyển đổi như vậy là chọn chính phần tử này và xác định vị trí của nó trong bố cục của cả hai Hoạt động. Sau này, bạn cần thêm thuộc tính android:transitionName vào mô tả của từng Chế độ xem hiển thị phần tử đã chọn và cũng gán cho chúng một android:id nếu thiếu.
Trong trường hợp của chúng tôi, đây là các ImageView thông thường có dạng sau:
Có hai điểm quan trọng đáng lưu ý ở đây. Đầu tiên, cả hai ImageView cần được đặt thành cùng một transitionName, điều này hợp lý. Thứ hai, vì chúng ta đang sử dụng ImageView nên nội dung của chúng phải giống nhau, vì việc sử dụng hai tài nguyên khác nhau có thể dẫn đến những hậu quả không mong muốn (ít nhất là chế độ xem hoạt ảnh nhấp nháy ở đầu và cuối hoạt ảnh).
Ở bước thứ hai, bạn cần thêm các tùy chọn cho Hoạt động đã khởi chạy (thứ hai), cho biết rằng hoạt ảnh sẽ được khởi chạy khi nó bắt đầu.
Ghi chú.“Thứ hai” chúng tôi muốn nói đến Hoạt động đã khởi chạy, quá trình chuyển đổi sang hoạt động này phải được thực hiện và “đầu tiên” chúng tôi muốn nói đến Hoạt động khởi chạy.
Điều này được thực hiện như sau:
Gói gói = null; if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) ( Xem v = hoạt động.findViewById(R.id.auth_logo); if (v != null) ( Tùy chọn Hoạt động = Hoạt động.makeSceneTransitionAnimation(hoạt động , v, hoạt động.getString(R.string.email_auth_transition)); bó = tùy chọn.toBundle(); ) ) Ý định = ý định mới (hoạt động, SecondActivity.class); if (gói == null) ( hoạt động.startActivity(ý định); ) khác ( hoạt động.startActivity(ý định, gói); )
Trong danh sách sau:
- R.id.auth_logo - ImageView từ Hoạt động đầu tiên, được sử dụng trong hoạt ảnh;
- hoạt động - Hoạt động đầu tiên;
- R.string.email_auth_transition - nhãn trước đây được để lại trong bố cục của cả hai ImageView;
- SecondActivity.class - Hoạt động thứ hai.
Và bây giờ, người đọc chú ý có thể bối rối: trong phần giới thiệu chúng ta đã nói về việc sử dụng API cấp 19, trong ví dụ có API cấp 21 và trong danh sách ở trên có hạn chế về API cấp 22. Thật không may, khi viết mã, nó hóa ra rằng hoạt ảnh chuyển tiếp có thành phần chung có thể hoạt động không chính xác trên điện thoại có API cấp 21. Điều này thể hiện ở dạng hoạt ảnh bị chậm lại nói chung và các tạo phẩm trên Chế độ xem hoạt ảnh nói riêng. Nếu bạn đã quen thuộc với chủ đề này, biết lý do của hành vi này và/hoặc cách giải quyết vấn đề được mô tả, hãy cho chúng tôi biết về vấn đề đó trong phần nhận xét.
Ở bước thứ ba, cần mô tả hoạt ảnh chuyển tiếp, tức là. chỉ ra đường dẫn mà Chế độ xem động đi qua và sự chuyển đổi của chính Chế độ xem đó. Đối với điều này, chúng tôi sẽ tạo ra tập tin riêng biệt projectName/src/main/res/transitions/email_auth_transition.xml với nội dung sau:
Một chút lý thuyết. Thẻ transitionSet nhằm mục đích mô tả một số phép biến đổi được áp dụng cho Chế độ xem động cùng một lúc. Tham số transitionOrdering kiểm soát thứ tự áp dụng các phép biến đổi này. Trong trường hợp của chúng tôi, chúng được áp dụng đồng thời. Có một số loại chuyển đổi dựng sẵn được cung cấp trong Khung chuyển tiếp. Danh sách đầy đủ có thể được tìm thấy trên trang này. Chúng ta sẽ tập trung vào hai cái cụ thể: ChangeBounds và ChangeImageTransform.
Cái đầu tiên là để chuyển đổi kích thước của Chế độ xem. Cái thứ hai chỉ hoạt động với ImageView và kết hợp với cái thứ nhất, cho phép bạn thay đổi không chỉ kích thước mà còn cả hình dạng của ImageView. Sử dụng dữ liệu chuyển đổi, chúng tôi thu được hình ảnh động đầu ra về việc thay đổi kích thước hình ảnh, được hiển thị trong Hình. 2. Nếu bạn không chỉ định kiểu chuyển động của Chế độ xem động thì nó sẽ di chuyển theo đường đi ngắn nhất. Hơn cách thú vị Chúng ta sẽ xem xét chuyển động trong ví dụ thứ hai.
Bước cuối cùng trong việc tạo hoạt ảnh là khai báo nó trong chủ đề của cả hai Hoạt động. Để thực hiện việc này, hãy chỉnh sửa mô tả của các chủ đề như sau (hoặc tạo chủ đề mới trong thư mục projectName/src/main/res/values-v22/theme.xml):
- android:windowActivityTransitions cho phép hoạt ảnh chuyển tiếp;
- android:windowSharedElementEnterTransition trỏ tới một tệp mô tả hoạt ảnh của quá trình chuyển đổi từ Hoạt động đầu tiên sang Hoạt động thứ hai;
- android:windowSharedElementExitTransition trỏ đến một tệp mô tả hoạt ảnh chuyển tiếp khi quay lại từ Hoạt động thứ hai về Hoạt động đầu tiên.
Cần lưu ý rằng đối với các phiên bản HĐH dưới 5.1 cần tạo các chủ đề có phong cách giống hệt nhau để tránh những hậu quả khá mong đợi khi ứng dụng bị treo. Ví dụ: hãy đặt chúng vào tệp projectName/src/main/res/values/theme.xml:
Итак, для создания анимации перехода от Activity к Activity необходимо:
- Описать анимации (в нашем случае в xml-файле);
- Добавить эти анимации в xml-описание темы Activity;
- Пометить анимируемый общий элемент (View) в разметке;
- При запуске второй Activity указать в параметрах запуска, что для неё необходимо задействовать анимацию перехода.
Как видите, создавать такие анимации совсем не трудно, если не считать некоторых ограничений, упомянутых в первом примере. Теперь рассмотрим второй, более сложный пример. Тут нас интересует переход из раздела комментариев к профилю пользователя (рис. 3).
Рис. 3. Анимация перехода из комментариев к профилю пользователя
Все шаги по созданию перехода, рассмотренные выше, также подходят для этой анимации. А вот трансформация общего элемента реализована немного иначе. В приведённом ниже листинге описано перемещение общего элемента «по дуге» вместе с изменением его размера.
В чём же сложность второго примера? В первом случае использовалось изображение из ресурсов самого приложения, а тут - картинка загружается из сети. К тому же для комментариев изображение аватара пользователя берётся в более низком разрешении, чем для профиля. Поэтому требуется не только дать второй Activity доступ к изображению, используемому в первой, но и по завершении анимации подгрузить требуемое изображение в более высоком качестве. Так и получается две проблемы.
Для решения первой можно было бы собственноручно закэшировать изображение на диск или же передать его адрес в параметре второй Activity. Однако решение данной проблемы переложили на используемую в приложении библиотеку для загрузки изображений - Glide. При загрузке изображения достаточно просто добавить параметр diskCacheStrategy(DiskCacheStrategy.SOURCE), и оно будет закэшировано самой библиотекой (актуально для Glide версии 3.x). Следовательно, при повторном обращении к данному ресурсу из второй Activity будет использоваться кэшированный файл, что поможет нам избежать моргания анимируемого ImageView.
Вторая проблема также решается достаточно просто. В то время как осуществляется анимация перехода, профиль пользователя вместе с аватаром в более высоком разрешении скачиваются из сети и ожидают её завершения. Как только выполняются оба условия (завершение анимации и завершение загрузки), аватар пользователя обновляется. Добиться такого поведения можно, если использовать специальный Listener, в котором реализованы колбэки, вызываемые при смене статуса анимации. Для этого во Fragment, который принадлежит второй Activity, зададим этот самый Listener:
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { getActivity().getWindow().getSharedElementEnterTransition() .addListener(mEnterTransitionListener); } setAvatar(); }
Здесь происходит следующее:
- С помощью getSharedElementEnterTransition().addListener() задаётся Listener для анимации появления Activity;
- В методе setAvatar() производится попытка загрузки и установки аватара (который уже лежит в кэше).
Рассмотрим, как именно реализован Listener:
Private Transition.TransitionListener mEnterTransitionListener = new Transition.TransitionListener() { @Override public void onTransitionStart(Transition transition) { } @Override public void onTransitionEnd(Transition transition) { onProfileUpdated(); } @Override public void onTransitionCancel(Transition transition) { } @Override public void onTransitionPause(Transition transition) { } @Override public void onTransitionResume(Transition transition) { } };
В методе onProfileUpdated() мы обновляем содержимое профиля, в т.ч. и аватар.
Стоит отдельно упомянуть случай, когда общий элемент уходит за пределы экрана. Особенность его состоит в том, что, вопреки (а может, и согласно) логике, анимация перехода всё равно будет выполнена и будет смотреться достаточно забавно (рис. 4).
Рис. 4. Анимация возвращения из профиля в комментарии
Чтобы избежать подобного поведения, достаточно в момент ухода общего элемента за пределы экрана выставить ему видимость, отличную от View.VISIBLE.
В целом можно сказать, что Transitions Framework является простым и мощным инструментом для создания анимаций. Он не ограничивается только анимациями перехода между Activity - в статье был рассмотрен лишь частный случай его использования. Также стоит отметить, что помимо предоставляемых трансформаций имеется возможность создавать свои собственные, но это уже совсем другая история, достойная отдельного поста.
P.S. А о том, как придумывались анимации для iFunny, вы можете прочитать .
В ribot мы заботимся о создании красивого и значимого опыта для людей, в котором движение играет важную роль.
Став свидетелем вдохновляющей речи на Droidcon London, я решил покопаться глубже в элементах движения на Android. Исходя из этого, я собрал все свои находки, чтобы помочь разработчикам и дизайнерам узнать, насколько это просто добавить красивое движение в приложениях на Android.
Если вы хотите попробовать сделать эти анимации сами, каждый из этих примеров упакован в Android приложении на Github.
Я люблю движение, оно не только повышает взаимодействие, но оно сразу же обращает на себя внимание. Подумайте о приложениях, которые вы используете и об анимационном дизайне, особенно то, как приятно, легко, свободно и естественно они выглядят.
Falcon Pro: Даже едва заметные движения могут показать огромную разницу в пользовательском опыте
Теперь сравните их с теми приложениями, которые вы любите, и которые не вызывают таких же чувств.
Medium: Насколько я люблю Medium приложение, но ему действительно не хватает движения в тех областях, в которых она заслуживает его иметь.
Все в деталях
Мы можем использовать эти эффекты движения разными способами:
- Переводить пользователей через навигационный контекст
- Усиливать элементарную иерархию
- Объяснять изменения между компонентами, отображаемыми на экране
Целью данной статьи является показать вам, насколько просто осуществить движение в ваших приложениях, там где оно может принести значительную пользу - так давайте начнем.
Обратная связь по сигналу касания
Обеспечение обратной связи, когда пользователь касается экрана, помогает общаться в визуальной форме, чтобы осуществилось взаимодействие. Эти анимации не должны отвлекать пользователя, но должны его веселить, вносить ясность и поощрять дальнейшее изучение.
Android фреймворк обеспечивает пульсирующее состояние для этого уровня обратной связи, которое может быть использовано для установки фона анимационного образа на одном из следующих:
Android:attr/selectableItemBackground - Показывает пульсирующий эффект в пределах границ образа.
Пульсация начинается в точке касания, заполняя фон представленного образа
?android:attr/selectableItemBackgroundBorderless - Показывает пульсирующий эффект, выходящий за границы представленного образа.
Круговой пульсирующий эффект начинается в точке касания, заполняя радиус, выходящий за пределы представленного образа
View Property Animator
View Property Animator был введен на уровне API 12, что позволяет просто и эффективно выполнять анимационные операции (параллельно) на некоторых свойствах образа, используя один экземпляр Animator.
Здесь я делаю анимации на все свойства, представленные ниже.
alpha ()- Устанавливает значение альфа, чтобы сделать анимацию
ScaleX ()& ScaleY () - Уравновешивает обзор на своей Х и / или Y оси
translationZ ()- Переводит обзор на своей оси Z
setDuration ()- Устанавливает продолжительность анимации
setStartDelay ()- Устанавливает задержку анимации
setInterpolator ()- Устанавливает интерполяции анимации
setListener ()- Устанавливает слушателя, чтобы знать, когда анимация начинается, заканчивается, повторяется или отменена.
Примечание: Когда слушатель был установлен в данном изображении, и если вы осуществляете иные анимации на этой же точке и не хотите использовать эту функцию обратного вызова, то вы должны установить слушателя на NULL.
Это также просто и аккуратно реализовать программно:
mButton.animate():
TranslationZ(10f)
SetInterpolator(new FastOutSlowInInterpolator())
SetStartDelay(200)
SetListener(new Animator.AnimatorListener() {
public void onAnimationStart(Animator animation) { }
public void onAnimationEnd(Animator animation) { }
public void onAnimationCancel(Animator animation) { }
public void onAnimationRepeat(Animator animation) { }
Примечание: Мы на самом деле не должны вызывать start () на нашем анимационном застройщике, так как анимация запускается автоматически, как только мы одновременно прекращаем заявлять об анимации. Если это так, то анимация не начнется до следующего обновления из очереди событий инструментария интерфейса.
Примечание: Для обеспечения обратной совместимости, вы можете использовать класс ViewCompat для реализации ViewPropertyAnimator из Android API версии 4 и выше.
Как и View Property Animator, Object Animator позволяет нам выполнять анимацию на различных свойствах целевого изображения (как в коде так и ресурсах XML-файлов). Тем не менее, есть несколько отличий:
Object Animator только позволяет анимации существовать в единственном состоянии на один образец, например, за шкалой X следует шкала Y
Тем не менее, она позволяет анимации существовать в обычном состоянии, например, цвет переднего плана образа.
Используя пользовательские Свойства или Состояния, чтобы сделать анимацию масштабирования изображения и изменения цвета переднего плана, мы можем получить следующее:
Используя Custom Property, мы можем создать один экземпляр Object Animator вызвав ObjectAnimator.оfInt (), где мы заявляем:
Вид- Вид, чтобы применить анимацию
Свойство- Свойство для анимации
Первоначальный цвет- Цвет, с которого анимационный вид начинается
Целевой цвет- Цвет, с которым данный образ должен ожить
private void animateForegroundColor(@ColorInt final int targetColor) {
ObjectAnimator animator =
ObjectAnimator.ofInt(YOUR_VIEW, FOREGROUND_COLOR, Color.TRANSPARENT, targetColor);
animator.setEvaluator(new ArgbEvaluator());
animator.setStartDelay(DELAY_COLOR_CHANGE);
animator.start();
}
Затем мы устанавливаем оценщика (мы используем ArgbEvaluator, так как мы делаем анимацию между значениями цвета), устанавливаем задержку и начинаем () анимацию.
Мы создаем экземпляр ObjectAnimator используя оfFloat (), потому что мы не делаем анимацию целочисленных значений при работе с размерами образов
Вместо custom property, мы используем свойства изображения - как View.SCALE_X так и View. SCALE_Y
private void resizeView() {
final float widthHeightRatio = (float) getHeight() / (float) getWidth();
resizeViewProperty(View.SCALE_X, .5f, 200);
resizeViewProperty(View.SCALE_Y, .5f / widthHeightRatio, 250);
}
private void resizeViewProperty(Property
float targetScale,
int durationOffset) {
ObjectAnimator animator = ObjectAnimator.ofFloat(this, property, 1f, targetScale);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.setStartDelay(DELAY_COLOR_CHANGE + durationOffset);
animator.start();
}
Наконец, нам надо «оживить» наш образ с измененным размером вне экрана. В этом случае, мы используем AdapterViewFlipper, чтобы вместить наши образы, которые мы анимируем вне экрана. Использование этого означает, что мы можем вызвать showNext () на образце ViewFlipper и он займется анимационными образами вне экрана используя анимацию, которую мы определили. Затем, следующий образ автоматически будет оживать на экране, также используя входящую анимацию, которую мы также определили.
Интерполяторы
Интерполятор может быть использован для определения скорости изменения для анимации, то есть скорость, ускорение и поведение при анимации могут быть изменены. Несколько различных типов, доступных интерполяторов и различия между некоторыми из них являются едва заметными, так что я предлагаю попробовать их на этом устройстве.
- Без Интерполятора - Вид оживает без вариаций в скорости изменения
- Быстро - Вне линии - Внутри
Образ начинает анимацию и заканчивается линейным движением
- Быстро - Медленно - Внутри
Образ начинает анимацию быстро и замедляется к концу
- Линейно - Медленно - Внутри
Образ начинается с линейных движений и замедляется к концу
- Ускорение - Замедление
Образ начинает появляется с ускорения в начале анимации, и постепенно замедляется, когда подходит к концу
- Ускорение- Образ постепенно ускоряется, пока анимация не закончится
- Торможение- Образ постепенно замедляется до тех пор, пока анимация не закончится
- Опережение- Образ начинается с небольшого поворота указанной анимации, прежде чем она станет двигаться стандартным образом
- Предвидеть - Проскакивать- Также как и в Опережении, но движение «тянущее назад», которое происходит во время анимации немного более преувеличено
- Прыгающий Интерполятор- Образ оживает в эффекте «отскок» до того, как дойдет до финиша
- Линейный Интерполятор- Образ оживает от начала до конца линейным и плавным движением
- Проскакивающий Интерполятор- Образ «оживляет» преувеличение данного значения, втягиваясь обратно до требуемого значения
Круговое оживление
Анимация CircularReveal или Круговое оживление использует отсеченный круг, чтобы либо раскрыть, либо скрыть группу элементов пользовательского интерфейса. Кроме помощи в обеспечении визуальной преемственности, это также приятное взаимодействие, для того чтобы помочь усилить его с пользователем.
Как было показано выше, мы начинаем с использования View Property Animator, чтобы скрыть кнопку Floating Action перед началом оживления анимации на наших глазах. Настройка нашего круга оживления требует определить всего лишь несколько атрибутов:
- startView- вид, с которого CircularReveal начнется с (т.е. сжатый вид)
- centerX- Центр координирует для X-оси в нажатом виде
- centerY- Центр координирует для Y-оси в нажатом виде
- targetView- Вид, который надо создать
- finalRadius- Радиус отсечения круга, равный гипотенузе наших значений - centerX и centerY
int centerX = (startView.getLeft() + startView.getRight()) / 2;
int centerY = (startView.getTop() + startView.getBottom()) / 2;
float finalRadius = (float) Math.hypot((double) centerX, (double) centerY);
Animator mCircularReveal = ViewAnimationUtils.createCircularReveal(
targetView, centerX, centerY, 0, finalRadius);
Оконные Переходы
Настройка переходов, используемых для навигации между транзакциями, позволяет производить более сильные визуальные связи между состояниями приложения. По умолчанию мы можем настроить следующие переходы:
- вход- Определяет, как образы транзакции выходят на сцену
- выход- Определяет, как образы транзакции уходят со сцены
- войти снова- Определяет, как транзакция входит снова после ранее сделанного выхода
- общие элементы- Определяет, как обмениваются образы переходов между транзакциями
Как и в 21 уровне API, появилось, и было введено несколько новых переходов:
Взрывной переход позволяет образам выходить со всех сторон экрана, создавая взрывной эффект в нажатом виде.
Взрывной эффект работает очень хорошо на макетах, основанных на сетке.
Этот эффект прост в реализации - начнем с того, что вам нужно создать следующий переход в RES res/transition каталоге.
Все, что мы сделали здесь:
- Объявили взрывной переход
- Установили продолжительность в 300 миллисекунд
Hoặc theo chương trình:
Chuyển đổi bùng nổ = TransitionInflater.from(this).inflateTransition(R.transition.explode);
getWindow().setEnterTransition(nổ);
Cầu trượt
Chuyển đổi slide cho phép bạn trượt vào hoặc ra khỏi giao dịch từ phía bên phải hoặc phía dưới màn hình. Mặc dù bạn có thể đã đạt được điều này trước đây nhưng quá trình chuyển đổi mới này linh hoạt hơn nhiều.
Chuyển tiếp slide cho phép bạn trượt tuần tự vào các hình ảnh con
Quá trình chuyển đổi này có thể phổ biến khi chuyển đổi giao dịch, tôi đặc biệt thích slide bên phải do trạng thái giống như chất lỏng của nó. Một lần nữa, điều này rất dễ thực hiện:
android:slideEdge=“kết thúc“/>
Ở đây chúng tôi:
- Thông báo chuyển tiếp slide
- Đặt slideEdge chuyển tiếp kết thúc ở đó (ở bên phải), để các slide chuyển sang bên phải - slide dưới cùng phải được đặt ở dưới cùng
Mờ dần
Chuyển đổi mờ dần cho phép bạn chuyển đổi sang giao dịch nội bộ hoặc bên ngoài bằng cách sử dụng hiệu ứng mờ dần.
Quá trình chuyển đổi mờ dần rất đơn giản, mặc dù quá trình chuyển đổi mờ dần rất dễ chịu.
Việc tạo nó thậm chí còn dễ dàng hơn so với các chuyển đổi trước đó:
Ở đây chúng tôi:
- Chúng tôi thông báo quá trình chuyển đổi mờ dần
- Đặt thời lượng thành 300 mili giây
Tối ưu hóa chuyển đổi
Mặc dù đã thử nghiệm nhưng tôi đã tìm thấy một số phương pháp có thể giúp cải thiện các hiệu ứng chuyển tiếp được đề cập ở trên.
Cho phép chuyển đổi nội dung cửa sổ- bạn phải kích hoạt thuộc tính sau trong các chủ đề kế thừa từ chủ đề vật chất:
Bật/tắt chuyển tiếp phù hợp- Khi chuyển đổi, có thể có độ trễ khi một hành động chờ một hành động khác hoàn tất quá trình chuyển đổi trước khi hành động đó có thể bắt đầu quá trình chuyển đổi của chính nó. Tùy thuộc vào trường hợp sử dụng, quá trình chuyển đổi nhìn chung sẽ trôi chảy và tự nhiên hơn nếu bạn bật các thuộc tính sau:
Loại trừ hình ảnh khỏi quá trình chuyển đổi- Đôi khi chúng tôi có thể không muốn tạo chuyển tiếp cho tất cả hình ảnh giao dịch của mình. Tôi nhận thấy rằng trong hầu hết các trường hợp, thanh trạng thái và thanh công cụ đều gây ra sự cố chuyển tiếp. May mắn thay, chúng tôi có thể loại trừ một số loài nhất định đã được đưa vào quá trình chuyển đổi của chúng tôi:
Thanh công cụ và thanh hành động- Khi chuyển đổi giữa các thao tác sử dụng Action Bar sang sử dụng Toolbar (và ngược lại), đôi khi tôi nhận thấy quá trình chuyển đổi không phải lúc nào cũng suôn sẻ. Để khắc phục điều này, tôi đảm bảo rằng hai hoạt động liên quan đến quá trình chuyển đổi đều sử dụng cùng một thành phần.
Thời gian chuyển tiếp- Bạn không muốn người dùng phải chờ đợi quá lâu nhưng cũng không muốn tạo ra các thành phần xuất hiện với tốc độ ánh sáng. Điều này phụ thuộc vào quá trình chuyển đổi mà bạn đang sử dụng, vì vậy tốt nhất bạn nên thử nghiệm, nhưng tôi nhận thấy rằng thời lượng 200-500 mili giây có tác dụng trong hầu hết các trường hợp.
Các yếu tố chuyển tiếp phổ biến
Các phần tử chuyển tiếp được chia sẻ cho phép bạn tạo hiệu ứng chuyển tiếp giữa các hình ảnh được chia sẻ trong một giao dịch, tạo ra các chuyển tiếp thú vị hơn và giúp người dùng hiểu rõ hơn về hành trình của họ.
Ở đây, hình ảnh từ hành động đầu tiên của chúng tôi được thu nhỏ và dịch thành hình ảnh tiêu đề trong hành động thứ hai
Trong bố cục của mình, chúng tôi phải liên kết bất kỳ hình ảnh phổ biến nào bằng thuộc tính transitionName - điều này thiết lập mối quan hệ chuyển tiếp giữa các hình ảnh. Dưới đây là những hình ảnh chung từ hoạt hình trên:
Đây là những hình ảnh được chia sẻ, có nghĩa là chúng sẽ trở nên sống động với nhau trong quá trình chuyển đổi hành động
Để chuyển đổi giữa hai điều này, chúng tôi bắt đầu bằng cách khai báo tên của quá trình chuyển đổi chung, được thực hiện bằng cách sử dụng thuộc tính transitionName trong bố cục XML.
android:transitionName=“@string/transition_view“/>
android:transitionName=“@string/transition_view“/>
Sau khi hoàn thành việc này, chúng ta tạo một đối tượng Cặp ở bước 1) chứa hình ảnh chuyển tiếp của chúng ta và tên chuyển tiếp của nó. Sau đó, chúng tôi chuyển nó sang các tùy chọn giao dịch mẫu như (ActivityOptionsCompat) để cả hai hoạt động đều nhận biết được các thành phần chung. Từ đó chúng ta sẽ bắt đầu giao dịch của mình, thông qua tùy chọn ví dụ:
Người tham gia cặp = Cặp mới<>(mSquareView, ViewCompat.getTransitionName(mSquareView));
Hoạt độngOptionsCompat chuyển tiếpActivityOptions =
Hoạt độngOptionsCompat.makeSceneTransitionAnimation(
SharedTransitionsActivity.this, người tham gia);
Hoạt độngCompat.startActivity(SharedTransitionsActivity.this,
ý định, transitionActivityOptions.toBundle());
Việc tách những hình ảnh này trong khi quá trình chuyển đổi đang diễn ra thực sự giúp hoàn thành quá trình chuyển đổi.
Đây là phần chuyển tiếp giữa hai hình ảnh này, nhưng còn những hình ảnh trong màn thứ hai trượt từ bên dưới thì sao?
(Những người ở bên trái)
Tôi rất vui vì bạn đã hỏi! Điều này cũng dễ dàng đạt được, như hình dưới đây:
Trượt slide = Slide mới(Gravity.BOTTOM);
slide.addTarget(R.id.view_separator);
slide.addTarget(R.id.text_detail);
slide.addTarget(R.id.text_close);
getWindow().setEnterTransition(slide);
Như bạn có thể thấy, chúng tôi tạo mẫu Trang trình bày chuyển tiếp mới bằng cách thêm các chế độ xem mục tiêu cho quá trình chuyển đổi và đặt trang trình bày làm chuyển tiếp mục nhập giao dịch.
Chuyển tiếp tùy chỉnh
Chúng tôi cũng có khả năng tạo các chuyển đổi của riêng mình bằng cách sử dụng bất kỳ hoạt ảnh nào từ API mà chúng tôi đã đề cập cho đến nay. Ví dụ: chúng ta có thể thực hiện thêm một bước chuyển tiếp Phần tử được chia sẻ để trở thành hình ảnh chuyển tiếp - điều này có thể hữu ích khi chúng ta muốn hiển thị hộp thoại (hoặc hình ảnh bật lên tương tự), như hiển thị bên dưới:
Chuyển động này giúp hướng sự chú ý của người dùng giữa các trạng thái thành phần
Chúng ta hãy xem nhanh những gì đang xảy ra ở đây:
- Chúng tôi bắt đầu bằng cách tạo SharedTransition, chuyển ở trạng thái được nhấn cùng với tên chuyển đổi để tham chiếu thành phần được chia sẻ
- Tiếp theo, chúng tôi tạo một phiên bản ArcMotion, điều này cho phép chúng tôi tạo hiệu ứng chuyển động cong khi chuyển đổi giữa hai hình ảnh
- Sau đó, chúng tôi mở rộng ChangeBounds để tạo chuyển đổi tùy chỉnh và chuyển đổi hai biểu mẫu (chúng tôi có một lớp riêng cho nút và FAB). Ở đây, chúng tôi ghi đè các phương thức khác nhau từ lớp để có thể tạo hiệu ứng động cho các thuộc tính được yêu cầu. Chúng ta sẽ sử dụng ViewPropertyAnimator để tạo hoạt ảnh cho độ trong suốt của hình ảnh hộp thoại, ObjectAnimator để tạo hoạt ảnh cho hình ảnh giữa hai màu và một AnimatorSet mẫu để chúng ta có thể tạo hiệu ứng cho cả hai hiệu ứng này cùng nhau.
Vector hoạt hình của hệ số đầu vào
Kể từ phiên bản API 21 (Lollipop), AnimatedVectorDrawable có thể được sử dụng để tạo hoạt ảnh cho các thuộc tính VectorDrawable nhằm tạo ra hoạt ảnh của đối tượng có thể vẽ.
Bây giờ thật dễ dàng để tạo một số loại hoạt ảnh khác nhau trên hệ số đầu vào
Nhưng làm thế nào để chúng tôi làm điều này? Vâng, chúng ta hãy xem điều này:
Nó bao gồm một số tệp khác nhau và chúng tôi bắt đầu bằng cách tạo hai tệp vectơ riêng biệt, mỗi tệp có một số thuộc tính:
- Chiều cao và chiều rộng - Kích thước thực tế của hình ảnh vector
- Chiều cao và chiều rộng của khung nhìn - Khai báo kích thước của khung vẽ ảo nơi các rãnh vectơ được vẽ trên đó
- Tên nhóm - Khai báo nhóm mà bản nhạc thuộc về
- Pivot X & Y - Khai báo trục xoay dùng để chia tỷ lệ và xoay nhóm
- Tô màu đường dẫn - Vector tô màu đường dẫn
- Path Data - Khai báo dữ liệu của đường dẫn vector dùng để vẽ vector
Lưu ý: Tất cả các thuộc tính liên kết được lưu trữ trong một tệp dòng chung, giúp giữ cho các phần tử được ngăn nắp và gọn gàng.
android:width=“56dp“
android:viewportWidth=“24.0“>
android:pivotX=“12“
android:pivotY=“12“>
android:pathData=“@string/path_add“/>
Vectơ được tạo từ tệp ic_add.xml của chúng tôi (bên dưới)
android:width=“56dp“
android:viewportHeight="24.0"
android:viewportWidth=“24.0“>
android:pivotX=“12“
android:pivotY=“12“>
android:pathData=“@string/path_remove“/>
Vectơ được tạo từ tệp ic_remove.xml của chúng tôi (bên dưới)
Tiếp theo, chúng tôi khai báo các tệp Vector có thể vẽ hoạt hình, đặt cả Vector có thể vẽ được và hoạt ảnh được sử dụng cho từng trạng thái "kéo dài" (Thêm hoặc Xóa). Bằng cách xem xét vectơ hoạt ảnh được thêm hoặc xóa, chúng ta khai báo mục tiêu:
Hoạt hình từ trạng thái này sang trạng thái khác
Hoạt hình xoay của hệ số đã nhập
android:drawable=“@drawable/ic_add“>
android:animation=“@animator/add_to_remove“ />
android:animation=“@animator/rotate_add_to_remove“ />
Sau đó, chúng ta phải tạo từng tệp được đề cập cho các mục đích này.
Thay đổi trạng thái của hệ số đã nhập
Trong add_to_remove.xml, chúng tôi sử dụng ObjectAnimator để chuyển đổi giữa các hình dạng bằng các thuộc tính sau:
- PropertyName - Thuộc tính hoạt ảnh
- valueFrom- Giá trị ban đầu cho đường dẫn vectơ
- valueTo- Giá trị đích cho đường dẫn vector
- Thời lượng - Thời lượng của hoạt ảnh
- bộ nội suy - Bộ nội suy được sử dụng cho hoạt ảnh
- ValueType - Loại giá trị chúng ta đang tạo hiệu ứng
android:propertyName=“pathData“
android:valueFrom=“@string/path_add“
android:valueTo=“@string/path_remove“
android:interpolator=“@android:interpolator/fast_out_slow_in“
android:valueType=“pathType“ />
Xoay biểu mẫu
Chúng tôi sử dụng cách tiếp cận tương tự để xoay hình bằng cách sử dụng thuộc tính góc quay và độ lớn:
android:propertyName=“xoay”
android:valueFrom=“-180“
android:valueTo=“0“
android:duration=“@integer/duration“
android:interpolator=“@android:interpolator/fast_out_slow_in“ />
Hoạt ảnh đảo ngược (từ Xóa sang Thêm) hoạt động tương tự, chỉ với các giá trị hoạt ảnh đảo ngược.
Vector hệ số đầu vào hoạt hình đã hoàn thành của chúng ta trông thật tuyệt phải không!
Và kết luận là…
Mặc dù chỉ là bề nổi nhưng tôi hy vọng bài viết này đã cung cấp một số thông tin chi tiết về cách bạn có thể tạo ra chuyển động có ý nghĩa trong ứng dụng của mình. Tôi mong muốn tìm hiểu cách tôi có thể đẩy chúng đi xa hơn và cải thiện giao diện thiết kế của tôi.
Nếu bạn thích bài viết này, vui lòng nhấp vào “Đề xuất”!
Tôi muốn biết suy nghĩ của bạn về vấn đề này và nơi bạn sử dụng những hoạt ảnh này - vui lòng để lại nhận xét hoặc tweet cho tôi!
Chúc một ngày tốt lành cho tất cả. Tôi muốn dành bài đăng này cho chủ đề về các mảnh vỡ dành cho Android. Hiện đã có bản dịch và một số bài viết trên Habré đề cập đến cách bắt đầu làm việc với các mảnh cho Android. Ví dụ như bài viết. Nó chứa mô tả về các phân đoạn là gì và chúng có sẵn ở phiên bản Android nào, vì vậy những người chưa sử dụng nó có thể đọc nó nếu họ muốn, nhưng tôi sẽ không kể lại điều này trong bài đăng của mình. Vậy tôi sẽ đi thẳng vào vấn đề.
Bắt đầu công việc
Hãy để tôi nói ngắn gọn rằng các đoạn là các thành phần giao diện người dùng có thể được sử dụng bằng lớp Hoạt động để hiển thị dữ liệu người dùng, nhưng vòng đời của chúng không phụ thuộc vào điều đó. Chức năng do các mảnh cung cấp có chức năng làm việc với chúng rộng hơn so với Hoạt động, vì vậy việc sử dụng chúng có tầm quan trọng không nhỏ đối với các nhà phát triển nếu họ muốn ứng dụng của mình có giao diện người dùng hiện đại hơn theo tiêu chuẩn ngày nay.Bây giờ chúng ta hãy đi vào điểm của bài viết. Theo ý kiến của tôi, các nhà phát triển mảnh Google đã được ban tặng sự hỗ trợ tuyệt vời cho hoạt ảnh hiển thị chính mảnh đó. Điều này sẽ được thảo luận thêm. Tôi đã tìm kiếm Habr các bài viết về chủ đề này nhưng không tìm thấy gì nên bây giờ tôi sẽ chia sẻ kiến thức của mình.
Tạo một dự án
Hãy tạo một dự án nhỏ. Tôi đã tạo một dự án cho Samsung Nexus S của mình, nơi tôi có phiên bản Android 4.1.2, đây là phiên bản tôi đã sử dụng (Api cấp 16). Tôi gọi dự án đó là FragmentsAnimationTest.Để minh họa, chúng ta sẽ cần hoạt động chính và bố cục của nó, một vài đoạn, mỗi đoạn có bố cục riêng và một vài tệp xml khác cho chính hoạt ảnh mà tôi sẽ nói sau.
Ứng dụng sẽ trông như thế này: một trong các đoạn sẽ được hiển thị trên màn hình, việc chuyển đổi giữa chúng sẽ được thực hiện bằng nút thông thường và theo đó, việc chuyển đổi các đoạn sẽ đi kèm với hiệu ứng hoạt hình.
Trước tiên, hãy sắp xếp các thành phần của hoạt động chính trong tệp hoạt động_main.xml:
Từ mã, bạn có thể thấy bố cục chính được sử dụng - InteractiveLayout, khá thuận tiện khi làm việc với các đoạn; hai phần tử FrameLayout tiêu chuẩn được đặt trong đó - trên thực tế, nó sẽ là nơi chứa các đoạn và một nút sẽ được sử dụng. để chuyển đổi các mảnh với nhau. Hiện tại, mọi thứ sẽ cực kỳ đơn giản.
Tiếp theo, hãy chuyển sang các mảnh vỡ của chúng tôi. Hãy tạo đánh dấu cho họ và chính các lớp đó:
đoạn1.xml
Đoạn2.xml
Đối với cả hai đoạn, mã gần như giống nhau, điểm khác biệt duy nhất là văn bản sẽ được hiển thị trong chính đoạn đó để xác định nó và màu nền để có thể nhìn thấy rõ hoạt ảnh.
Đoạn1.java
lớp công khai Fragment1 mở rộng Fragment ( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle SavedInstanceState) ( return inflater.inflate(R.layout.fragment_1, null); ) )
Fragment2.java
public class Fragment2 mở rộng Fragment( @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle SavedInstanceState) ( return inflater.inflate(R.layout.fragment_2, null); ) )
Trong lớp học, mọi thứ cũng phải rõ ràng nếu bạn đã quen với chủ đề của các đoạn. Chúng chỉ đơn giản chỉ ra phần bỏ đi chính xác nào sẽ được sử dụng khi hiển thị một đoạn cụ thể và chỉ vậy thôi.
Bây giờ chúng ta hãy đến phần ngon. Hãy làm việc với lớp hoạt động chính, đây là mã của nó:
lớp công khai MainActivity mở rộng Hoạt động ( đoạn riêng tư Fragment2; đoạn riêng tư Fragment1; riêng tư FragmentTransaction ft; @Override protected void onCreate(Bundle saveInstanceState) ( super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment1 = new Fragment1() ;Fragment2 = new Fragment2(); ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right), ft.addToBackStack(null) ; ft.commit(); Nút btn = (Nút) findViewById(R.id.btn); btn.setOnClickListener() ( @Override public void onClick(View v) ( ft = getFragmentManager().beginTransaction(); ft. setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right); // ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); if(fragment1.isVisible( ))( ft.replace(R.id.fragCont, Fragment2); )else ( ft.replace(R.id.fragCont, đoạn1); ) ft.commit(); ) )); ) )
Hãy xem chính xác những gì đang xảy ra trong hoạt động của chúng tôi. Đầu tiên, cả hai mảnh đều được tạo, như đã đề cập, sẽ luân phiên thay đổi lẫn nhau. Tiếp theo, chúng tôi biểu thị bằng dòng ft = getFragmentManager().beginTransaction(), chúng tôi nhận được FragmentTransaction, nhờ đó chúng tôi có thể tương tác với các phân đoạn của mình, nhưng đây là tất cả trong bài viết mà tôi đã đề cập trước đó. Trước khi chuyển sang phân tích đoạn mã sau, tôi sẽ thực hiện một phân tích nhỏ.
Có hai tùy chọn để tạo hình động để hiển thị các đoạn:
- Phương pháp đầu tiên là kết nối hoạt ảnh tiêu chuẩn bằng phương thức setTransition(int Transit). Lớp FragmentTransaction có một số hoạt ảnh được xác định trước.
- Phương pháp thứ 2 chính xác là điều chúng ta quan tâm trong chủ đề này, việc triển khai hoạt ảnh tùy chỉnh. Hoàn tất bằng phương thức setCustomAnimations()
Mặc dù vậy, một số nhận xét có sẵn là để bạn có thể thử sử dụng hoạt ảnh được mô tả trước, chỉ cần bỏ ghi chú chúng và nhận xét dòng trước đó - ft.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_in_right), trong cả hai trường hợp Cái này không cần thiết.
Hãy phân tích mã hoạt động đến cuối và chuyển sang tạo hoạt ảnh.
Sau khi thiết lập hoạt ảnh, đoạn này được hiển thị, được thêm vào ngăn xếp và giao dịch hoàn tất để hiển thị tất cả các thay đổi. Sau đó, chúng tôi khởi tạo nút của mình và đính kèm trình xử lý sự kiện nhấn nút vào nút đó, bên trong có mã để thay đổi các đoạn. Khi nhấn nút, chúng tôi bắt đầu giao dịch, kết nối hoạt ảnh và thay đổi đoạn đối diện với đoạn hiện tại. cho xem. Code rất đơn giản nên không cần giải thích sâu.
Tạo hoạt ảnh
Hãy chuyển sang phần chính của chủ đề của chúng tôi. Hãy tìm hiểu cách tự tạo hoạt ảnh. Cách chúng tôi tạo hoạt ảnh ở đây hơi khác so với cách chúng tôi thường làm trong các phiên bản Android trước đó. Việc thực hiện diễn ra như sau. Trước tiên, bạn cần tạo một thư mục hoạt hình trong thư mục tài nguyên ứng dụng, nó sẽ trông như thế này - res/animator/. Ở đây chúng ta phải đặt các tệp xml sẽ mô tả chính xác cách phát hoạt ảnh. Hãy đặt chúng ở đó:slide_in_left.xml
Và slide_in_right.xml
Bây giờ chúng ta hãy xem xét chúng một cách chi tiết. Bản thân các thành phần của hiệu ứng hình ảnh được mô tả trong thẻ objectAnimator; mỗi thẻ như vậy mô tả mô tả về hiệu ứng hoạt hình mới. Bây giờ chúng ta hãy xem xét các thuộc tính. Thuộc tính đầu tiên trong tệp slide_in_left.xml là bộ nội suy, nó có một số giá trị, bạn có thể tìm hiểu thêm về chúng trong tài liệu Hoạt ảnh thuộc tính. Bộ nội suy chịu trách nhiệm hiển thị đoạn của chúng tôi theo một cách nhất định trong một thời gian nhất định. Tiếp theo, chúng ta có thuộc tính propertyName, nó cho biết thuộc tính nào của đoạn chúng ta sẽ thay đổi trong quá trình hoạt ảnh; trong ví dụ của chúng ta, y xuất hiện trước và valueType cho biết loại tham số chúng ta đang thay đổi. Cuốn sách Pro Android 4 giải thích điều này bằng cách nói rằng nếu bạn xem phương thức setX() trong lớp View, bạn sẽ thấy rõ rằng nó nhận một giá trị float; phương thức setY() cũng thực hiện tương tự, do đó có giá trị floatType.
Tiếp theo là các thuộc tính không quan trọng valueFrom và valueTo, chúng cho biết giá trị nào sẽ thay đổi giá trị được chỉ định trong propertyName, trong trường hợp đầu tiên của chúng ta là y. Nếu tham số valueFrom không được chỉ định thì giá trị sẽ được lấy bằng giá trị hiện tại. Trong trường hợp của chúng tôi, valueFrom bằng -1280, điều này có nghĩa là chuyển động của đoạn dọc theo trục y sẽ bắt đầu từ giá trị -1280, giá trị này được chọn do nó nằm bên ngoài màn hình thiết bị và chuyển động sẽ xảy ra cho đến khi giá trị y bằng 0 ở góc trên bên trái của đoạn của chúng ta trong 1500 mili giây. Và cuối cùng, thuộc tính thời lượng chỉ định chính xác hiệu ứng hoạt hình của chúng ta sẽ kéo dài bao lâu tính bằng mili giây.
Và sắc thái cuối cùng mà tôi muốn mô tả. Nhìn vào bất kỳ tệp mô tả hoạt ảnh nào, bạn có thể thấy thẻ set chứa tất cả các hiệu ứng hoạt hình; nó dùng để kết hợp các hiệu ứng hoặc tách chúng ra. Tệp slide_in_right.xml sử dụng thuộc tính sắp xếp trong thẻ đã đặt, trong trường hợp của chúng tôi, nó có giá trị cùng nhau, nghĩa là phát các hiệu ứng đồng thời, trái ngược với nó là có một giá trị tuần tự, yêu cầu các hiệu ứng phải được hiển thị tuần tự trong hoạt hình, rất thuận tiện trong một số trường hợp.
Đó là tất cả. Tệp slide_in_right.xml cung cấp ví dụ về cách bạn có thể sử dụng các thuộc tính khác cho hoạt ảnh, chẳng hạn như kênh alpha. Tôi hy vọng bài viết này sẽ hữu ích cho những ai quan tâm đến ứng dụng của họ sẽ trông như thế nào.
Như chính bạn cũng hiểu, Habrausers thân mến, ảnh chụp màn hình sẽ không thể hiển thị kết quả công việc.
Các tài liệu và nguồn được sử dụng khi viết bài đã được đề cập trong chính bài báo.
Trong bài viết này, chúng ta sẽ xem xét cách tạo hoạt ảnh cho các thành phần giao diện trong Android. Trong trường hợp này, các thành phần giao diện có nghĩa là tất cả các thành phần con của lớp View ( danh sách đầy đủ con cháu có thể được tìm thấy trong tài liệu của lớp View). Hoạt ảnh là một cách dễ dàng để làm cho ứng dụng trở nên sinh động hơn :)
1.
Hãy bắt đầu bằng cách tạo một trang web thử nghiệm. Hãy tạo một ứng dụng đơn giản với một nút bấm và một hình ảnh ở giữa màn hình. Tôi sẽ không cung cấp mã, rất đơn giản, nếu có, hãy xem nguồn (ở cuối bài viết).
2.
Trong thư mục /res/anim, tạo tệp anim.xml và ghi vào đó
xml
version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
set
xmlns:android="
http
:
//
schemas.android.com
/apk/res/android
"
android:shareInterpolator="
false
"
>
<
alpha
android:fromAlpha="
0.0
"
android:toAlpha="
1.0
"
android:duration="
1000
"
/>
set
>
Đây là mô tả hoạt ảnh mà chúng tôi sẽ áp dụng cho hình ảnh của mình. Chúng tôi sẽ xem xét những gì đang xảy ra ở đây một cách chi tiết hơn bên dưới, nhưng hiện tại chúng tôi sẽ chỉ sao chép nó vào một tệp.
3.
Để tải một hình ảnh động từ tập tin xmlđã sử dụng phương pháp tĩnh lớp Hoạt hìnhUtils
LoadAnimation(Ngữ cảnh, int id), Ở đâu bối cảnh là bối cảnh hiện tại, và nhận dạng- mã định danh tài nguyên có hình ảnh động. Phương thức này trả về một thể hiện của lớp Hoạt hình.
Hoạt hình- lớp trừu tượngđể trình bày hình ảnh động trong ứng dụng.
Để áp dụng nó, thể hiện kết quả của lớp Hoạt hình được truyền cho phương thức
startAnimation( Hoạt hình hoạt hình)
Chế độ xem lớp (và tất cả con cháu của nó).
4.
Hãy ghi vào tệp AnimationTestActivity.java:
lớp công khai AnimationTestActivity mở rộng Hoạt động ( Hình ảnh ImageView; Nút nút; Hoạt hình; @Override protected void onCreate(Bundle SavedInstanceState) ( super .onCreate(savedInstanceState); setContentView(R.layout.main); image = (ImageView)findViewById(R. id.image); nút = (Button )findViewById(R.id.button); anim = AnimationUtils.loadAnimation(this , R.anim.anim); // 1 nút.setOnClickListener(new OnClickListener() ( @Override public void onClick(Xem v) ( image.startAnimation(anim); //2 ) ) )
1) Đọc tệp có mã định danh R.anim.anim (tương ứng với tệp /res/anim/anim.xml) và lấy một phiên bản của lớp Hoạt hình.
2) Bằng cách nhấp vào nút, chúng tôi áp dụng hoạt ảnh cho hình ảnh.
5. Bạn có thể chạy ứng dụng của chúng tôi. Khi bạn nhấn nút, hình ảnh sẽ biến mất và sau đó bắt đầu xuất hiện trở lại từ từ.
6.
Bây giờ chúng ta hãy xem xét kỹ hơn cách tạo hoạt ảnh trong tệp xml.
Có 4 loại hoạt hình:
- alpha(minh bạch, rõ ràng)
- tỉ lệ(chia tỷ lệ)
- quay(xoay)
- dịch(di chuyển)
Để tạo hoạt ảnh, chúng ta phải mô tả trạng thái ban đầu và trạng thái cuối cùng của đối tượng và chính hệ thống sẽ quyết định cách chuyển từ trạng thái này sang trạng thái khác. Trong ví dụ của chúng tôi
<
alpha
android:fromAlpha="
0.0
"
android:toAlpha="
1.0
"
android:duration="
1000
"
/>
chúng tôi mô tả hoạt ảnh alpha, nghĩa là chúng tôi thay đổi mức độ hiển thị của đối tượng. Đặt trạng thái ban đầu từAlpha="0.0"(hoàn toàn vô hình) và hữu hạn toAlpha="1.0"(có thể nhìn thấy đầy đủ). Chỉ định thời lượng của hoạt ảnh thời lượng="1000"(tính bằng mili giây). Và mọi thứ khác, đó là cách thay đổi mức độ hiển thị của một đối tượng để biến nó từ vô hình sang hiển thị trong một giây, hệ thống sẽ tự thực hiện. Điều này được tính bằng cách sử dụng phép nội suy- trong toán học tính toán, một cách để tìm giá trị trung gian các giá trị từ tập giá trị rời rạc có sẵn. Đối với mỗi hoạt ảnh, bạn có thể đặt bộ nội suy
-Bộ nội suy tăng tốcGiảm tốc(@android:anim/accelerate_decelerate_int erpolator) - tốc độ thay đổi thấp ở đầu và cuối và tăng tốc ở giữa
-Bộ nội suy tăng tốc(@android:anim/accelerate_interpolator) - tốc độ thay đổi bắt đầu ở mức thấp và sau đó tăng tốc
-Dự đoánInterpolator(@android:anim/anticipate_interpolator) - các thay đổi bắt đầu theo hướng ngược lại và sau đó tiến mạnh về phía trước
-Dự đoánOvershootInterpolator(@android:anim/anticipate_overshoot_inte rpolator) - các thay đổi bắt đầu theo hướng ngược lại, sau đó nhanh chóng di chuyển về phía trước và bay lên trên giá trị cuối cùng, sau đó quay trở lại giá trị cuối cùng
-Bộ nội suy trả lại(@android:anim/bounce_interpolator) - tốc độ thay đổi tăng vào cuối
-Chu kỳInterpolator(@android:anim/cycle_interpolator) - lặp lại hoạt ảnh một số lần nhất định. Tốc độ thay đổi theo hình sin
-Bộ suy giảm tốc độ(@android:anim/decelerate_interpolator) - tốc độ thay đổi giảm dần ở cuối
-Bộ nội suy tuyến tính(@android:anim/Linear_interpolator) - tốc độ thay đổi không đổi
-OvershootInterpolator(@android:anim/overshoot_interpolator) - các thay đổi nhảy về phía trước và vượt lên trên giá trị cuối cùng, sau đó quay lại giá trị cuối cùng
Bộ nội suy được đặt bằng thuộc tính android:interpolator. Ví dụ
android:interpolator="@android:anim/cycl e_interpolator". Giá trị mặc định là LinearInterpolator.
7. Mô tả trạng thái ban đầu và cuối cùng
1) alpha (tính minh bạch, khả năng hiển thị)
- android: fromAlpha- giá trị minh bạch ban đầu. 0,0 - hoàn toàn trong suốt (vô hình), 1,0 - hoàn toàn mờ đục (hiển thị)
- android:toAlpha- giá trị minh bạch cuối cùng
2) tỉ lệ
- android: fromXScale- giá trị tỷ lệ ban đầu dọc theo trục X (trong đó kích thước hiện tại tương ứng với giá trị 1.0)
- android:toXScale- giá trị tỷ lệ cuối cùng dọc theo trục X
- android:fromYScale- giá trị tỷ lệ ban đầu dọc theo trục Y (trong đó kích thước hiện tại tương ứng với giá trị 1.0)
- android:toYScale- giá trị tỷ lệ cuối cùng dọc theo trục Y
- android:pivotX- tọa độ x của điểm, sẽ không thay đổi sau khi chia tỷ lệ
- android:pivotY- tọa độ y của điểm, sẽ không thay đổi sau khi chia tỷ lệ
Các giá trị có thể có cho PivotX và PivotY:
tính bằng pixel so với cạnh trái (hoặc trên cùng đối với tọa độ Y) của phần tử (ví dụ: "5")
dưới dạng phần trăm so với cạnh trái (trên cùng) (ví dụ: "5%")
dưới dạng phần trăm so với cạnh trái (trên cùng) của phần tử gốc (ví dụ: "5%p")
Ví dụ: nếu PivotX=0, PivotY=0 (tương ứng với góc trên cùng bên trái của phần tử), thì tỷ lệ sẽ thay đổi kích thước phần tử xuống và sang phải. Nếu PivotX=50%, PivotY=50% thì điểm nằm ở giữa phần tử và kích thước thay đổi theo mọi hướng, trong khi tâm sẽ vẫn ở một điểm.
3) xoay (xoay)
- android:fromDegrees- Giá trị ban đầu của góc quay (tính bằng độ, có thể có giá trị âm)
- android: toDegrees- giá trị cuối cùng của góc quay
- android:pivotX- tọa độ x tâm quay.
- android:pivotY- tọa độ y của tâm quay.
Các giá trị có thể có của PivotX và PivotY như trong ảnh động tỷ lệ
4) dịch (di chuyển)
- android:fromXDelta- tọa độ x của điểm bắt đầu chuyển động. Những giá trị khả thi:
tính bằng pixel so với vị trí ban đầu (ví dụ: “5”)
dưới dạng phần trăm so với chiều rộng của phần tử (ví dụ: “5%”)
dưới dạng phần trăm so với chiều rộng của phần tử gốc (ví dụ: "5%p")
- android: toXDelta- tọa độ x điểm cuối sự di chuyển
- android: fromYDelta- tọa độ y của điểm bắt đầu chuyển động
- android:toYDelta- tọa độ y của điểm cuối của chuyển động
8. Tùy chọn bổ sung
Ngoài ra còn có các thuộc tính chung cho cả bốn loại hoạt ảnh, trong đó hữu ích nhất là:
- android: thời lượng- thời lượng hoạt ảnh (tính bằng mili giây)
- android: bộ nội suy- xác định bộ nội suy cho hoạt ảnh
- android:repeatCount- số lần lặp lại hoạt ảnh bổ sung. Chính xác là những cái bổ sung, nghĩa là hoạt ảnh sẽ được thực thi một lần. Giá trị mặc định là "0" - điều này có nghĩa là hoạt ảnh sẽ chỉ được thực thi một lần. Giá trị "1" có nghĩa là hoạt ảnh sẽ chạy hai lần (một lần là hoạt ảnh chính và một lần là hoạt ảnh phụ). Giá trị “-1” hoặc “vô hạn” có nghĩa là sự lặp lại vô tận.
- android: Chế độ lặp lại- xác định hành vi của hoạt ảnh khi nó kết thúc và tham số số lần lặp lại không bằng 0. Có hai giá trị: “khởi động lại” - hoạt ảnh bắt đầu lại và “đảo ngược” - hoạt ảnh sẽ đi theo thứ tự ngược lại .
- android:startOffset- độ trễ trước khi hoạt ảnh bắt đầu (tính bằng mili giây)
9. Kết hợp nhiều ảnh động
Bạn có thể áp dụng nhiều loại hoạt ảnh cho một phần tử cùng một lúc. Ví dụ: nếu chúng ta viết:
xml
version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
set
xmlns:android="
http
:
//
schemas.android.com
/apk/res/android
"
>
<
alpha
android:fromAlpha="
0.0
"
android:toAlpha="
1.0
"
android:duration="
1000
"
/>
<
rotate
android:fromDegrees="
0
"
android:toDegrees="
360
"
android:pivotX="
50%
"
android:pivotY="
50%
"
android:duration="
1000
"
/>
set
>
Hình ảnh sẽ thay đổi độ trong suốt trong 1 giây (từ trong suốt hoàn toàn sang mờ đục) và đồng thời xoay 360 độ.
Hoạt ảnh có thể được đặt thành các khoảng thời gian khác nhau, ví dụ: hãy đặt thời lượng=5000để xoay hình ảnh động. Bây giờ hình ảnh sẽ xoay chậm hơn nhiều và độ trong suốt vẫn sẽ thay đổi sau một giây.
Bằng cách sử dụng bắt đầuOffset, bạn có thể tạo hoạt ảnh theo trình tự. Thêm thuộc tính xoay bắt đầuOffset="1000"(nghĩa là chúng ta sẽ tạo độ trễ bằng thời lượng của hoạt ảnh đầu tiên). Bây giờ, hình ảnh đầu tiên sẽ hiển thị sau 1 giây và sau đó chỉ xoay 360 độ.
Một số hoạt ảnh có thể được kết hợp thành bộ bằng cách sử dụng thẻ. Một thẻ như vậy sẽ luôn có trong tệp và là thẻ gốc. Bạn có thể đặt các thuộc tính sau cho một bộ:
- khoảng thời gian(khoảng thời gian), Lặp lại các chế độ(chế độ lặp lại) - các thuộc tính này sẽ được áp dụng cho từng hoạt ảnh trong bộ
- bộ nội suy- xác định bộ nội suy hoạt ảnh và chia sẻInterpolator- liệu bộ nội suy này có được áp dụng cho từng hoạt ảnh trong bộ hay không (các giá trị có thể là “true” và “false”)
- bắt đầuOffset(độ trễ) - độ trễ cho toàn bộ bộ hoạt ảnh.
Thật không may, thuộc tính không thể được áp dụng cho tập hợp lặp lạiĐếm, nghĩa là, việc lặp lại một tập hợp hoạt ảnh nhiều lần sẽ không hiệu quả.
Các bộ có thể được lồng vào nhau.
10. Tạo ảnh động không cần xml
Hoạt hình có thể được tạo mà không cần cách sử dụng xml, trực tiếp trong mã chương trình. Đối với điều này, các lớp con cháu Animation được sử dụng:
1) AlphaAnimation để tạo hoạt ảnh alpha. Trình xây dựng lớp trông giống như
AlphaAnimation(float từ Alpha, float tới Alpha) trong đó fromAlpha và toAlpha lần lượt là giá trị độ trong suốt ban đầu và cuối cùng (từ 0,0 đến 1,0)
11.
Hãy tạo một hình động trong mã mà khi bạn nhấn nút, hình ảnh sẽ xoay hình ảnh theo một góc ngẫu nhiên (từ 0 đến 360) và phóng to nó lên kích thước ngẫu nhiên (không quá hai lần). Với mục đích này tôi đã thêm một nút khác RandomButton
RandomButton.setOnClickListener(new OnClickListener() ( @Override public void onClick(View v) ( Random Random = new Random (); //1 RotateAnimation xoay = new RotateAnimation (0, (float )random.nextInt(360), Animation. RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); //2 xoay.setDuration(1000); //3 xoay.setRepeatMode(Animation.REVERSE); //4 xoay.setRepeatCount(1); ); //6 kích thước float = ngẫu nhiên.nextFloat() + 1.0; //7 Thang đo ScalAnimation = Thang đo mới (1.0f, kích thước, 1.0f, kích thước, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF , 0.5f); //8 thang đo.setDuration(1000); thang đo.setStartOffset(thời lượng); //9 AnimationSet = new AnimationSet (false); //10 set.addAnimation (tỷ lệ image.startAnimation(set); );
1) Tạo đối tượng Random để tạo số ngẫu nhiên. Bạn có thể đọc thêm về Random trong tài liệu; bây giờ chúng ta quan tâm đến các phương thức int nextInt(int n) - tạo ra một số nguyên trong phạm vi từ 0 đến n. Và phương thức float nextFloat() - tạo một số thực từ 0 đến 1.
2) Tạo hoạt ảnh xoay. Góc bắt đầu = 0, góc kết thúc = một số ngẫu nhiên từ 0 đến 360. Animation.RELATIVE_TO_SELF có nghĩa là chúng ta sẽ chỉ định tâm xoay theo tỷ lệ phần trăm so với chiều rộng của phần tử. Đừng quên rằng giá trị 1.0 tương ứng với 100%, nghĩa là 0,5f là 50%. Điều này có nghĩa là tâm điểm xoay sẽ ở giữa bức ảnh.
3) Đặt thời lượng hoạt ảnh thành 1000 mili giây (đây là 1 giây)
4) Chúng ta xác định chế độ lặp lại là Animation.REVERSE, tức là khi lặp lại ảnh động chúng ta sẽ đi theo thứ tự ngược lại.
5) Đặt số lần lặp lại bổ sung = 1. Điều này có nghĩa là hoạt ảnh sẽ được lặp lại hai lần, một lần theo thứ tự thuận và một lần ngược lại.
6) Phương thức tính toánDurationHint() dài tính toán tổng thời gian hoạt ảnh sẽ kéo dài. Có một phương thức getDuration() nhưng nó chỉ trả về giá trị thời lượng mà chúng ta đặt bằng phương thức setDuration(). Trong trường hợp của chúng tôi, chúng tôi đặt giá trị thời lượng thành 1000 và phương thức getDuration() sẽ trả về 1000 và sẽ không tính đến việc hoạt ảnh sẽ lặp lại hai lần, có nghĩa là nó thực sự sẽ kéo dài 2000 mili giây. Phương thức tính toánDurationHint() sẽ tính toán thời lượng có tính đến số lần thử lại và độ trễ.
7) Tính kích thước mới của hình ảnh. Giá trị 1.0 là tỷ lệ hình ảnh hiện tại, vì vậy giá trị 2.0 có nghĩa là hình ảnh được nhân đôi. Chúng tôi tạo một số từ 0,0 đến 1,0 và thêm 1, có nghĩa là chúng tôi nhận được một số từ 1,0 đến 2,0
8) Tạo hoạt ảnh chia tỷ lệ từ kích thước hình ảnh hiện tại thành số được tạo ngẫu nhiên từ 1,0 đến 2,0
9) Đặt độ trễ bằng tổng thời lượng của hoạt ảnh xoay. Để hoạt ảnh thứ hai bắt đầu ngay sau khi kết thúc hoạt ảnh đầu tiên
10) Tạo một bộ ảnh động.
11) Thêm hai hình động đã tạo vào bộ
12) Áp dụng một bộ hoạt ảnh cho ảnh
12.
Một phương thức thú vị khác của lớp Animation
setAnimationListener(Trình nghe Animation.AnimationListener)- đặt trình lắng nghe để thay đổi trạng thái hoạt ảnh. Giao diện Animation.AnimationListener xác định các phương thức sau:
onAnimationStart (Hoạt hình hoạt hình)- được gọi khi hoạt ảnh bắt đầu
onAnimationRestart (Hoạt hình hoạt hình)- được gọi khi hoạt ảnh lặp lại
onAnimationEnd(Hoạt hình hoạt hình)- được gọi ở cuối hoạt ảnh
Ví dụ:
hoạt hình = AnimationUtils.loadAnimation(this, R.anim.anim); anim.setAnimationListener(new AnimationListener () ( @Override public void onAnimationEnd(Animation animation) ( Log.d("MY" , "animation end" ); ) @Override public void onAnimationRepeat(Animation animation) ( Log.d("MY " , "lặp lại hoạt ảnh"); ) @Override public void onAnimationStart(Hoạt hình hoạt hình) ( Log.d("MY" , "bắt đầu hoạt hình" ); ) ));
Chúng tôi không làm gì hữu ích khi thay đổi trạng thái hoạt ảnh, chúng tôi chỉ ghi nó vào nhật ký.
Đó là tất cả. Tôi đã nói với bạn những điều cơ bản, phần còn lại tốt hơn nên học thông qua thử nghiệm :)
Nguồn có thể được tải về ở đây
Api chuyển tiếp được bao gồm trong sdk android tiêu chuẩn. Vấn đề là hầu hết các tính năng của Transition Api chỉ có cho api 21+. Google gần đây đã nhập lại nhiều tính năng Transition Api cho api 19+, nhưng điều này có thể vẫn chưa đủ. Thư viện Transition Everywhere () đã giúp ích cho chúng tôi, đây là cổng hỗ trợ của Google Transitions cho các phiên bản trước đó. phiên bản android, lên tới android 4.0 (api 14). Ngoài ra, thư viện còn bao gồm nhiều tính năng khác.
Hãy để tôi tóm tắt ngắn gọn: nếu bạn đang phát triển một ứng dụng cho api 19 và không muốn kết nối thêm bất kỳ thứ gì, thì bạn có thể sử dụng Transition Api có trong sdk, nhưng nếu bạn cần hỗ trợ thêm phiên bản trước, thì bạn sẽ phải sử dụng một lib bổ sung, Transition-Everywhere (liên kết ở trên). Nó kết nối với một dòng:
Các phần phụ thuộc ( biên dịch "com.andkulikov:transitionseverywhere:1.7.0" )
Tại sao Api chuyển tiếp này tốt? Bởi vì nó rất dễ sử dụng và với sự trợ giúp của nó, bạn có thể thực hiện hầu hết các hoạt ảnh cần thiết. Để thực hiện một số hoạt ảnh bạn chỉ cần viết một dòng! Và thực hiện các hoạt ảnh phức tạp hơn cũng là một niềm vui :)
Cuối cùng, hãy bắt đầu.
Chúng ta hãy xem phương thức BeginDelayedTransition của TransitionManager. Tham số đầu tiên là Chế độ xem gốc, mà chúng tôi muốn áp dụng hoạt ảnh cho các thành viên của nó, bao gồm cả chế độ xem gốc. Với tham số thứ hai, chúng tôi chỉ ra loại hoạt ảnh sẽ được áp dụng. Nếu tham số thứ hai bị bỏ qua, AutoTransition mặc định sẽ được đặt. Sau khi gọi phương thức này, tất cả các Chế độ xem bên trong Chế độ xem gốc được chỉ định bởi tham số thứ 1 sẽ “lắng nghe” các hành động kích hoạt hoạt ảnh.
Hãy thực hiện hoạt ảnh cho văn bản biến mất. Đầu tiên, chúng ta chỉ ra vùng chứa Chế độ xem chứa Chế độ xem mà chúng ta cần tạo hiệu ứng. Trong trường hợp của chúng tôi, transitionContainer là một Bố cục tương đối và văn bản là một TextView nằm bên trong bố cục này. Hãy bỏ qua tham số thứ hai. Sau đó, chúng tôi thay đổi thuộc tính hiển thị của text để bắt đầu quá trình hoạt ảnh.
TransitionManager.beginDelayedTransition(transitionsContainer); có thể nhìn thấy = !có thể nhìn thấy; text.setVisibility(hiển thị? View.VISIBLE: View.GONE);
Kết quả:
Vì chúng tôi không chỉ định tham số thứ 2 trong BeginDelayedTransition nên Tự động chuyển đổi đã được áp dụng cho văn bản. Nó bao gồm các hoạt ảnh Fade và ChangeBounds. Hãy xem một ví dụ với loại hoạt ảnh Slide. Hãy làm cho văn bản trượt khỏi màn hình và biến mất. Để thực hiện việc này, chúng ta sẽ chỉ định loại Slide làm tham số thứ hai trong phương thức BeginDelayedTransition và chỉ ra hướng trượt bằng cách sử dụng Gravity . Sau đó, chúng tôi thay đổi thuộc tính hiển thị của văn bản.
TransitionManager.beginDelayedTransition(transitionsContainer, new Slide(Gravity.RIGHT)); có thể nhìn thấy = !có thể nhìn thấy; text.setVisibility(hiển thị? View.VISIBLE: View.GONE);
Kết quả:
Bây giờ chúng ta hãy xem một ví dụ với kiểu hoạt ảnh ChangeBounds, đồng thời gán một số tham số cho hoạt ảnh và xem kết quả. Hãy thực hiện chuyển động của nút từ phần này sang phần khác của màn hình và quay lại. Vì vậy, hãy xác định loại hoạt ảnh, chỉ định thời lượng cho cả hai hướng, xác định bộ nội suy và độ trễ bắt đầu của hoạt ảnh.
MToRightAnimation = !mToRightAnimation; Chuyển tiếp chuyển tiếp = new ChangeBounds(); transition.setDuration(mToRightAnimation ? 700: 300); transition.setInterpolator(mToRightAnimation ? FastOutSlowInInterpolator mới() : AccelerateInterpolator mới()); transition.setStartDelay(mToRightAnimation ? 0: 500);
Sau đó, trong lệnh gọi phương thức BeginDelayedTransition, chúng ta sẽ chỉ ra hoạt ảnh mà chúng ta đã xác định là tham số thứ 2 và xác định sự thay đổi trong tham số Bố cục của nút của chúng ta.
TransitionManager.beginDelayedTransition(transitionsContainer, transition); Thông số FrameLayout.LayoutParams = (FrameLayout.LayoutParams)button.getLayoutParams(); params.Gravity = mToRightAnimation ? (Gravity.RIGHT | Gravity.TOP) : (Gravity.LEFT | Gravity.TOP); nút.setLayoutParams(params);
Kết quả:
Chúng ta hãy xem một hoạt ảnh thú vị khác có thể được tạo bằng cách xác định ChangeBounds để di chuyển dọc theo đường dẫn bằng phương thức setPathMotion.
TransitionManager.beginDelayedTransition(transitionsContainer, new ChangeBounds().setPathMotion(new ArcMotion()).setDuration(500)); mToRightAnimation = !mToRightAnimation; Thông số FrameLayout.LayoutParams = (FrameLayout.LayoutParams) Button.getLayoutParams(); params.Gravity = mToRightAnimation ? (Gravity.RIGHT | Gravity.BOTTOM) : (Gravity.LEFT | Gravity.TOP); nút.setLayoutParams(params);
Kết quả:
Hãy thực hiện hoạt ảnh thay đổi màu sắc. Để làm được điều này, chúng ta cần một hình ảnh động như Recolor.
TransitionManager.beginDelayedTransition(transitionsContainer, new Recolor()); mColorsInverted = !mColorsInverted; nút.setTextColor(getResources().getColor(!mColorsInverted ? R.color.second_accent: R.color.accent)); nút.setBackgroundDrawable(ColorDrawable mới(getResources().getColor(!mColorsInverted ? R.color.accent: R.color.second_accent)));
Kết quả:
Hãy thực hiện hoạt ảnh xoay biểu tượng. Để làm điều này, chúng tôi sẽ sử dụng hoạt ảnh kiểu Xoay.
TransitionManager.beginDelayedTransition(transitionsContainer, new Rotate()); mRotated = !mRotated; icon.setRotation(mRotated ? 135: 0);
Kết quả:
Nhìn chung, như bạn có thể thấy ở trên, hầu hết các hoạt ảnh đều có những cái tên “nói” và không khó để hiểu mục đích của chúng.
Hãy xem cách áp dụng nhiều hình ảnh động cho một đối tượng. Chúng tôi thực hiện đồng thời việc biến mất văn bản với việc giảm bớt nó. Hãy xác định một bộ hoạt ảnh TransitionSet, bao gồm hoạt ảnh Tỷ lệ với hệ số giảm là 0,7 và hoạt ảnh Fade.
TransitionSet set = new TransitionSet() .addTransition(new Scale(0.7f)) .addTransition(new Fade()) .setInterpolator(visible ? new LinearOutSlowInInterpolator() : new FastOutLinearInInterpolator()); TransitionManager.beginDelayedTransition(transitionsContainer, set); text2.setVisibility(hiển thị? View.VISIBLE: View.INVISIBLE);
Kết quả:
Đối với bất kỳ Chuyển đổi nào, bạn có thể chỉ định nhiều yếu tố - mục tiêu mà nó sẽ được áp dụng.
Điều này được thực hiện bằng cách sử dụng các phương thức của lớp Transition: thêm mục tiêu- thêm một mục tiêu, loại bỏ mục tiêu- xóa mục tiêu đã chọn trước đó, loại trừ mục tiêu- một phương pháp mà bạn có thể áp dụng hành động “cho tất cả mọi người ngoại trừ” và loại trừTrẻ em mà bạn có thể loại trừ con của một bố cục nhất định.
Hãy xem một ví dụ sử dụng mục tiêu. Hãy triển khai một hoạt ảnh trong đó các ô của bảng sẽ phân tán khi bạn nhấp vào một trong các ô. Chúng tôi sử dụng hoạt ảnh Explode cho việc này.
TransitionManager.beginDelayedTransition(mRecyclerView, new Explode()); // xóa tất cả chế độ xem khỏi Chế độ xem tái chế mRecyclerView.setAdapter(null);
Kết quả:
Bây giờ, hãy đảm bảo rằng ô mà chúng ta đã nhấp vào không có hoạt ảnh Explode mà có hoạt ảnh Fade. Để làm điều này, chúng ta sẽ tạo một bộ gồm 2 animation Explode và Fade. Đối với Explode, bằng cách sử dụng phương thức loại trừTarget, chúng tôi sẽ loại trừ ô được nhấp và đối với phương thức Fade, sử dụng phương thức addTarget, chúng tôi sẽ chỉ thêm một mục tiêu - ô được nhấp vào.
Chế độ xem Rect cuối cùngRect = new Rect(); clickedView.getGlobalVisibleRect(viewRect); TransitionSet set = new TransitionSet() .addTransition(new Explode().setEpicenterCallback(new Transition.EpicenterCallback() ( @Override public Rect onGetEpicenter(Transition transition) ( return viewRect; )) .excludeTarget(clickedView, true)) .addTransition ( Fade mới().addTarget(clickedView)); TransitionManager.beginDelayedTransition(mRecyclerView, set);
Kết quả:
Bây giờ ô được nhấn vẫn giữ nguyên vị trí và biến mất một cách trơn tru, trong khi các ô còn lại phân tán.
Tôi hy vọng nó sẽ có ích. Cám ơn vì sự quan tâm của bạn!