Merge "Separate inflate from render step" into nyc-dev
This commit is contained in:
@@ -24,6 +24,7 @@ import com.android.ide.common.rendering.api.RenderSession;
|
||||
import com.android.ide.common.rendering.api.Result;
|
||||
import com.android.ide.common.rendering.api.Result.Status;
|
||||
import com.android.ide.common.rendering.api.SessionParams;
|
||||
import com.android.layoutlib.bridge.android.RenderParamsFlags;
|
||||
import com.android.layoutlib.bridge.impl.RenderDrawable;
|
||||
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
|
||||
import com.android.layoutlib.bridge.util.DynamicIdMap;
|
||||
@@ -408,7 +409,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
|
||||
/**
|
||||
* Starts a layout session by inflating and rendering it. The method returns a
|
||||
* {@link RenderSession} on which further actions can be taken.
|
||||
*
|
||||
* <p/>
|
||||
* If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE},
|
||||
* this method will only inflate the layout but will NOT render it.
|
||||
* @param params the {@link SessionParams} object with all the information necessary to create
|
||||
* the scene.
|
||||
* @return a new {@link RenderSession} object that contains the result of the layout.
|
||||
@@ -424,7 +427,10 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
|
||||
lastResult = scene.init(params.getTimeout());
|
||||
if (lastResult.isSuccess()) {
|
||||
lastResult = scene.inflate();
|
||||
if (lastResult.isSuccess()) {
|
||||
|
||||
boolean doNotRenderOnCreate = Boolean.TRUE.equals(
|
||||
params.getFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE));
|
||||
if (lastResult.isSuccess() && !doNotRenderOnCreate) {
|
||||
lastResult = scene.render(true /*freshRender*/);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,12 @@ public final class RenderParamsFlags {
|
||||
*/
|
||||
public static final Key<Boolean> FLAG_KEY_XML_FILE_PARSER_SUPPORT =
|
||||
new Key<Boolean>("xmlFileParser", Boolean.class);
|
||||
/**
|
||||
* To tell LayoutLib to not render when creating a new session. This allows controlling when the first
|
||||
* layout rendering will happen.
|
||||
*/
|
||||
public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE =
|
||||
new Key<Boolean>("doNotRenderOnCreate", Boolean.class);
|
||||
|
||||
// Disallow instances.
|
||||
private RenderParamsFlags() {}
|
||||
|
||||
@@ -266,6 +266,34 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
mElapsedFrameTimeNanos = nanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given view hierarchy to the passed canvas and returns the result of the render
|
||||
* operation.
|
||||
* @param canvas an optional canvas to render the views to. If null, only the measure and
|
||||
* layout steps will be executed.
|
||||
*/
|
||||
private static Result render(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot,
|
||||
@Nullable Canvas canvas, int width, int height) {
|
||||
// measure again with the size we need
|
||||
// This must always be done before the call to layout
|
||||
measureView(viewRoot, null /*measuredView*/,
|
||||
width, MeasureSpec.EXACTLY,
|
||||
height, MeasureSpec.EXACTLY);
|
||||
|
||||
// now do the layout.
|
||||
viewRoot.layout(0, 0, width, height);
|
||||
handleScrolling(context, viewRoot);
|
||||
|
||||
if (canvas == null) {
|
||||
return SUCCESS.createResult();
|
||||
}
|
||||
|
||||
AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
|
||||
viewRoot.draw(canvas);
|
||||
|
||||
return SUCCESS.createResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the scene.
|
||||
* <p>
|
||||
@@ -367,24 +395,12 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
}
|
||||
}
|
||||
|
||||
// measure again with the size we need
|
||||
// This must always be done before the call to layout
|
||||
measureView(mViewRoot, null /*measuredView*/,
|
||||
mMeasuredScreenWidth, MeasureSpec.EXACTLY,
|
||||
mMeasuredScreenHeight, MeasureSpec.EXACTLY);
|
||||
|
||||
// now do the layout.
|
||||
mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
|
||||
|
||||
handleScrolling(mViewRoot);
|
||||
|
||||
Result renderResult = SUCCESS.createResult();
|
||||
if (params.isLayoutOnly()) {
|
||||
// delete the canvas and image to reset them on the next full rendering
|
||||
mImage = null;
|
||||
mCanvas = null;
|
||||
} else {
|
||||
AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot);
|
||||
|
||||
// draw the views
|
||||
// create the BufferedImage into which the layout will be rendered.
|
||||
boolean newImage = false;
|
||||
@@ -446,6 +462,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
if (mElapsedFrameTimeNanos >= 0) {
|
||||
long initialTime = System_Delegate.nanoTime();
|
||||
if (!mFirstFrameExecuted) {
|
||||
// We need to run an initial draw call to initialize the animations
|
||||
render(getContext(), mViewRoot, mCanvas, 0, 0);
|
||||
|
||||
// The first frame will initialize the animations
|
||||
Choreographer_Delegate.doFrame(initialTime);
|
||||
mFirstFrameExecuted = true;
|
||||
@@ -453,14 +472,15 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
// Second frame will move the animations
|
||||
Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
|
||||
}
|
||||
mViewRoot.draw(mCanvas);
|
||||
renderResult = render(getContext(), mViewRoot, mCanvas, mMeasuredScreenWidth,
|
||||
mMeasuredScreenHeight);
|
||||
}
|
||||
|
||||
mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(),
|
||||
false);
|
||||
|
||||
// success!
|
||||
return SUCCESS.createResult();
|
||||
return renderResult;
|
||||
} catch (Throwable e) {
|
||||
// get the real cause of the exception.
|
||||
Throwable t = e;
|
||||
@@ -488,7 +508,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
* @return the measured width/height if measuredView is non-null, null otherwise.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // For the use of Pair
|
||||
private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
|
||||
private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
|
||||
int width, int widthMode, int height, int heightMode) {
|
||||
int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
|
||||
int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
|
||||
@@ -1061,8 +1081,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
* the component supports nested scrolling attempt that first, then use the unconsumed scroll
|
||||
* part to scroll the content in the component.
|
||||
*/
|
||||
private void handleScrolling(View view) {
|
||||
BridgeContext context = getContext();
|
||||
private static void handleScrolling(BridgeContext context, View view) {
|
||||
int scrollPosX = context.getScrollXPos(view);
|
||||
int scrollPosY = context.getScrollYPos(view);
|
||||
if (scrollPosX != 0 || scrollPosY != 0) {
|
||||
@@ -1080,7 +1099,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
}
|
||||
}
|
||||
if (scrollPosX != 0 || scrollPosY != 0) {
|
||||
view.scrollBy(scrollPosX, scrollPosY);
|
||||
view.scrollTo(scrollPosX, scrollPosY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,7 +1109,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
|
||||
ViewGroup group = (ViewGroup) view;
|
||||
for (int i = 0; i < group.getChildCount(); i++) {
|
||||
View child = group.getChildAt(i);
|
||||
handleScrolling(child);
|
||||
handleScrolling(context, child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollX="10px"
|
||||
android:scrollY="30px">
|
||||
android:scrollX="30px"
|
||||
android:scrollY="90px">
|
||||
<LinearLayout
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
@@ -29,8 +29,8 @@
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="400dp"
|
||||
android:orientation="vertical"
|
||||
android:scrollX="-30px"
|
||||
android:scrollY="150px">
|
||||
android:scrollX="-90px"
|
||||
android:scrollY="450px">
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="60dp"
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.android.ide.common.resources.configuration.FolderConfiguration;
|
||||
import com.android.io.FolderWrapper;
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
import com.android.layoutlib.bridge.android.RenderParamsFlags;
|
||||
import com.android.layoutlib.bridge.impl.RenderAction;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
|
||||
@@ -564,7 +565,7 @@ public class Main {
|
||||
sFrameworkRepo.getConfiguredResources(config),
|
||||
themeName, isProjectTheme);
|
||||
|
||||
return new SessionParams(
|
||||
SessionParams sessionParams = new SessionParams(
|
||||
layoutParser,
|
||||
renderingMode,
|
||||
null /*used for caching*/,
|
||||
@@ -574,6 +575,8 @@ public class Main {
|
||||
0,
|
||||
targetSdk,
|
||||
getLayoutLog());
|
||||
sessionParams.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true);
|
||||
return sessionParams;
|
||||
}
|
||||
|
||||
private static LayoutLog getLayoutLog() {
|
||||
|
||||
Reference in New Issue
Block a user