Let the Yoga sample app compile
Summary: The sample app is really old and has a lot of legacy code. Here I'm refreshing it a bit. Will do another pass later (perhaps rewrite it in Kotlin?). Reviewed By: mdvacca Differential Revision: D45694414 fbshipit-source-id: 36a84609b0dcf5b4a5237da900f665e4eb7895a5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
420f0016c6
commit
172bd0a88e
32
sample/build.gradle
Normal file
32
sample/build.gradle
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
namespace 'com.facebook.yoga.sample'
|
||||
|
||||
compileSdkVersion rootProject.compileSdkVersion
|
||||
buildToolsVersion rootProject.buildToolsVersion
|
||||
ndkVersion rootProject.ndkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.minSdkVersion
|
||||
targetSdkVersion rootProject.targetSdkVersion
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
targetCompatibility rootProject.targetCompatibilityVersion
|
||||
sourceCompatibility rootProject.sourceCompatibilityVersion
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':yoga-layout')
|
||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation("com.facebook.soloader:soloader:0.10.4")
|
||||
}
|
28
sample/src/main/AndroidManifest.xml
Normal file
28
sample/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/NoTitleBarWhiteBG">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".BenchmarkActivity"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.facebook.yoga.android.YogaViewLayoutFactory;
|
||||
|
||||
public class BenchmarkActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.benchmark_select_layout);
|
||||
|
||||
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() {
|
||||
@Override
|
||||
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
ViewPager viewPager = findViewById(R.id.viewpager);
|
||||
viewPager.setCurrentItem(tab.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.Math;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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<Long> 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 (time<p90 && time>p10) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.yoga.android.YogaLayout;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
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 = rootLayout.findViewById(R.id.benchmarkSelect);
|
||||
String[] items = new String[]{"Basic", "Typical", "Nested"};
|
||||
ArrayAdapter<String> 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 = 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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
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;
|
||||
|
||||
public class BenchmarkInflate extends BenchmarkFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
Button b = rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(v -> startBenchmark());
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
protected void startBenchmark() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
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();
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
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;
|
||||
|
||||
public class BenchmarkLayout extends BenchmarkFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
Button b = rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(v -> startBenchmark());
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
protected void startBenchmark() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
TextView textView = rootLayout.findViewById(R.id.text);
|
||||
|
||||
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 +
|
||||
"\n" +
|
||||
linearInflationAggregator);
|
||||
Log.i(
|
||||
"YogaLayoutBenchmark",
|
||||
yogaInflationAggregator +
|
||||
"\n" +
|
||||
linearInflationAggregator);
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
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 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 = rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(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());
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.yoga.sample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.facebook.yoga.android.YogaViewLayoutFactory;
|
||||
|
||||
/**
|
||||
* An activity to show off Yoga in Android. This activity shows a simple layout (defined in
|
||||
* {@code main_layout.xml}) that shows off the awesome functionality of the Yoga layout engine
|
||||
* as well as some optimisations on layout systems that it facilitates.
|
||||
*/
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance());
|
||||
super.onCreate(savedInstanceState);
|
||||
SoLoader.init(this, false);
|
||||
|
||||
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(@NonNull MenuItem item) {
|
||||
// There is only one option
|
||||
Intent intent = new Intent(this, BenchmarkActivity.class);
|
||||
startActivity(intent);
|
||||
this.finish();
|
||||
return true;
|
||||
}
|
||||
}
|
17
sample/src/main/res/drawable/action_bar_background.xml
Normal file
17
sample/src/main/res/drawable/action_bar_background.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
>
|
||||
<solid
|
||||
android:color="@color/yoga_grey"
|
||||
/>
|
||||
</shape>
|
BIN
sample/src/main/res/drawable/ic_launcher.png
Normal file
BIN
sample/src/main/res/drawable/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
34
sample/src/main/res/drawable/sample_children_background.xml
Normal file
34
sample/src/main/res/drawable/sample_children_background.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
>
|
||||
|
||||
<corners
|
||||
android:radius="4dp"
|
||||
/>
|
||||
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/children_stroke"
|
||||
/>
|
||||
|
||||
<padding
|
||||
android:top="6dp"
|
||||
android:bottom="6dp"
|
||||
android:left="8dp"
|
||||
android:right="8dp"
|
||||
/>
|
||||
|
||||
<solid
|
||||
android:color="@color/children_background"
|
||||
/>
|
||||
</shape>
|
50
sample/src/main/res/layout/benchmark_fragment.xml
Normal file
50
sample/src/main/res/layout/benchmark_fragment.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="column"
|
||||
>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_height="50dp"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="Run benchmark"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<Spinner
|
||||
android:id="@+id/benchmarkSelect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:spinnerMode="dropdown"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textSize="10sp"
|
||||
android:fontFamily="monospace"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@android:color/darker_gray"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:id="@+id/preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
/>
|
||||
</YogaLayout>
|
30
sample/src/main/res/layout/benchmark_layout_1.xml
Normal file
30
sample/src/main/res/layout/benchmark_layout_1.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<View
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_flex="0"
|
||||
app:yg_marginAll="5dp"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_2_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginHorizontal="5dp"
|
||||
/>
|
||||
</YogaLayout>
|
28
sample/src/main/res/layout/benchmark_layout_1_linear.xml
Normal file
28
sample/src/main/res/layout/benchmark_layout_1_linear.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_margin="5dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="@string/child_2_text"
|
||||
/>
|
||||
</LinearLayout>
|
104
sample/src/main/res/layout/benchmark_layout_2.xml
Normal file
104
sample/src/main/res/layout/benchmark_layout_2.xml
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
app:yg_flexDirection="column"
|
||||
app:yg_alignItems="stretch"
|
||||
>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:height="40dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="stretch"
|
||||
>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginAll="10dp"
|
||||
app:yg_aspectRatio="1"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:height="40dp"
|
||||
app:yg_flexDirection="column"
|
||||
app:yg_alignItems="stretch"
|
||||
app:yg_flex="1"
|
||||
app:yg_justifyContent="space_around"
|
||||
>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:height="8dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:height="8dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:height="8dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
app:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</YogaLayout>
|
95
sample/src/main/res/layout/benchmark_layout_2_linear.xml
Normal file
95
sample/src/main/res/layout/benchmark_layout_2_linear.xml
Normal file
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<View
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
android:layout_margin="10dp"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
206
sample/src/main/res/layout/benchmark_layout_3.xml
Normal file
206
sample/src/main/res/layout/benchmark_layout_3.xml
Normal file
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_alignItems="center"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_justifyContent="center"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="column"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="column"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="column"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
app:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_flex="1"
|
||||
>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</YogaLayout>
|
204
sample/src/main/res/layout/benchmark_layout_3_linear.xml
Normal file
204
sample/src/main/res/layout/benchmark_layout_3_linear.xml
Normal file
@@ -0,0 +1,204 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
7
sample/src/main/res/layout/benchmark_select_layout.xml
Normal file
7
sample/src/main/res/layout/benchmark_select_layout.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/viewpager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
137
sample/src/main/res/layout/main_layout.xml
Normal file
137
sample/src/main/res/layout/main_layout.xml
Normal file
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
app:yg_marginHorizontal="10dp"
|
||||
app:yg_marginTop="5dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textColor="@color/children_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
app:yg_marginHorizontal="10dp"
|
||||
app:yg_marginTop="5dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_2_text"
|
||||
android:textColor="@color/children_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
app:yg_marginHorizontal="10dp"
|
||||
app:yg_marginTop="5dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_3_text"
|
||||
android:textColor="@color/children_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
app:yg_marginHorizontal="10dp"
|
||||
app:yg_marginTop="5dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_4_text"
|
||||
android:textColor="@color/children_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
app:yg_marginHorizontal="10dp"
|
||||
app:yg_marginTop="5dp"
|
||||
app:yg_flexDirection="row"
|
||||
app:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
app:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_5_text"
|
||||
android:textColor="@color/children_text"
|
||||
app:yg_flex="1"
|
||||
app:yg_marginStart="10dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
</YogaLayout>
|
8
sample/src/main/res/menu/action_bar_benchmark.xml
Normal file
8
sample/src/main/res/menu/action_bar_benchmark.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_home"
|
||||
android:title="@string/home"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
8
sample/src/main/res/menu/action_bar_home.xml
Normal file
8
sample/src/main/res/menu/action_bar_home.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_benchmark"
|
||||
android:title="@string/benchmark"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
20
sample/src/main/res/values/colors.xml
Normal file
20
sample/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<color name="yoga_grey">#FF303846</color>
|
||||
<color name="yoga_blue">#FF97DCCF</color>
|
||||
|
||||
<color name="children_background">#FFFFFFFF</color>
|
||||
<color name="children_stroke">#665890ff</color>
|
||||
<color name="children_text">#FF23355b</color>
|
||||
|
||||
</resources>
|
35
sample/src/main/res/values/strings.xml
Normal file
35
sample/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="app_name">Yoga</string>
|
||||
<string
|
||||
name="child_1_text"
|
||||
description="Placeholder text for the first element in the layout"
|
||||
>Hello. I am Yoga!</string>
|
||||
<string
|
||||
name="child_2_text"
|
||||
description="Placeholder text for the second element in the layout"
|
||||
>I am a layout engine!</string>
|
||||
<string
|
||||
name="child_3_text"
|
||||
description="Placeholder text for the third element in the layout"
|
||||
>I run natively.</string>
|
||||
<string
|
||||
name="child_4_text"
|
||||
description="Placeholder text for the fourth element in the layout"
|
||||
>So I\'m fast.</string>
|
||||
<string
|
||||
name="child_5_text"
|
||||
description="Placeholder text for the fifth element in the layout"
|
||||
>Who are you?</string>
|
||||
<string name="home">Home</string>
|
||||
<string name="benchmark">Benchmark</string>
|
||||
</resources>
|
23
sample/src/main/res/values/styles.xml
Normal file
23
sample/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Copyright 2014-present, Facebook, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This source code is licensed under the license found in the
|
||||
LICENSE-examples file in the root directory of this source tree.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<style name="NoTitleBarWhiteBG" parent="Theme.AppCompat.Light">
|
||||
<item name="android:actionBarStyle">@style/MyActionBar</item>
|
||||
<item name="android:textDirection">locale</item>
|
||||
</style>
|
||||
<style name="MyActionBar" parent="Widget.AppCompat.Light.ActionBar">
|
||||
<item name="android:titleTextStyle">@style/MyTitleText</item>
|
||||
<item name="android:background">@drawable/action_bar_background</item>
|
||||
</style>
|
||||
<style name="MyTitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
|
||||
<item name="android:textColor">@color/yoga_blue</item>
|
||||
</style>
|
||||
</resources>
|
Reference in New Issue
Block a user