summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2011-01-07 12:47:31 -0800
committerXavier Ducrohet <xav@android.com>2011-01-07 12:49:49 -0800
commit2b9c38ab62abc8d5b2f956e961087f259caf25ff (patch)
tree8b48c79c6f861b71e4b1791b107df9e7e8add7ae /tools
parentfe75027c5c2bbb53f008ae5382de94ed8d37317b (diff)
downloadframeworks_base-2b9c38ab62abc8d5b2f956e961087f259caf25ff.zip
frameworks_base-2b9c38ab62abc8d5b2f956e961087f259caf25ff.tar.gz
frameworks_base-2b9c38ab62abc8d5b2f956e961087f259caf25ff.tar.bz2
LayoutLib: fix animated moveChild.
The child can only be added to the new viewgroup after it's been removed from the previous one, which is delayed if there's an animation. Change-Id: I9123a2670d0d17b3eb6f8f89085ebab8ca2b800f
Diffstat (limited to 'tools')
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java8
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java90
2 files changed, 80 insertions, 18 deletions
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
index 1651d6a..6eef581 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
@@ -39,7 +39,7 @@ import java.util.Queue;
* <p/>
* Classes should implement {@link #preAnimation()} and {@link #postAnimation()}.
* <p/>
- * If {@link #preAnimation()} does not start an animation something then the thread doesn't do
+ * If {@link #preAnimation()} does not start an animation somehow then the thread doesn't do
* anything.
*
*/
@@ -59,7 +59,7 @@ public abstract class AnimationThread extends Thread {
private final RenderSessionImpl mSession;
- Queue<MessageBundle> mQueue = new LinkedList<MessageBundle>();
+ private Queue<MessageBundle> mQueue = new LinkedList<MessageBundle>();
private final IAnimationListener mListener;
public AnimationThread(RenderSessionImpl scene, String threadName,
@@ -148,6 +148,10 @@ public abstract class AnimationThread extends Thread {
} while (mListener.isCanceled() == false && mQueue.size() > 0);
mListener.done(Status.SUCCESS.createResult());
+
+ } catch (Throwable throwable) {
+ Bridge.getLog().error(null, "Error playing animation", throwable);
+
} finally {
postAnimation();
Handler_Delegate.setCallback(null);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 5f86c92..b624f58 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -50,6 +50,7 @@ import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.LayoutTransition;
+import android.animation.LayoutTransition.TransitionListener;
import android.app.Fragment_Delegate;
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
@@ -626,7 +627,7 @@ public class RenderSessionImpl {
*
* @see LayoutScene#moveChild(Object, Object, int, Map, IAnimationListener)
*/
- public Result moveChild(final ViewGroup parentView, final View childView, final int index,
+ public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
Map<String, String> layoutParamsMap, IAnimationListener listener) {
checkLock();
@@ -635,23 +636,43 @@ public class RenderSessionImpl {
LayoutParams layoutParams = null;
if (layoutParamsMap != null) {
// need to create a new LayoutParams object for the new parent.
- layoutParams = parentView.generateLayoutParams(
+ layoutParams = newParentView.generateLayoutParams(
new BridgeLayoutParamsMapAttributes(layoutParamsMap));
}
+ // get the current parent of the view that needs to be moved.
+ final ViewGroup previousParent = (ViewGroup) childView.getParent();
+
if (listener != null) {
final LayoutParams params = layoutParams;
new AnimationThread(this, "moveChild", listener) {
@Override
public Result preAnimation() {
- parentView.setLayoutTransition(new LayoutTransition());
- return moveView(parentView, childView, index, params);
+ // set up the transition for the previous parent.
+ LayoutTransition removeTransition = new LayoutTransition();
+ previousParent.setLayoutTransition(removeTransition);
+
+ // no fade-out
+ removeTransition.setAnimator(LayoutTransition.DISAPPEARING, null);
+
+ // now for the new parent, if different
+ if (previousParent != newParentView) {
+ LayoutTransition addTransition = new LayoutTransition();
+
+ // no fade-in
+ addTransition.setAnimator(LayoutTransition.APPEARING, null);
+
+ newParentView.setLayoutTransition(addTransition);
+ }
+
+ return moveView(previousParent, newParentView, childView, index, params);
}
@Override
public void postAnimation() {
- parentView.setLayoutTransition(null);
+ previousParent.setLayoutTransition(null);
+ newParentView.setLayoutTransition(null);
}
}.start();
@@ -659,7 +680,7 @@ public class RenderSessionImpl {
return SUCCESS.createResult(layoutParams);
}
- Result result = moveView(parentView, childView, index, layoutParams);
+ Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
if (result.isSuccess() == false) {
return result;
}
@@ -676,7 +697,8 @@ public class RenderSessionImpl {
* Moves a View from its current parent to a new given parent at a new given location, with
* an optional new {@link LayoutParams} instance
*
- * @param parent the new parent
+ * @param previousParent the previous parent, still owning the child at the time of the call.
+ * @param newParent the new parent
* @param view the view to move
* @param index the new location in the new parent
* @param params an option (can be null) {@link LayoutParams} instance.
@@ -685,20 +707,56 @@ public class RenderSessionImpl {
* {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
* adding views.
*/
- private Result moveView(ViewGroup parent, View view, int index, LayoutParams params) {
+ private Result moveView(ViewGroup previousParent, final ViewGroup newParent, View view,
+ final int index, final LayoutParams params) {
try {
- ViewGroup previousParent = (ViewGroup) view.getParent();
- previousParent.removeView(view);
+ // check if there is a transition on the previousParent.
+ LayoutTransition transition = previousParent.getLayoutTransition();
+ if (transition != null) {
+ // in this case there is an animation. This means we have to listener for the
+ // disappearing animation to be done before we can add the view to the new parent.
+ // TODO: check that if the disappearing animation is null, the removal is done during the removeView call which would simplify the code.
+
+ // add a listener to the transition to be notified of the actual removal.
+ transition.addTransitionListener(new TransitionListener() {
+
+ public void startTransition(LayoutTransition transition, ViewGroup container,
+ View view, int transitionType) {
+ // don't care.
+ }
- // add it to the parentView in the correct location
+ public void endTransition(LayoutTransition transition, ViewGroup container,
+ View view, int transitionType) {
+ if (transitionType == LayoutTransition.DISAPPEARING) {
+ // add it to the parentView in the correct location
+ if (params != null) {
+ newParent.addView(view, index, params);
+ } else {
+ newParent.addView(view, index);
+ }
- if (params != null) {
- parent.addView(view, index, params);
+ }
+ }
+ });
+
+ // remove the view from the current parent.
+ previousParent.removeView(view);
+
+ // and return since adding the view to the new parent is done in the listener.
+ return SUCCESS.createResult();
} else {
- parent.addView(view, index);
- }
+ // standard code with no animation. pretty simple.
+ previousParent.removeView(view);
- return SUCCESS.createResult();
+ // add it to the parentView in the correct location
+ if (params != null) {
+ newParent.addView(view, index, params);
+ } else {
+ newParent.addView(view, index);
+ }
+
+ return SUCCESS.createResult();
+ }
} catch (UnsupportedOperationException e) {
// looks like this is a view class that doesn't support children manipulation!
return ERROR_VIEWGROUP_NO_CHILDREN.createResult();