編輯:關於Android編程
前面一篇文章講解了Android動畫Animator,但是不知道你有沒有發現,前面講解的所有的動畫都是針對某一Object來進行的,雖然我們可以對整個Layout添加動畫效果,但這是先把整個layout看成一個整體,再對這個整體添加動畫效果。當我們想同時對多個Object添加動畫效果時又該怎麼做呢?
先來看一下效果
一個Scene保存了一個ViewGroup中所有元素的狀。同時他還擁有一個關於這個ViewGroup的父ViewGroup的引用,這個父ViewGroup稱為scene root。
關於動畫的信息都存在一個Transition 對象中。通過 TransitionManager 使用Transition中動畫。Transitions 框架可以在兩個不同的Scene或者同一Scene的不同元素之間使用動畫。
Scene mAScene;
Scene mAnotherScene;
// Create the scene root for the scenes in this app
mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);
// Create the scenes
mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
mAnotherScene =
Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);
Transitions 框架允許自定義進入和退出Scene時的Action。把自定義的Action定義成Runnable對象並把他們作為參數傳到Scene.setExitAction() 或者 Scene.setEnterAction() 中。系統會在進入和退出的時候調用這兩個方法。
步驟如下:
1 . 在項目中添加res/transition/目錄
2 . 在目錄中新建XML文件
res/transition/fade_transition.xml
3 . 在Activity中加載
Transition mFadeTransition =
TransitionInflater.from(this).
inflateTransition(R.transition.fade_transition);
Transition mFadeTransition = new Fade();
TransitionManager.go(mEndingScene, mFadeTransition);
通過這一條語句,scene root中的View就會從初始狀態根據Transition 變為結束狀態。
由於Transition框架並不是對所有的對象都適用(比如ListView ),所以有時我們需要指定使用Transition的對象。
每一個使用Transition的對象叫做一個target,當然這個對象需要在Scene中。可以通過在開始transition前調用 removeTarget() 方法去除不支持的對象或者調用addTarget()來添加對象。
transitionSet類似Animation中的Set,是一個動畫集合。定義在XML中,如下:
在Activity中調用TransitionInflater.from() 來加載TransitionSet。TransitionSet繼承自Transition,能用Transition的地方都可以使用TransitionSet。
public class CustomTransition extends Transition {
@Override
public void captureStartValues(TransitionValues values) {}
@Override
public void captureEndValues(TransitionValues values) {}
@Override
public Animator createAnimator(ViewGroup sceneRoot,
TransitionValues startValues,
TransitionValues endValues) {}
}
框架會對開始Scene中的每一個對象調用captureStartValues()方法,方法的參數是TransitionValues 對象,這個對象包含對應這個View的一個引用和一個Map實例,這個Map實例用來保存你需要的屬性值,為了保證屬性值的Key不與其他的TransitionValues 的Key 沖突,推薦使用如下的命名規則。
package_name:transition_name:property_name
下面是一個重寫 captureStartValues() 的例子:
public class CustomTransition extends Transition {
// Define a key for storing a property value in
// TransitionValues.values with the syntax
// package_name:transition_class:property_name to avoid collisions
private static final String PROPNAME_BACKGROUND =
"com.example.android.customtransition:CustomTransition:background";
@Override
public void captureStartValues(TransitionValues transitionValues) {
// Call the convenience method captureValues
captureValues(transitionValues);
}
// For the view in transitionValues.view, get the values you
// want and put them in transitionValues.values
private void captureValues(TransitionValues transitionValues) {
// Get a reference to the view
View view = transitionValues.view;
// Store its background property in the values map
transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
}
...
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
與captureStartValues()類似,把結束的值放入TransitionValues 的Map對象中,captureEndValues()中的Map對象與captureStartValues()中的Map不是同一個對象,put()的時候請放心~
創建一個Animator用來負責從初始狀態到結束狀態的動畫效果,並把這個Animator返回。下面是一個改變背景顏色的例子。
// Create an animation for each target that is in both the starting and ending Scene. For each
// pair of targets, if their background property value is a color (rather than a graphic),
// create a ValueAnimator based on an ArgbEvaluator that interpolates between the starting and
// ending color. Also create an update listener that sets the View background color for each
// animation frame
@Override
public Animator createAnimator(ViewGroup sceneRoot,
TransitionValues startValues, TransitionValues endValues) {
// This transition can only be applied to views that are on both starting and ending scenes.
if (null == startValues || null == endValues) {
return null;
}
// Store a convenient reference to the target. Both the starting and ending layout have the
// same target.
final View view = endValues.view;
// Store the object containing the background property for both the starting and ending
// layouts.
Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
// This transition changes background colors for a target. It doesn't animate any other
// background changes. If the property isn't a ColorDrawable, ignore the target.
if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
ColorDrawable startColor = (ColorDrawable) startBackground;
ColorDrawable endColor = (ColorDrawable) endBackground;
// If the background color for the target in the starting and ending layouts is
// different, create an animation.
if (startColor.getColor() != endColor.getColor()) {
// Create a new Animator object to apply to the targets as the transitions framework
// changes from the starting to the ending layout. Use the class ValueAnimator,
// which provides a timing pulse to change property values provided to it. The
// animation runs on the UI thread. The Evaluator controls what type of
// interpolation is done. In this case, an ArgbEvaluator interpolates between two
// #argb values, which are specified as the 2nd and 3rd input arguments.
ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
startColor.getColor(), endColor.getColor());
// Add an update listener to the Animator object.
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Object value = animation.getAnimatedValue();
// Each time the ValueAnimator produces a new frame in the animation, change
// the background color of the target. Ensure that the value isn't null.
if (null != value) {
view.setBackgroundColor((Integer) value);
}
}
});
// Return the Animator object to the transitions framework. As the framework changes
// between the starting and ending layouts, it applies the animation you've created.
return animator;
}
}
// For non-ColorDrawable backgrounds, we just return null, and no animation will take place.
return null;
}
關於Android動畫的所有基本知識到此就講完了,Animation主要為了實現單個對象的動畫效果,Transitions 框架可以同時實現多個對象的動畫效果。在實際項目中還需要根據具體需求選擇。基本知識雖然講完了,但是如何實現優美的效果還是很考驗美術功底的,比如說博主就是一個典型的失敗例子/(ㄒoㄒ)/~~
一、前言前一段時間在做視頻開發,由於本人剛接觸視頻開發這塊,所以領導沒有對我提很高的要求,僅僅要求能夠播放本地視頻即可。我想怎麼簡單怎麼做。於是選擇用Android Vi
本文屬於個人平時項目開發過程遇到的一些問題,記錄下來並總結解決方案,希望能幫到大家解決問題,有些問題的解決方案是在StackoverFlow上找到的,建議大家遇到問題多去
為了兼容簡體、繁體及其他語系,推薦使用UTF-8編碼。 首選,我們看看Android端應該怎麼做: 在發送前,應該對參數值要進行UTF-8編碼,我寫了一個s
通過widget定義,我們在widget列表中看到了我們的TestWidget,當我們拖拽widget到主頁時,如果在appwidet-provider中定義了andr