Merge "LayoutLib: implement insert/move/removeChild."
This commit is contained in:
committed by
Android (Google) Code Review
commit
b63eef7662
@@ -23,6 +23,7 @@ import com.android.layoutlib.api.IXmlPullParser;
|
||||
import com.android.layoutlib.api.LayoutBridge;
|
||||
import com.android.layoutlib.api.SceneParams;
|
||||
import com.android.layoutlib.api.SceneResult;
|
||||
import com.android.layoutlib.api.SceneResult.SceneStatus;
|
||||
import com.android.layoutlib.bridge.android.BridgeAssetManager;
|
||||
import com.android.layoutlib.bridge.impl.FontLoader;
|
||||
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
|
||||
@@ -308,8 +309,13 @@ public final class Bridge extends LayoutBridge {
|
||||
|
||||
return new BridgeLayoutScene(scene, lastResult);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return new BridgeLayoutScene(null, new SceneResult("error!", t));
|
||||
// get the real cause of the exception.
|
||||
Throwable t2 = t;
|
||||
while (t2.getCause() != null) {
|
||||
t2 = t.getCause();
|
||||
}
|
||||
return new BridgeLayoutScene(null,
|
||||
new SceneResult(SceneStatus.ERROR_UNKNOWN, t2.getMessage(), t2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
|
||||
package com.android.layoutlib.bridge;
|
||||
|
||||
import com.android.layoutlib.api.IXmlPullParser;
|
||||
import com.android.layoutlib.api.LayoutScene;
|
||||
import com.android.layoutlib.api.SceneParams;
|
||||
import com.android.layoutlib.api.SceneResult;
|
||||
import com.android.layoutlib.api.ViewInfo;
|
||||
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -92,13 +96,86 @@ public class BridgeLayoutScene extends LayoutScene {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// TODO Auto-generated method stub
|
||||
public SceneResult insertChild(Object parentView, IXmlPullParser childXml, Object beforeSibling,
|
||||
IAnimationListener listener) {
|
||||
if (parentView instanceof ViewGroup == false) {
|
||||
throw new IllegalArgumentException("parentView is not a ViewGroup");
|
||||
}
|
||||
if (beforeSibling != null && beforeSibling instanceof View == false) {
|
||||
throw new IllegalArgumentException("beforeSibling is not a View");
|
||||
}
|
||||
|
||||
try {
|
||||
mScene.prepareThread();
|
||||
mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
|
||||
if (mLastResult == SceneResult.SUCCESS) {
|
||||
mLastResult = mScene.insertChild((ViewGroup) parentView, childXml,
|
||||
(View) beforeSibling, listener);
|
||||
}
|
||||
} finally {
|
||||
mScene.release();
|
||||
mScene.cleanupThread();
|
||||
}
|
||||
|
||||
return mLastResult;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SceneResult moveChild(Object parentView, Object childView, Object beforeSibling,
|
||||
IAnimationListener listener) {
|
||||
if (parentView instanceof ViewGroup == false) {
|
||||
throw new IllegalArgumentException("parentView is not a ViewGroup");
|
||||
}
|
||||
if (childView instanceof View == false) {
|
||||
throw new IllegalArgumentException("childView is not a View");
|
||||
}
|
||||
if (beforeSibling != null && beforeSibling instanceof View == false) {
|
||||
throw new IllegalArgumentException("beforeSibling is not a View");
|
||||
}
|
||||
|
||||
try {
|
||||
mScene.prepareThread();
|
||||
mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
|
||||
if (mLastResult == SceneResult.SUCCESS) {
|
||||
mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView,
|
||||
(View) beforeSibling, listener);
|
||||
}
|
||||
} finally {
|
||||
mScene.release();
|
||||
mScene.cleanupThread();
|
||||
}
|
||||
|
||||
return mLastResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SceneResult removeChild(Object childView, IAnimationListener listener) {
|
||||
if (childView instanceof View == false) {
|
||||
throw new IllegalArgumentException("childView is not a View");
|
||||
}
|
||||
|
||||
try {
|
||||
mScene.prepareThread();
|
||||
mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
|
||||
if (mLastResult == SceneResult.SUCCESS) {
|
||||
mLastResult = mScene.removeChild((View) childView, listener);
|
||||
}
|
||||
} finally {
|
||||
mScene.release();
|
||||
mScene.cleanupThread();
|
||||
}
|
||||
|
||||
return mLastResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/*package*/ BridgeLayoutScene(LayoutSceneImpl scene, SceneResult lastResult) {
|
||||
mScene = scene;
|
||||
mScene.setScene(this);
|
||||
mLastResult = lastResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class AnimationThread extends Thread {
|
||||
try {
|
||||
bundle.mTarget.handleMessage(bundle.mMessage);
|
||||
if (mScene.render() == SceneResult.SUCCESS) {
|
||||
mListener.onNewFrame(mScene.getImage());
|
||||
mListener.onNewFrame(mScene.getScene());
|
||||
}
|
||||
} finally {
|
||||
mScene.release();
|
||||
|
||||
@@ -24,13 +24,16 @@ import com.android.internal.util.XmlUtils;
|
||||
import com.android.layoutlib.api.IProjectCallback;
|
||||
import com.android.layoutlib.api.IResourceValue;
|
||||
import com.android.layoutlib.api.IStyleResourceValue;
|
||||
import com.android.layoutlib.api.IXmlPullParser;
|
||||
import com.android.layoutlib.api.LayoutBridge;
|
||||
import com.android.layoutlib.api.LayoutScene;
|
||||
import com.android.layoutlib.api.SceneParams;
|
||||
import com.android.layoutlib.api.SceneResult;
|
||||
import com.android.layoutlib.api.ViewInfo;
|
||||
import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
|
||||
import com.android.layoutlib.api.LayoutScene.IAnimationListener;
|
||||
import com.android.layoutlib.api.SceneParams.RenderingMode;
|
||||
import com.android.layoutlib.api.SceneResult.SceneStatus;
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.BridgeConstants;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
@@ -53,6 +56,7 @@ import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.View.AttachInfo;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -92,6 +96,7 @@ public class LayoutSceneImpl {
|
||||
private final SceneParams mParams;
|
||||
|
||||
// scene state
|
||||
private LayoutScene mScene;
|
||||
private BridgeContext mContext;
|
||||
private BridgeXmlBlockParser mBlockParser;
|
||||
private BridgeInflater mInflater;
|
||||
@@ -362,7 +367,7 @@ public class LayoutSceneImpl {
|
||||
|
||||
return SceneResult.SUCCESS;
|
||||
} catch (PostInflateException e) {
|
||||
return new SceneResult("Error during post inflation process:\n" + e.getMessage());
|
||||
return new SceneResult(SceneStatus.ERROR_INFLATION, e.getMessage(), e);
|
||||
} catch (Throwable e) {
|
||||
// get the real cause of the exception.
|
||||
Throwable t = e;
|
||||
@@ -373,7 +378,7 @@ public class LayoutSceneImpl {
|
||||
// log it
|
||||
mParams.getLogger().error(t);
|
||||
|
||||
return new SceneResult("Unknown error during inflation.", t);
|
||||
return new SceneResult(SceneStatus.ERROR_INFLATION, t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +396,7 @@ public class LayoutSceneImpl {
|
||||
try {
|
||||
long current = System.currentTimeMillis();
|
||||
if (mViewRoot == null) {
|
||||
return new SceneResult("Layout has not been inflated!");
|
||||
return new SceneResult(SceneStatus.ERROR_NOT_INFLATED);
|
||||
}
|
||||
// measure the views
|
||||
int w_spec, h_spec;
|
||||
@@ -487,7 +492,7 @@ public class LayoutSceneImpl {
|
||||
// log it
|
||||
mParams.getLogger().error(t);
|
||||
|
||||
return new SceneResult("Unknown error during rendering.", t);
|
||||
return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,12 +535,74 @@ public class LayoutSceneImpl {
|
||||
return SceneResult.SUCCESS;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new SceneResult("", e);
|
||||
// get the real cause of the exception.
|
||||
Throwable t = e;
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
|
||||
return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
return new SceneResult("Failed to find animation");
|
||||
return new SceneResult(SceneStatus.ERROR_ANIM_NOT_FOUND);
|
||||
}
|
||||
|
||||
public SceneResult insertChild(ViewGroup parentView, IXmlPullParser childXml,
|
||||
View beforeSibling, IAnimationListener listener) {
|
||||
checkLock();
|
||||
|
||||
int index = parentView.indexOfChild(beforeSibling);
|
||||
if (beforeSibling != null && index == -1) {
|
||||
throw new IllegalArgumentException("beforeSibling not in parentView");
|
||||
}
|
||||
|
||||
// create a block parser for the XML
|
||||
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, mContext,
|
||||
false /* platformResourceFlag */);
|
||||
|
||||
// inflate the child without adding it to the root since we want to control where it'll
|
||||
// get added. We do pass the parentView however to ensure that the layoutParams will
|
||||
// be created correctly.
|
||||
View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
|
||||
|
||||
// add it to the parentView in the correct location
|
||||
parentView.addView(child, index);
|
||||
|
||||
return render();
|
||||
}
|
||||
|
||||
public SceneResult moveChild(ViewGroup parentView, View childView, View beforeSibling,
|
||||
IAnimationListener listener) {
|
||||
checkLock();
|
||||
|
||||
int index = parentView.indexOfChild(beforeSibling);
|
||||
if (beforeSibling != null && index == -1) {
|
||||
throw new IllegalArgumentException("beforeSibling not in parentView");
|
||||
}
|
||||
|
||||
ViewParent parent = childView.getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
ViewGroup parentGroup = (ViewGroup) parent;
|
||||
parentGroup.removeView(childView);
|
||||
}
|
||||
|
||||
// add it to the parentView in the correct location
|
||||
parentView.addView(childView, index);
|
||||
|
||||
return render();
|
||||
}
|
||||
|
||||
public SceneResult removeChild(View childView, IAnimationListener listener) {
|
||||
checkLock();
|
||||
|
||||
ViewParent parent = childView.getParent();
|
||||
if (parent instanceof ViewGroup) {
|
||||
ViewGroup parentGroup = (ViewGroup) parent;
|
||||
parentGroup.removeView(childView);
|
||||
}
|
||||
|
||||
return render();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -915,4 +982,12 @@ public class LayoutSceneImpl {
|
||||
public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
|
||||
return mContext.getDefaultPropMap(viewObject);
|
||||
}
|
||||
|
||||
public void setScene(LayoutScene scene) {
|
||||
mScene = scene;
|
||||
}
|
||||
|
||||
public LayoutScene getScene() {
|
||||
return mScene;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user