diff --git a/android/sample/AndroidManifest.xml b/android/sample/AndroidManifest.xml
index e5da6654..a47e1e0d 100644
--- a/android/sample/AndroidManifest.xml
+++ b/android/sample/AndroidManifest.xml
@@ -22,6 +22,8 @@
android:targetSdkVersion="19"
/>
+
+
+
+
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkActivity.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkActivity.java
new file mode 100644
index 00000000..fa1fb54b
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkActivity.java
@@ -0,0 +1,113 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.Menu;
+import android.support.v7.app.ActionBar;
+
+import com.facebook.samples.yoga.R;
+import com.facebook.yoga.android.YogaViewLayoutFactory;
+
+public class BenchmarkActivity extends ActionBarActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance());
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.benchmark_select_layout);
+
+ ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
+ viewPager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
+
+ final ActionBar actionBar = getSupportActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+
+ ActionBar.TabListener tabListener = new ActionBar.TabListener() {
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
+ ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
+ viewPager.setCurrentItem(tab.getPosition());
+ }
+
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+ };
+ actionBar.addTab(
+ actionBar.newTab()
+ .setText("Inflate")
+ .setTabListener(tabListener));
+ actionBar.addTab(
+ actionBar.newTab()
+ .setText("Measure")
+ .setTabListener(tabListener));
+ actionBar.addTab(
+ actionBar.newTab()
+ .setText("Layout")
+ .setTabListener(tabListener));
+
+ viewPager.setOnPageChangeListener(
+ new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ // When swiping between pages, select the
+ // corresponding tab.
+ actionBar.setSelectedNavigationItem(position);
+ }
+ });
+
+ viewPager.setOffscreenPageLimit(3);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.action_bar_benchmark, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // There is only one option
+ Intent intent = new Intent(this, MainActivity.class);
+ startActivity(intent);
+ this.finish();
+ return true;
+ }
+
+ public static class PagerAdapter extends FragmentPagerAdapter {
+ public PagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int i) {
+ switch (i) {
+ case 0:
+ return new BenchmarkInflate();
+ case 1:
+ return new BenchmarkMeasure();
+ default:
+ return new BenchmarkLayout();
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return 3;
+ }
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkAggregator.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkAggregator.java
new file mode 100644
index 00000000..2fc57896
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkAggregator.java
@@ -0,0 +1,193 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.lang.Math;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.text.DateFormat;
+import java.util.Date;
+
+import android.content.Context;
+import android.util.Log;
+import android.os.Environment;
+
+import static java.util.Collections.sort;
+
+public class BenchmarkAggregator {
+
+ private final int GRAPH_WIDTH = 30;
+ private final int GRAPH_HEIGHT = 6;
+
+ private List times;
+ private boolean tracing;
+ private long lastTraceStart;
+
+ private boolean statsFresh;
+ private long mean;
+ private long variance;
+ private long stddev;
+ private long min;
+ private long max;
+ private long p10;
+ private long p50;
+ private long p90;
+
+ private String name;
+
+ public BenchmarkAggregator(String name) {
+ times = new ArrayList<>();
+ tracing = false;
+ this.name = name;
+ }
+
+ public void startTrace() {
+ if (tracing) {
+ throw new RuntimeException("Cannot start trace while running previous one");
+ }
+ tracing = true;
+ lastTraceStart = System.nanoTime();
+ }
+
+ public void endTrace() {
+ if (!tracing) {
+ throw new RuntimeException("Cannot stop trace if none are running!");
+ }
+ times.add(System.nanoTime() - lastTraceStart);
+ tracing = false;
+ statsFresh = false;
+ }
+
+ private void computeStats() {
+ if (statsFresh) {
+ return;
+ }
+
+ sort(times);
+
+ min = Long.MAX_VALUE;
+ max = -1;
+ mean = 0;
+ for (long f: times) {
+ mean += f;
+ if (f < min) {
+ min = f;
+ }
+ if (f > max) {
+ max = f;
+ }
+ }
+ mean /= times.size();
+
+ variance = 0;
+ for (long f: times) {
+ variance += (f-mean)*(f-mean);
+ }
+ variance /= times.size();
+ stddev = (long) Math.sqrt((double) variance);
+
+ p10 = times.get(times.size()*10/100);
+ p50 = times.get(times.size()*50/100);
+ p90 = times.get(times.size()*90/100);
+
+ statsFresh = true;
+ }
+
+ public String toString() {
+ computeStats();
+ return String.format(
+ "%s:\n" +
+ "| %d samples\n" +
+ "| Mean %.3f\u00B1%.3fms\n" + // plusminus
+ "| Min %.3fms ; Max %.3fms\n" +
+ "| p10 %.3fms ; p50 %.3fms ; p90 %.3fms\n" +
+ "%s",
+ name,
+ times.size(),
+ mean/10e6,
+ stddev/10e6,
+ min/10e6,
+ max/10e6,
+ p10/10e6,
+ p50/10e6,
+ p90/10e6,
+ makeGraph());
+ }
+
+ private String makeGraph() {
+ char canvas[][] = new char[GRAPH_HEIGHT][GRAPH_WIDTH];
+ for (int i = 0; i < GRAPH_HEIGHT; i++)
+ for (int j = 0; j < GRAPH_WIDTH; j++)
+ canvas[i][j] = ' ';
+
+ long bucketSize = (p90 - p10) / GRAPH_WIDTH+1;
+ int bucketCount[] = new int[GRAPH_WIDTH];
+ for (long time : times) {
+ if (timep10) {
+ bucketCount[(int) ((time - p10) / bucketSize)]++;
+ }
+ }
+
+ int maxBucket = 0;
+ for (int i = 0; i < GRAPH_WIDTH; i++)
+ if (bucketCount[i] > maxBucket) {
+ maxBucket = bucketCount[i];
+ }
+
+ for (int i = 0; i < GRAPH_HEIGHT; i++)
+ for (int j = 0; j < GRAPH_WIDTH; j++)
+ if (i < bucketCount[j] * GRAPH_HEIGHT / maxBucket) {
+ canvas[i][j] = 'Z';
+ }
+
+ String graph = new String();
+ for (int i = 0; i < GRAPH_HEIGHT; i++)
+ {
+ int percentage = 100 * (GRAPH_HEIGHT - i - 1) * maxBucket / (times.size() * GRAPH_HEIGHT);
+ graph += String.format("| %2d%% ", percentage);
+ for (int j = 0; j < GRAPH_WIDTH; j++)
+ graph += canvas[GRAPH_HEIGHT-1-i][j];
+ graph += '\n';
+ }
+
+ graph += "| p10";
+ for (int i = 0; i < GRAPH_WIDTH-6; i++)
+ graph += " ";
+ graph += "p90\n";
+ return graph;
+ }
+
+ /**
+ * Dumps the collected times to a file on the device. This allows us to grab the raw data
+ * and perform more in-depth analysis.
+ */
+ public void dump(Context context) {
+ String state = Environment.getExternalStorageState();
+ if (!Environment.MEDIA_MOUNTED.equals(state)) {
+ Log.e("YogaLayoutBenchmark","No external file storage");
+ return;
+ }
+
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+ String filename = format.format(new Date()) + "_" + name.replace(' ','_');
+ File file = new File(context.getExternalFilesDir(
+ Environment.DIRECTORY_DOCUMENTS), filename);
+
+ try {
+ PrintWriter printWriter = new PrintWriter(file);
+ for (long l : times) {
+ printWriter.println(l);
+ }
+ printWriter.close();
+
+ Log.i("YogaLayoutBenchmark","Benchmark data saved in "+file.getPath());
+ } catch (java.io.IOException e) {
+ Log.e("YogaLayoutBenchmark", "Could not save benchmark data", e);
+ }
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkFragment.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkFragment.java
new file mode 100644
index 00000000..bc692290
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkFragment.java
@@ -0,0 +1,110 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+
+import java.util.Random;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.ArrayAdapter;
+import android.widget.AdapterView;
+
+import com.facebook.samples.yoga.R;
+import com.facebook.yoga.android.YogaLayout;
+
+public class BenchmarkFragment extends Fragment implements AdapterView.OnItemSelectedListener {
+ private LayoutInflater mInflater;
+
+ protected com.facebook.yoga.android.YogaLayout rootLayout;
+ protected int yogaLayout;
+ protected int linearLayout;
+
+ static final Random random = new Random();
+
+ static void randomizeText(View root) {
+ if (root instanceof TextView) {
+ ((TextView) root).setText("" + random.nextInt(1000));
+ ((TextView) root).setTextSize(10 + random.nextInt(20));
+ ViewParent parent = root.getParent();
+ if (parent instanceof YogaLayout) {
+ ((YogaLayout) parent).invalidate(root);
+ }
+ } else if (root instanceof ViewGroup) {
+ for (int i = 0; i < ((ViewGroup) root).getChildCount(); i++) {
+ randomizeText(((ViewGroup) root).getChildAt(i));
+ }
+ }
+ }
+
+ public BenchmarkFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ mInflater = inflater;
+
+ rootLayout = (YogaLayout) inflater.inflate(
+ R.layout.benchmark_fragment,
+ container,
+ false);
+
+ Spinner benchmarkSelect = (Spinner) rootLayout.findViewById(R.id.benchmarkSelect);
+ String[] items = new String[]{"Basic", "Typical", "Nested"};
+ ArrayAdapter adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_dropdown_item, items);
+ benchmarkSelect.setAdapter(adapter);
+ benchmarkSelect.setOnItemSelectedListener(this);
+ return rootLayout;
+ }
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
+ switch (pos) {
+ case 0:
+ yogaLayout = R.layout.benchmark_layout_1;
+ linearLayout = R.layout.benchmark_layout_1_linear;
+ break;
+ case 1:
+ yogaLayout = R.layout.benchmark_layout_2;
+ linearLayout = R.layout.benchmark_layout_2_linear;
+ break;
+ case 2:
+ default:
+ yogaLayout = R.layout.benchmark_layout_3;
+ linearLayout = R.layout.benchmark_layout_3_linear;
+ break;
+ }
+ updatePreview();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ yogaLayout = R.layout.benchmark_layout_1;
+ linearLayout = R.layout.benchmark_layout_1_linear;
+ updatePreview();
+ }
+
+ private void updatePreview() {
+ LinearLayout previewLayout = (LinearLayout) rootLayout.findViewById(R.id.preview);
+ View v = mInflater.inflate(yogaLayout, rootLayout, false);
+ v.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT));
+ previewLayout.removeAllViews();
+ previewLayout.addView(v);
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkInflate.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkInflate.java
new file mode 100644
index 00000000..b3a24474
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkInflate.java
@@ -0,0 +1,65 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Button;
+import android.view.ViewGroup;
+import android.util.Log;
+import com.facebook.samples.yoga.R;
+
+public class BenchmarkInflate extends BenchmarkFragment {
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ Button b = (Button) rootLayout.findViewById(R.id.btn);
+ b.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startBenchmark();
+ }
+ });
+
+ return rootLayout;
+ }
+
+ protected void startBenchmark() {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ TextView textView = (TextView) rootLayout.findViewById(R.id.text);
+
+ final int ITERATIONS = 500;
+
+ inflater.inflate(yogaLayout, null);
+ inflater.inflate(linearLayout, null);
+
+ BenchmarkAggregator yogaInflationAggregator = new BenchmarkAggregator("Yoga Inflate");
+ BenchmarkAggregator linearInflationAggregator = new BenchmarkAggregator("Linear Inflate");
+ for (int i = 0; i < ITERATIONS; i++) {
+ yogaInflationAggregator.startTrace();
+ inflater.inflate(yogaLayout, null);
+ yogaInflationAggregator.endTrace();
+ linearInflationAggregator.startTrace();
+ inflater.inflate(linearLayout, null);
+ linearInflationAggregator.endTrace();
+ }
+
+ textView.setText(
+ yogaInflationAggregator.toString()+
+ "\n"+
+ linearInflationAggregator.toString());
+ Log.i(
+ "YogaLayoutBenchmark",
+ yogaInflationAggregator.toString()+
+ "\n"+
+ linearInflationAggregator.toString());
+ rootLayout.invalidate();
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkLayout.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkLayout.java
new file mode 100644
index 00000000..8fdcdb64
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkLayout.java
@@ -0,0 +1,74 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import com.facebook.samples.yoga.R;
+
+import java.util.Random;
+
+public class BenchmarkLayout extends BenchmarkFragment {
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ Button b = (Button) rootLayout.findViewById(R.id.btn);
+ b.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startBenchmark();
+ }
+ });
+
+ return rootLayout;
+ }
+
+ protected void startBenchmark() {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ TextView textView = (TextView) rootLayout.findViewById(R.id.text);
+ Random random = new Random();
+
+ final int ITERATIONS = 500;
+
+ BenchmarkAggregator yogaInflationAggregator = new BenchmarkAggregator("Yoga Layout");
+ BenchmarkAggregator linearInflationAggregator = new BenchmarkAggregator("Linear Layout");
+ View yogaView = inflater.inflate(yogaLayout, null);
+ View linearView = inflater.inflate(linearLayout, null);
+ for (int i = 0; i < ITERATIONS; i++) {
+ randomizeText(yogaView);
+ randomizeText(linearView);
+ yogaView.measure(
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
+ linearView.measure(
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
+ yogaInflationAggregator.startTrace();
+ yogaView.layout(0, 0, yogaView.getMeasuredWidth(), yogaView.getMeasuredHeight());
+ yogaInflationAggregator.endTrace();
+ linearInflationAggregator.startTrace();
+ linearView.layout(0, 0, linearView.getMeasuredWidth(), linearView.getMeasuredHeight());
+ linearInflationAggregator.endTrace();
+ }
+
+ textView.setText(
+ yogaInflationAggregator.toString()+
+ "\n"+
+ linearInflationAggregator.toString());
+ Log.i(
+ "YogaLayoutBenchmark",
+ yogaInflationAggregator.toString()+
+ "\n"+
+ linearInflationAggregator.toString());
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/BenchmarkMeasure.java b/android/sample/java/com/facebook/samples/yoga/BenchmarkMeasure.java
new file mode 100644
index 00000000..51151878
--- /dev/null
+++ b/android/sample/java/com/facebook/samples/yoga/BenchmarkMeasure.java
@@ -0,0 +1,75 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.facebook.samples.yoga;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import com.facebook.samples.yoga.R;
+
+import java.util.Random;
+
+public class BenchmarkMeasure extends BenchmarkFragment {
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+
+ Button b = (Button) rootLayout.findViewById(R.id.btn);
+ b.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startBenchmark();
+ }
+ });
+
+ return rootLayout;
+ }
+
+ protected void startBenchmark() {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ TextView textView = (TextView) rootLayout.findViewById(R.id.text);
+ Random random = new Random();
+
+ final int ITERATIONS = 500;
+
+ BenchmarkAggregator yogaMeasureAggregator = new BenchmarkAggregator("Yoga Measure");
+ BenchmarkAggregator linearMeasureAggregator = new BenchmarkAggregator("Linear Measure");
+ View yogaView = inflater.inflate(yogaLayout, null);
+ View linearView = inflater.inflate(linearLayout, null);
+ for (int i = 0; i < ITERATIONS; i++) {
+ randomizeText(yogaView);
+ randomizeText(linearView);
+ yogaMeasureAggregator.startTrace();
+ yogaView.measure(
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
+ yogaMeasureAggregator.endTrace();
+ linearMeasureAggregator.startTrace();
+ linearView.measure(
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
+ linearMeasureAggregator.endTrace();
+ }
+
+ textView.setText(
+ yogaMeasureAggregator.toString()+
+ "\n"+
+ linearMeasureAggregator.toString());
+ Log.i(
+ "YogaLayoutBenchmark",
+ yogaMeasureAggregator.toString()+
+ "\n"+
+ linearMeasureAggregator.toString());
+
+ yogaMeasureAggregator.dump(getActivity());
+ linearMeasureAggregator.dump(getActivity());
+ }
+}
diff --git a/android/sample/java/com/facebook/samples/yoga/MainActivity.java b/android/sample/java/com/facebook/samples/yoga/MainActivity.java
index 52649a1a..fbc45b99 100644
--- a/android/sample/java/com/facebook/samples/yoga/MainActivity.java
+++ b/android/sample/java/com/facebook/samples/yoga/MainActivity.java
@@ -8,9 +8,13 @@
package com.facebook.samples.yoga;
+import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.Menu;
import com.facebook.samples.yoga.R;
import com.facebook.soloader.SoLoader;
@@ -31,4 +35,20 @@ public class MainActivity extends ActionBarActivity {
setContentView(R.layout.main_layout);
}
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.action_bar_home, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // There is only one option
+ Intent intent = new Intent(this, BenchmarkActivity.class);
+ startActivity(intent);
+ this.finish();
+ return true;
+ }
}
diff --git a/android/sample/res/layout/benchmark_fragment.xml b/android/sample/res/layout/benchmark_fragment.xml
new file mode 100644
index 00000000..6f9bdbd9
--- /dev/null
+++ b/android/sample/res/layout/benchmark_fragment.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_1.xml b/android/sample/res/layout/benchmark_layout_1.xml
new file mode 100644
index 00000000..e589be0f
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_1.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_1_linear.xml b/android/sample/res/layout/benchmark_layout_1_linear.xml
new file mode 100644
index 00000000..033846d5
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_1_linear.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_2.xml b/android/sample/res/layout/benchmark_layout_2.xml
new file mode 100644
index 00000000..49022e0e
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_2.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_2_linear.xml b/android/sample/res/layout/benchmark_layout_2_linear.xml
new file mode 100644
index 00000000..f77426f3
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_2_linear.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_3.xml b/android/sample/res/layout/benchmark_layout_3.xml
new file mode 100644
index 00000000..bbc9bb29
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_3.xml
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_layout_3_linear.xml b/android/sample/res/layout/benchmark_layout_3_linear.xml
new file mode 100644
index 00000000..7768c451
--- /dev/null
+++ b/android/sample/res/layout/benchmark_layout_3_linear.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/sample/res/layout/benchmark_select_layout.xml b/android/sample/res/layout/benchmark_select_layout.xml
new file mode 100644
index 00000000..d3de70a0
--- /dev/null
+++ b/android/sample/res/layout/benchmark_select_layout.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/android/sample/res/menu/action_bar_benchmark.xml b/android/sample/res/menu/action_bar_benchmark.xml
new file mode 100644
index 00000000..618f6f37
--- /dev/null
+++ b/android/sample/res/menu/action_bar_benchmark.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/android/sample/res/menu/action_bar_home.xml b/android/sample/res/menu/action_bar_home.xml
new file mode 100644
index 00000000..9fb78394
--- /dev/null
+++ b/android/sample/res/menu/action_bar_home.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
diff --git a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java
index 2f5b7d43..00478f90 100644
--- a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java
+++ b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java
@@ -23,6 +23,7 @@ import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.util.Log;
import com.facebook.yoga.android.R;
import com.facebook.yoga.YogaAlign;
@@ -278,6 +279,7 @@ public class YogaLayout extends ViewGroup {
private void applyLayoutRecursive(YogaNode node, float xOffset, float yOffset) {
View view = (View) node.getData();
+
if (view != null && view != this) {
if (view.getVisibility() == GONE) {
return;
@@ -360,7 +362,6 @@ public class YogaLayout extends ViewGroup {
if (widthMode == MeasureSpec.AT_MOST) {
mYogaNode.setMaxWidth(widthSize);
}
-
mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
}
diff --git a/lib/soloader/soloader-0.1.0.aar b/lib/soloader/soloader-0.1.0.aar
index 765e7437..497494a9 100644
Binary files a/lib/soloader/soloader-0.1.0.aar and b/lib/soloader/soloader-0.1.0.aar differ