Remove YogaLayout ViewGroup (#1318)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1318 We deprecated this as part of the Yoga 2.0 release. The last version is still present as part of the `release-v2.0` branch, and was still published, but we are not carrying the code forward. This removes it. There are a couple followups here: 1. The top-level organization (e.g. a gradle-specific directory called `build-logic` in a multi-language repo) can and should be cleaned up. Yoga Java bindings should be condensed to the `java` folder. 2. We no longer have a sample app excersizing the bindings. We should resolve this by getting the JNI binding UTs working in OSS again. Reviewed By: cortinico Differential Revision: D47136243 fbshipit-source-id: 72f74914effde2c895934ac1100adfd305044d46
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1b40f05b8c
commit
f7324fb71e
@@ -1,21 +0,0 @@
|
|||||||
# YogaLayout [](https://facebook.github.io/yoga/docs/api/android/) [](https://facebook.github.io/yoga/docs/api/android/) [](https://bintray.com/facebook/maven/com.facebook.yoga.android%3Ayoga-layout/_latestVersion)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
YogaLayout is available via jcenter:
|
|
||||||
|
|
||||||
implementation 'com.facebook.yoga.android:yoga-layout:1.16.0'
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
Check out the docs [here](https://yogalayout.com/getting-started/standalone/).
|
|
||||||
|
|
||||||
We also have a sample project. To try it, clone the repo and run (with a device attached)
|
|
||||||
|
|
||||||
buck install -r android/sample
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
We welcome all pull-requests! At Facebook we sync the open source version of YogaKit daily, so we're always testing the latest changes.
|
|
||||||
|
|
||||||
See the CONTRIBUTING file for how to help out.
|
|
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("com.android.library")
|
|
||||||
id("publish")
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace 'com.facebook.yoga.android'
|
|
||||||
|
|
||||||
compileSdkVersion rootProject.compileSdkVersion
|
|
||||||
buildToolsVersion rootProject.buildToolsVersion
|
|
||||||
ndkVersion rootProject.ndkVersion
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
minSdkVersion rootProject.minSdkVersion
|
|
||||||
targetSdkVersion rootProject.targetSdkVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
targetCompatibility rootProject.targetCompatibilityVersion
|
|
||||||
sourceCompatibility rootProject.sourceCompatibilityVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
multipleVariants {
|
|
||||||
withSourcesJar()
|
|
||||||
withJavadocJar()
|
|
||||||
includeBuildTypeValues('debug', 'release')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
api project(':yoga')
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
|
|
||||||
This source code is licensed under the MIT license found in the
|
|
||||||
LICENSE file in the root directory of this source tree.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<application/>
|
|
||||||
|
|
||||||
</manifest>
|
|
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.android;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import com.facebook.yoga.YogaNode;
|
|
||||||
import com.facebook.yoga.YogaNodeFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Much like a {@link YogaLayout}, except this class does not render itself (the container) to the
|
|
||||||
* screen. As a result, <i>do not use this if you wish the container to have a background or
|
|
||||||
* foreground</i>. However, all of its children will still render as expected.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* In practice, this class never added to the View tree, and all its children become children of its
|
|
||||||
* parent. As a result, all the layout (such as the traversal of the tree) is performed by Yoga
|
|
||||||
* (and so natively) increasing performance.
|
|
||||||
*/
|
|
||||||
public class VirtualYogaLayout extends ViewGroup {
|
|
||||||
|
|
||||||
final private List<View> mChildren = new LinkedList<>();
|
|
||||||
final private Map<View, YogaNode> mYogaNodes = new HashMap<>();
|
|
||||||
final private YogaNode mYogaNode = YogaNodeFactory.create();
|
|
||||||
|
|
||||||
public VirtualYogaLayout(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualYogaLayout(Context context, AttributeSet attrs) {
|
|
||||||
this(context, attrs, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VirtualYogaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(context, attrs);
|
|
||||||
YogaLayout.applyLayoutParams(lp, mYogaNode, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public YogaNode getYogaNode() {
|
|
||||||
return mYogaNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to add a view, creating a new yoga node for it and adding that yoga node to the parent.
|
|
||||||
* If the child is a {@link VirtualYogaLayout}, we simply transfer all its children to this one
|
|
||||||
* in a manner that maintains the tree, and add its root to the tree.
|
|
||||||
*
|
|
||||||
* @param child the View to add
|
|
||||||
* @param index the position at which to add it (ignored)
|
|
||||||
* @param params the layout parameters to apply
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
|
||||||
if (child instanceof VirtualYogaLayout) {
|
|
||||||
((VirtualYogaLayout) child).transferChildren(this);
|
|
||||||
|
|
||||||
final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode();
|
|
||||||
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
YogaNode node = YogaNodeFactory.create();
|
|
||||||
YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(params);
|
|
||||||
YogaLayout.applyLayoutParams(lp, node, child);
|
|
||||||
node.setData(child);
|
|
||||||
node.setMeasureFunction(new YogaLayout.ViewMeasureFunction());
|
|
||||||
|
|
||||||
mYogaNode.addChildAt(node, mYogaNode.getChildCount());
|
|
||||||
|
|
||||||
addView(child, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to add a view with a corresponding node, but not to change the Yoga tree in any way.
|
|
||||||
*
|
|
||||||
* @param child the View to add
|
|
||||||
* @param node the corresponding yoga node
|
|
||||||
*/
|
|
||||||
public void addView(View child, YogaNode node) {
|
|
||||||
mChildren.add(child);
|
|
||||||
mYogaNodes.put(child, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives up children {@code View}s to the parent, maintaining the Yoga tree. This function calls
|
|
||||||
* {@link YogaLayout#addView(View, YogaNode)} or {@link VirtualYogaLayout#addView(View, YogaNode)}
|
|
||||||
* on the parent to add the {@code View} without generating new yoga nodes.
|
|
||||||
*
|
|
||||||
* @param parent the parent to pass children to (must be a YogaLayout or a VirtualYogaLayout)
|
|
||||||
*/
|
|
||||||
protected void transferChildren(ViewGroup parent) {
|
|
||||||
if (parent instanceof VirtualYogaLayout) {
|
|
||||||
for (View child : mChildren) {
|
|
||||||
((VirtualYogaLayout) parent).addView(child, mYogaNodes.get(child));
|
|
||||||
}
|
|
||||||
} else if (parent instanceof YogaLayout) {
|
|
||||||
for (View child : mChildren) {
|
|
||||||
((YogaLayout) parent).addView(child, mYogaNodes.get(child));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("VirtualYogaLayout cannot transfer children to ViewGroup of type "
|
|
||||||
+parent.getClass().getCanonicalName()+". Must either be a VirtualYogaLayout or a " +
|
|
||||||
"YogaLayout.");
|
|
||||||
}
|
|
||||||
mChildren.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
||||||
throw new RuntimeException("Attempting to layout a VirtualYogaLayout");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
|
|
||||||
return new YogaLayout.LayoutParams(getContext(), attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
|
|
||||||
return new YogaLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
|
|
||||||
return new YogaLayout.LayoutParams(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
|
|
||||||
return p instanceof YogaLayout.LayoutParams;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,816 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.android;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import com.facebook.yoga.YogaAlign;
|
|
||||||
import com.facebook.yoga.YogaConstants;
|
|
||||||
import com.facebook.yoga.YogaDirection;
|
|
||||||
import com.facebook.yoga.YogaDisplay;
|
|
||||||
import com.facebook.yoga.YogaEdge;
|
|
||||||
import com.facebook.yoga.YogaFlexDirection;
|
|
||||||
import com.facebook.yoga.YogaJustify;
|
|
||||||
import com.facebook.yoga.YogaMeasureFunction;
|
|
||||||
import com.facebook.yoga.YogaMeasureMode;
|
|
||||||
import com.facebook.yoga.YogaMeasureOutput;
|
|
||||||
import com.facebook.yoga.YogaNode;
|
|
||||||
import com.facebook.yoga.YogaNodeFactory;
|
|
||||||
import com.facebook.yoga.YogaOverflow;
|
|
||||||
import com.facebook.yoga.YogaPositionType;
|
|
||||||
import com.facebook.yoga.YogaWrap;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@code ViewGroup} based on the Yoga layout engine.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This class is designed to be as "plug and play" as possible. That is, you can use it in XML
|
|
||||||
* like this (note: to use {@code YogaLayout} you need to use the {@link YogaViewLayoutFactory}):
|
|
||||||
* <p>
|
|
||||||
* <pre>{@code
|
|
||||||
* <YogaLayout
|
|
||||||
* xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
* xmlns:yoga="http://schemas.android.com/apk/com.facebook.yoga.android"
|
|
||||||
* android:layout_width="match_owner"
|
|
||||||
* android:layout_height="match_owner"
|
|
||||||
* yoga:flex_direction="row"
|
|
||||||
* yoga:padding_all="10dp"
|
|
||||||
* >
|
|
||||||
* <TextView
|
|
||||||
* android:layout_width="match_owner"
|
|
||||||
* android:layout_height="match_owner"
|
|
||||||
* android:text="Hello, World!"
|
|
||||||
* yoga:flex="1"
|
|
||||||
* />
|
|
||||||
* </YogaLayout>
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* Under the hood, all views added to this {@code ViewGroup} are laid out using flexbox rules
|
|
||||||
* and the Yoga engine.
|
|
||||||
*/
|
|
||||||
public class YogaLayout extends ViewGroup {
|
|
||||||
private final Map<View, YogaNode> mYogaNodes;
|
|
||||||
private final YogaNode mYogaNode;
|
|
||||||
|
|
||||||
public YogaLayout(Context context) {
|
|
||||||
this(context, null, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public YogaLayout(Context context, AttributeSet attrs) {
|
|
||||||
this(context, attrs, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public YogaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
|
|
||||||
mYogaNode = YogaNodeFactory.create();
|
|
||||||
mYogaNodes = new HashMap<>();
|
|
||||||
|
|
||||||
mYogaNode.setData(this);
|
|
||||||
mYogaNode.setMeasureFunction(new ViewMeasureFunction());
|
|
||||||
|
|
||||||
LayoutParams layoutParams = null;
|
|
||||||
if (attrs != null) {
|
|
||||||
layoutParams = new LayoutParams(context, attrs);
|
|
||||||
} else {
|
|
||||||
layoutParams = (LayoutParams) generateDefaultLayoutParams();
|
|
||||||
}
|
|
||||||
applyLayoutParams(layoutParams, mYogaNode, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public YogaNode getYogaNode() {
|
|
||||||
return mYogaNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public YogaNode getYogaNodeForView(View view) {
|
|
||||||
return mYogaNodes.get(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a child view with the specified layout parameters.
|
|
||||||
*
|
|
||||||
* In the typical View is added, this constructs a {@code YogaNode} for this child and applies all
|
|
||||||
* the {@code yoga:*} attributes. The Yoga node is added to the Yoga tree and the child is added
|
|
||||||
* to this ViewGroup.
|
|
||||||
*
|
|
||||||
* If the child is a {@link YogaLayout} itself, we do not construct a new Yoga node for that
|
|
||||||
* child, but use its root node instead.
|
|
||||||
*
|
|
||||||
* If the child is a {@link VirtualYogaLayout}, we also use its Yoga node, but we also instruct it
|
|
||||||
* to transfer all of its children to this {@link YogaLayout} while preserving the Yoga tree (so
|
|
||||||
* that the layout of its children is correct). The {@link VirtualYogaLayout} is then not added
|
|
||||||
* to the View hierarchy.
|
|
||||||
*
|
|
||||||
* <p><strong>Note:</strong> do not invoke this method from
|
|
||||||
* {@code #draw(android.graphics.Canvas)}, {@code onDraw(android.graphics.Canvas)},
|
|
||||||
* {@code #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
|
|
||||||
*
|
|
||||||
* @param child the child view to add
|
|
||||||
* @param index the position at which to add the child or -1 to add last
|
|
||||||
* @param params the layout parameters to set on the child
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
|
||||||
// Internal nodes (which this is now) cannot have measure functions
|
|
||||||
mYogaNode.setMeasureFunction(null);
|
|
||||||
|
|
||||||
if (child instanceof VirtualYogaLayout) {
|
|
||||||
((VirtualYogaLayout) child).transferChildren(this);
|
|
||||||
final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode();
|
|
||||||
|
|
||||||
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.addView(child, index, params);
|
|
||||||
|
|
||||||
// It is possible that addView is being called as part of a transferal of children, in which
|
|
||||||
// case we already know about the YogaNode and only need the Android View tree to be aware
|
|
||||||
// that we now own this child. If so, we don't need to do anything further
|
|
||||||
if (mYogaNodes.containsKey(child)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
YogaNode childNode;
|
|
||||||
|
|
||||||
if (child instanceof YogaLayout) {
|
|
||||||
childNode = ((YogaLayout) child).getYogaNode();
|
|
||||||
} else {
|
|
||||||
if(mYogaNodes.containsKey(child)) {
|
|
||||||
childNode = mYogaNodes.get(child);
|
|
||||||
} else {
|
|
||||||
childNode = YogaNodeFactory.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
childNode.setData(child);
|
|
||||||
childNode.setMeasureFunction(new ViewMeasureFunction());
|
|
||||||
}
|
|
||||||
|
|
||||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
|
||||||
applyLayoutParams(lp, childNode, child);
|
|
||||||
|
|
||||||
mYogaNodes.put(child, childNode);
|
|
||||||
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a view to this {@code ViewGroup} with an already given {@code YogaNode}. Use
|
|
||||||
* this function if you already have a Yoga node (and perhaps tree) associated with the view you
|
|
||||||
* are adding, that you would like to preserve.
|
|
||||||
*
|
|
||||||
* @param child The view to add
|
|
||||||
* @param node The Yoga node belonging to the view
|
|
||||||
*/
|
|
||||||
public void addView(View child, YogaNode node) {
|
|
||||||
mYogaNodes.put(child, node);
|
|
||||||
addView(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeView(View view) {
|
|
||||||
removeViewFromYogaTree(view, false);
|
|
||||||
super.removeView(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeViewAt(int index) {
|
|
||||||
removeViewFromYogaTree(getChildAt(index), false);
|
|
||||||
super.removeViewAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeViewInLayout(View view) {
|
|
||||||
removeViewFromYogaTree(view, true);
|
|
||||||
super.removeViewInLayout(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeViews(int start, int count) {
|
|
||||||
for (int i = start; i < start + count; i++) {
|
|
||||||
removeViewFromYogaTree(getChildAt(i), false);
|
|
||||||
}
|
|
||||||
super.removeViews(start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeViewsInLayout(int start, int count) {
|
|
||||||
for (int i = start; i < start + count; i++) {
|
|
||||||
removeViewFromYogaTree(getChildAt(i), true);
|
|
||||||
}
|
|
||||||
super.removeViewsInLayout(start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeAllViews() {
|
|
||||||
final int childCount = getChildCount();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
removeViewFromYogaTree(getChildAt(i), false);
|
|
||||||
}
|
|
||||||
super.removeAllViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeAllViewsInLayout() {
|
|
||||||
final int childCount = getChildCount();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
removeViewFromYogaTree(getChildAt(i), true);
|
|
||||||
}
|
|
||||||
super.removeAllViewsInLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks a particular view as "dirty" and to be relaid out. If the view is not a child of this
|
|
||||||
* {@link YogaLayout}, the entire tree is traversed to find it.
|
|
||||||
*
|
|
||||||
* @param view the view to mark as dirty
|
|
||||||
*/
|
|
||||||
public void invalidate(View view) {
|
|
||||||
if (mYogaNodes.containsKey(view)) {
|
|
||||||
mYogaNodes.get(view).dirty();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int childCount = mYogaNode.getChildCount();
|
|
||||||
for (int i = 0; i < childCount; i++) {
|
|
||||||
final YogaNode yogaNode = mYogaNode.getChildAt(i);
|
|
||||||
if (yogaNode.getData() instanceof YogaLayout) {
|
|
||||||
((YogaLayout) yogaNode.getData()).invalidate(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeViewFromYogaTree(View view, boolean inLayout) {
|
|
||||||
final YogaNode node = mYogaNodes.get(view);
|
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final YogaNode owner = node.getOwner();
|
|
||||||
|
|
||||||
for (int i = 0; i < owner.getChildCount(); i++) {
|
|
||||||
if (owner.getChildAt(i).equals(node)) {
|
|
||||||
owner.removeChildAt(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setData(null);
|
|
||||||
mYogaNodes.remove(view);
|
|
||||||
|
|
||||||
if (inLayout) {
|
|
||||||
mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyLayoutRecursive(YogaNode node, float xOffset, float yOffset) {
|
|
||||||
View view = (View) node.getData();
|
|
||||||
|
|
||||||
if (view != null && view != this) {
|
|
||||||
if (view.getVisibility() == GONE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int left = Math.round(xOffset + node.getLayoutX());
|
|
||||||
int top = Math.round(yOffset + node.getLayoutY());
|
|
||||||
view.measure(
|
|
||||||
View.MeasureSpec.makeMeasureSpec(
|
|
||||||
Math.round(node.getLayoutWidth()),
|
|
||||||
View.MeasureSpec.EXACTLY),
|
|
||||||
View.MeasureSpec.makeMeasureSpec(
|
|
||||||
Math.round(node.getLayoutHeight()),
|
|
||||||
View.MeasureSpec.EXACTLY));
|
|
||||||
view.layout(left, top, left + view.getMeasuredWidth(), top + view.getMeasuredHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
final int childrenCount = node.getChildCount();
|
|
||||||
for (int i = 0; i < childrenCount; i++) {
|
|
||||||
if (this.equals(view)) {
|
|
||||||
applyLayoutRecursive(node.getChildAt(i), xOffset, yOffset);
|
|
||||||
} else if (view instanceof YogaLayout) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
applyLayoutRecursive(
|
|
||||||
node.getChildAt(i),
|
|
||||||
xOffset + node.getLayoutX(),
|
|
||||||
yOffset + node.getLayoutY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
||||||
// Either we are a root of a tree, or this function is called by our owner's onLayout, in which
|
|
||||||
// case our r-l and b-t are the size of our node.
|
|
||||||
if (!(getParent() instanceof YogaLayout)) {
|
|
||||||
createLayout(
|
|
||||||
MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY),
|
|
||||||
MeasureSpec.makeMeasureSpec(b - t, MeasureSpec.EXACTLY));
|
|
||||||
}
|
|
||||||
|
|
||||||
applyLayoutRecursive(mYogaNode, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is mostly unneeded, because Yoga is doing the measuring. Hence we only need to
|
|
||||||
* return accurate results if we are the root.
|
|
||||||
*
|
|
||||||
* @param widthMeasureSpec the suggested specification for the width
|
|
||||||
* @param heightMeasureSpec the suggested specification for the height
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
if (!(getParent() instanceof YogaLayout)) {
|
|
||||||
createLayout(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
setMeasuredDimension(
|
|
||||||
Math.round(mYogaNode.getLayoutWidth()),
|
|
||||||
Math.round(mYogaNode.getLayoutHeight()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createLayout(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
|
|
||||||
if (heightMode == MeasureSpec.EXACTLY) {
|
|
||||||
mYogaNode.setHeight(heightSize);
|
|
||||||
}
|
|
||||||
if (widthMode == MeasureSpec.EXACTLY) {
|
|
||||||
mYogaNode.setWidth(widthSize);
|
|
||||||
}
|
|
||||||
if (heightMode == MeasureSpec.AT_MOST) {
|
|
||||||
mYogaNode.setMaxHeight(heightSize);
|
|
||||||
}
|
|
||||||
if (widthMode == MeasureSpec.AT_MOST) {
|
|
||||||
mYogaNode.setMaxWidth(widthSize);
|
|
||||||
}
|
|
||||||
mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies the layout parameters to the YogaNode. That is, this function is a translator from
|
|
||||||
* {@code yoga:X="Y"} to {@code yogaNode.setX(Y);}, with some reasonable defaults.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* If the SDK version is high enough, and the {@code yoga:direction} is not set on
|
|
||||||
* the component, the direction (LTR or RTL) is set according to the locale.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The attributes {@code padding_top}, {@code padding_right} etc. default to those of the view's
|
|
||||||
* drawable background, if it has one.
|
|
||||||
*
|
|
||||||
* @param layoutParameters The source set of params
|
|
||||||
* @param node The destination node
|
|
||||||
*/
|
|
||||||
protected static void applyLayoutParams(LayoutParams layoutParameters, YogaNode node, View view) {
|
|
||||||
// JELLY_BEAN_MR1 (17) is the first version supporting getLayoutDirection()
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
|
||||||
Configuration configuration = view.getResources().getConfiguration();
|
|
||||||
if (configuration.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
|
|
||||||
node.setDirection(YogaDirection.RTL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawable background = view.getBackground();
|
|
||||||
if (background != null) {
|
|
||||||
final Rect backgroundPadding = new Rect();
|
|
||||||
if (background.getPadding(backgroundPadding)) {
|
|
||||||
node.setPadding(YogaEdge.LEFT, backgroundPadding.left);
|
|
||||||
node.setPadding(YogaEdge.TOP, backgroundPadding.top);
|
|
||||||
node.setPadding(YogaEdge.RIGHT, backgroundPadding.right);
|
|
||||||
node.setPadding(YogaEdge.BOTTOM, backgroundPadding.bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < layoutParameters.numericAttributes.size(); i++) {
|
|
||||||
final int attribute = layoutParameters.numericAttributes.keyAt(i);
|
|
||||||
final float value = layoutParameters.numericAttributes.valueAt(i);
|
|
||||||
|
|
||||||
if (attribute == R.styleable.yoga_yg_alignContent) {
|
|
||||||
node.setAlignContent(YogaAlign.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_alignItems) {
|
|
||||||
node.setAlignItems(YogaAlign.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_alignSelf) {
|
|
||||||
node.setAlignSelf(YogaAlign.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_aspectRatio) {
|
|
||||||
node.setAspectRatio(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderLeft) {
|
|
||||||
node.setBorder(YogaEdge.LEFT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderTop) {
|
|
||||||
node.setBorder(YogaEdge.TOP, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderRight) {
|
|
||||||
node.setBorder(YogaEdge.RIGHT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderBottom) {
|
|
||||||
node.setBorder(YogaEdge.BOTTOM, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderStart) {
|
|
||||||
node.setBorder(YogaEdge.START, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderEnd) {
|
|
||||||
node.setBorder(YogaEdge.END, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderHorizontal) {
|
|
||||||
node.setBorder(YogaEdge.HORIZONTAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderVertical) {
|
|
||||||
node.setBorder(YogaEdge.VERTICAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_borderAll) {
|
|
||||||
node.setBorder(YogaEdge.ALL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_direction) {
|
|
||||||
node.setDirection(YogaDirection.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_display) {
|
|
||||||
node.setDisplay(YogaDisplay.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_flex) {
|
|
||||||
node.setFlex(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_flexBasis) {
|
|
||||||
node.setFlexBasis(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_flexDirection) {
|
|
||||||
node.setFlexDirection(YogaFlexDirection.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_flexGrow) {
|
|
||||||
node.setFlexGrow(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_flexShrink) {
|
|
||||||
node.setFlexShrink(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_height) {
|
|
||||||
node.setHeight(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginLeft) {
|
|
||||||
node.setMargin(YogaEdge.LEFT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_justifyContent) {
|
|
||||||
node.setJustifyContent(YogaJustify.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
|
||||||
node.setMargin(YogaEdge.TOP, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
|
||||||
node.setMargin(YogaEdge.RIGHT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
|
||||||
node.setMargin(YogaEdge.BOTTOM, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
|
||||||
node.setMargin(YogaEdge.START, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
|
||||||
node.setMargin(YogaEdge.END, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
|
||||||
node.setMargin(YogaEdge.HORIZONTAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
|
||||||
node.setMargin(YogaEdge.VERTICAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
|
||||||
node.setMargin(YogaEdge.ALL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_maxHeight) {
|
|
||||||
node.setMaxHeight(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_maxWidth) {
|
|
||||||
node.setMaxWidth(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_minHeight) {
|
|
||||||
node.setMinHeight(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_minWidth) {
|
|
||||||
node.setMinWidth(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_overflow) {
|
|
||||||
node.setOverflow(YogaOverflow.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingLeft) {
|
|
||||||
node.setPadding(YogaEdge.LEFT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingTop) {
|
|
||||||
node.setPadding(YogaEdge.TOP, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingRight) {
|
|
||||||
node.setPadding(YogaEdge.RIGHT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingBottom) {
|
|
||||||
node.setPadding(YogaEdge.BOTTOM, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingStart) {
|
|
||||||
node.setPadding(YogaEdge.START, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingEnd) {
|
|
||||||
node.setPadding(YogaEdge.END, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingHorizontal) {
|
|
||||||
node.setPadding(YogaEdge.HORIZONTAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingVertical) {
|
|
||||||
node.setPadding(YogaEdge.VERTICAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingAll) {
|
|
||||||
node.setPadding(YogaEdge.ALL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionLeft) {
|
|
||||||
node.setPosition(YogaEdge.LEFT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionTop) {
|
|
||||||
node.setPosition(YogaEdge.TOP, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionRight) {
|
|
||||||
node.setPosition(YogaEdge.RIGHT, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionBottom) {
|
|
||||||
node.setPosition(YogaEdge.BOTTOM, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionStart) {
|
|
||||||
node.setPosition(YogaEdge.START, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionEnd) {
|
|
||||||
node.setPosition(YogaEdge.END, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionHorizontal) {
|
|
||||||
node.setPosition(YogaEdge.HORIZONTAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionVertical) {
|
|
||||||
node.setPosition(YogaEdge.VERTICAL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionAll) {
|
|
||||||
node.setPosition(YogaEdge.ALL, value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionType) {
|
|
||||||
node.setPositionType(YogaPositionType.fromInt(Math.round(value)));
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_width) {
|
|
||||||
node.setWidth(value);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_wrap) {
|
|
||||||
node.setWrap(YogaWrap.fromInt(Math.round(value)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < layoutParameters.stringAttributes.size(); i++) {
|
|
||||||
final int attribute = layoutParameters.stringAttributes.keyAt(i);
|
|
||||||
final String value = layoutParameters.stringAttributes.valueAt(i);
|
|
||||||
|
|
||||||
if (value.equals("auto")) {
|
|
||||||
if (attribute == R.styleable.yoga_yg_marginLeft) {
|
|
||||||
node.setMarginAuto(YogaEdge.LEFT);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
|
||||||
node.setMarginAuto(YogaEdge.TOP);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
|
||||||
node.setMarginAuto(YogaEdge.RIGHT);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
|
||||||
node.setMarginAuto(YogaEdge.BOTTOM);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
|
||||||
node.setMarginAuto(YogaEdge.START);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
|
||||||
node.setMarginAuto(YogaEdge.END);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
|
||||||
node.setMarginAuto(YogaEdge.HORIZONTAL);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
|
||||||
node.setMarginAuto(YogaEdge.VERTICAL);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
|
||||||
node.setMarginAuto(YogaEdge.ALL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.endsWith("%")) {
|
|
||||||
final float numericValue = Float.parseFloat(value.substring(0, value.length()-1));
|
|
||||||
|
|
||||||
if (attribute == R.styleable.yoga_yg_flexBasis) {
|
|
||||||
node.setFlexBasisPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_height) {
|
|
||||||
node.setHeightPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginLeft) {
|
|
||||||
node.setMarginPercent(YogaEdge.LEFT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
|
||||||
node.setMarginPercent(YogaEdge.TOP, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
|
||||||
node.setMarginPercent(YogaEdge.RIGHT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
|
||||||
node.setMarginPercent(YogaEdge.BOTTOM, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
|
||||||
node.setMarginPercent(YogaEdge.START, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
|
||||||
node.setMarginPercent(YogaEdge.END, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
|
||||||
node.setMarginPercent(YogaEdge.HORIZONTAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
|
||||||
node.setMarginPercent(YogaEdge.VERTICAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
|
||||||
node.setMarginPercent(YogaEdge.ALL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_maxHeight) {
|
|
||||||
node.setMaxHeightPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_maxWidth) {
|
|
||||||
node.setMaxWidthPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_minHeight) {
|
|
||||||
node.setMinHeightPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_minWidth) {
|
|
||||||
node.setMinWidthPercent(numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingLeft) {
|
|
||||||
node.setPaddingPercent(YogaEdge.LEFT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingTop) {
|
|
||||||
node.setPaddingPercent(YogaEdge.TOP, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingRight) {
|
|
||||||
node.setPaddingPercent(YogaEdge.RIGHT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingBottom) {
|
|
||||||
node.setPaddingPercent(YogaEdge.BOTTOM, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingStart) {
|
|
||||||
node.setPaddingPercent(YogaEdge.START, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingEnd) {
|
|
||||||
node.setPaddingPercent(YogaEdge.END, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingHorizontal) {
|
|
||||||
node.setPaddingPercent(YogaEdge.HORIZONTAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingVertical) {
|
|
||||||
node.setPaddingPercent(YogaEdge.VERTICAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_paddingAll) {
|
|
||||||
node.setPaddingPercent(YogaEdge.ALL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionLeft) {
|
|
||||||
node.setPositionPercent(YogaEdge.LEFT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionTop) {
|
|
||||||
node.setPositionPercent(YogaEdge.TOP, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionRight) {
|
|
||||||
node.setPositionPercent(YogaEdge.RIGHT, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionBottom) {
|
|
||||||
node.setPositionPercent(YogaEdge.BOTTOM, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionStart) {
|
|
||||||
node.setPositionPercent(YogaEdge.START, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionEnd) {
|
|
||||||
node.setPositionPercent(YogaEdge.END, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionHorizontal) {
|
|
||||||
node.setPositionPercent(YogaEdge.HORIZONTAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionVertical) {
|
|
||||||
node.setPositionPercent(YogaEdge.VERTICAL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_positionAll) {
|
|
||||||
node.setPositionPercent(YogaEdge.ALL, numericValue);
|
|
||||||
} else if (attribute == R.styleable.yoga_yg_width) {
|
|
||||||
node.setWidthPercent(numericValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
|
|
||||||
return new YogaLayout.LayoutParams(getContext(), attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
|
|
||||||
return new YogaLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
|
|
||||||
return new YogaLayout.LayoutParams(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
|
|
||||||
return p instanceof LayoutParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code YogaLayout.LayoutParams} are used by views to tell {@link YogaLayout} how they want to
|
|
||||||
* be laid out. More precisely, the specify the yoga parameters of the view.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This is actually mostly a wrapper around a {@code SparseArray} that holds a mapping between
|
|
||||||
* styleable id's ({@code R.styleable.yoga_yg_*}) and the float of their values. In cases where
|
|
||||||
* the value is an enum or an integer, they should first be cast to int (with rounding) before
|
|
||||||
* using.
|
|
||||||
*/
|
|
||||||
public static class LayoutParams extends ViewGroup.LayoutParams {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapping from attribute keys ({@code R.styleable.yoga_yg_*}) to the float of their values.
|
|
||||||
* For attributes like position_percent_left (float), this is the native type. For attributes
|
|
||||||
* like align_self (enums), the integer enum value is cast (rounding is used on the other side
|
|
||||||
* to prevent precision errors). Dimension attributes are stored as float pixels.
|
|
||||||
*/
|
|
||||||
SparseArray<Float> numericAttributes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapping from attribute keys ({@code R.styleable.yoga_yg_*}) with string values to those
|
|
||||||
* strings. This is used for values such as "auto".
|
|
||||||
*/
|
|
||||||
SparseArray<String> stringAttributes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a set of layout params from a source set. In the case that the source set is
|
|
||||||
* actually a {@link YogaLayout.LayoutParams}, we can copy all the yoga attributes. Otherwise
|
|
||||||
* we start with a blank slate.
|
|
||||||
*
|
|
||||||
* @param source The layout params to copy from
|
|
||||||
*/
|
|
||||||
public LayoutParams(ViewGroup.LayoutParams source) {
|
|
||||||
super(source);
|
|
||||||
if (source instanceof LayoutParams) {
|
|
||||||
numericAttributes = ((LayoutParams) source).numericAttributes.clone();
|
|
||||||
stringAttributes = ((LayoutParams) source).stringAttributes.clone();
|
|
||||||
} else {
|
|
||||||
numericAttributes = new SparseArray<>();
|
|
||||||
stringAttributes = new SparseArray<>();
|
|
||||||
|
|
||||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
|
||||||
if (source.width >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
|
||||||
}
|
|
||||||
if (source.height >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_height, (float) height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a set of layout params, given width and height specs. In this case, we can set
|
|
||||||
* the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other
|
|
||||||
* options (such as {@code match_owner} or {@code wrap_content} are given, then the owner
|
|
||||||
* LayoutParams will store them, and we deal with them during layout. (see
|
|
||||||
* {@link YogaLayout#createLayout})
|
|
||||||
*
|
|
||||||
* @param width the requested width, either a pixel size, {@code WRAP_CONTENT} or
|
|
||||||
* {@code MATCH_PARENT}.
|
|
||||||
* @param height the requested height, either a pixel size, {@code WRAP_CONTENT} or
|
|
||||||
* {@code MATCH_PARENT}.
|
|
||||||
*/
|
|
||||||
public LayoutParams(int width, int height) {
|
|
||||||
super(width, height);
|
|
||||||
numericAttributes = new SparseArray<>();
|
|
||||||
stringAttributes = new SparseArray<>();
|
|
||||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
|
||||||
if (width >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
|
||||||
}
|
|
||||||
if (height >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_height, (float) height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a set of layout params, given attributes. Grabs all the {@code yoga:*}
|
|
||||||
* defined in {@code ALL_YOGA_ATTRIBUTES} and collects the ones that are set in {@code attrs}.
|
|
||||||
*
|
|
||||||
* @param context the application environment
|
|
||||||
* @param attrs the set of attributes from which to extract the yoga specific attributes
|
|
||||||
*/
|
|
||||||
public LayoutParams(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
numericAttributes = new SparseArray<>();
|
|
||||||
stringAttributes = new SparseArray<>();
|
|
||||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.yoga);
|
|
||||||
|
|
||||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
|
||||||
if (width >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
|
||||||
}
|
|
||||||
if (height >= 0) {
|
|
||||||
numericAttributes.put(R.styleable.yoga_yg_height, (float) height);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int attributeCount = a.getIndexCount();
|
|
||||||
for (int i = 0; i < attributeCount; i++) {
|
|
||||||
final int attribute = a.getIndex(i);
|
|
||||||
final TypedValue val = new TypedValue();
|
|
||||||
a.getValue(attribute, val);
|
|
||||||
|
|
||||||
if (val.type == TypedValue.TYPE_DIMENSION) {
|
|
||||||
numericAttributes.put(
|
|
||||||
attribute,
|
|
||||||
(float) a.getDimensionPixelSize(attribute, 0));
|
|
||||||
} else if (val.type == TypedValue.TYPE_STRING) {
|
|
||||||
stringAttributes.put(attribute, a.getString(attribute));
|
|
||||||
} else {
|
|
||||||
numericAttributes.put(attribute, a.getFloat(attribute, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a.recycle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper around measure function for yoga leaves.
|
|
||||||
*/
|
|
||||||
public static class ViewMeasureFunction implements YogaMeasureFunction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function to measure leaves of the Yoga tree. Yoga needs some way to know how large
|
|
||||||
* elements want to be. This function passes that question directly through to the relevant
|
|
||||||
* {@code View}'s measure function.
|
|
||||||
*
|
|
||||||
* @param node The yoga node to measure
|
|
||||||
* @param width The suggested width from the owner
|
|
||||||
* @param widthMode The type of suggestion for the width
|
|
||||||
* @param height The suggested height from the owner
|
|
||||||
* @param heightMode The type of suggestion for the height
|
|
||||||
* @return A measurement output ({@code YogaMeasureOutput}) for the node
|
|
||||||
*/
|
|
||||||
public long measure(
|
|
||||||
YogaNode node,
|
|
||||||
float width,
|
|
||||||
YogaMeasureMode widthMode,
|
|
||||||
float height,
|
|
||||||
YogaMeasureMode heightMode) {
|
|
||||||
final View view = (View) node.getData();
|
|
||||||
if (view == null || view instanceof YogaLayout) {
|
|
||||||
return YogaMeasureOutput.make(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(
|
|
||||||
(int) width,
|
|
||||||
viewMeasureSpecFromYogaMeasureMode(widthMode));
|
|
||||||
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(
|
|
||||||
(int) height,
|
|
||||||
viewMeasureSpecFromYogaMeasureMode(heightMode));
|
|
||||||
|
|
||||||
view.measure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
|
|
||||||
return YogaMeasureOutput.make(view.getMeasuredWidth(), view.getMeasuredHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int viewMeasureSpecFromYogaMeasureMode(YogaMeasureMode mode) {
|
|
||||||
if (mode == YogaMeasureMode.AT_MOST) {
|
|
||||||
return MeasureSpec.AT_MOST;
|
|
||||||
} else if (mode == YogaMeasureMode.EXACTLY) {
|
|
||||||
return MeasureSpec.EXACTLY;
|
|
||||||
} else {
|
|
||||||
return MeasureSpec.UNSPECIFIED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.android;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A layout inflater factory. This provides our custom {@link YogaViewLayoutFactory#onCreateView}
|
|
||||||
* to the XML inflation system, allowing us to replace XML tags.
|
|
||||||
*/
|
|
||||||
public class YogaViewLayoutFactory implements LayoutInflater.Factory {
|
|
||||||
private static YogaViewLayoutFactory sYogaViewLayoutFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains (and initialises if necessary) the singleton {@link YogaViewLayoutFactory}.
|
|
||||||
*
|
|
||||||
* @return The singleton instance
|
|
||||||
*/
|
|
||||||
public static YogaViewLayoutFactory getInstance() {
|
|
||||||
if (sYogaViewLayoutFactory == null) {
|
|
||||||
sYogaViewLayoutFactory = new YogaViewLayoutFactory();
|
|
||||||
}
|
|
||||||
return sYogaViewLayoutFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
YogaViewLayoutFactory() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook for inflating from a LayoutInflater. This hook replaces the cumbersome
|
|
||||||
* {@code com.facebook.etc.YogaLayout} with simply {@code YogaLayout} in your XML and the same
|
|
||||||
* with {@code VirtualYogaLayout}.
|
|
||||||
*
|
|
||||||
* @param name Tag name to be inflated.
|
|
||||||
* @param context The context the view is being created in.
|
|
||||||
* @param attrs Inflation attributes as specified in XML file.
|
|
||||||
*
|
|
||||||
* @return View Newly created view. Return null for the default behavior.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public View onCreateView(String name, Context context, AttributeSet attrs) {
|
|
||||||
if (YogaLayout.class.getSimpleName().equals(name)) {
|
|
||||||
return new YogaLayout(context, attrs);
|
|
||||||
}
|
|
||||||
if (VirtualYogaLayout.class.getSimpleName().equals(name)) {
|
|
||||||
return new VirtualYogaLayout(context, attrs);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,150 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
|
|
||||||
This source code is licensed under the MIT license found in the
|
|
||||||
LICENSE file in the root directory of this source tree.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<resources>
|
|
||||||
<declare-styleable name="yoga">
|
|
||||||
|
|
||||||
<attr name="yg_alignContent" format="enum">
|
|
||||||
<enum name="auto" value="0"/>
|
|
||||||
<enum name="flex_start" value="1"/>
|
|
||||||
<enum name="center" value="2"/>
|
|
||||||
<enum name="flex_end" value="3"/>
|
|
||||||
<enum name="stretch" value="4"/>
|
|
||||||
<enum name="baseline" value="5"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_alignItems" format="enum">
|
|
||||||
<enum name="auto" value="0"/>
|
|
||||||
<enum name="flex_start" value="1"/>
|
|
||||||
<enum name="center" value="2"/>
|
|
||||||
<enum name="flex_end" value="3"/>
|
|
||||||
<enum name="stretch" value="4"/>
|
|
||||||
<enum name="baseline" value="5"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_alignSelf" format="enum">
|
|
||||||
<enum name="auto" value="0"/>
|
|
||||||
<enum name="flex_start" value="1"/>
|
|
||||||
<enum name="center" value="2"/>
|
|
||||||
<enum name="flex_end" value="3"/>
|
|
||||||
<enum name="stretch" value="4"/>
|
|
||||||
<enum name="baseline" value="5"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_aspectRatio" format="float"/>
|
|
||||||
|
|
||||||
<attr name="yg_borderLeft" format="dimension"/>
|
|
||||||
<attr name="yg_borderTop" format="dimension"/>
|
|
||||||
<attr name="yg_borderRight" format="dimension"/>
|
|
||||||
<attr name="yg_borderBottom" format="dimension"/>
|
|
||||||
<attr name="yg_borderStart" format="dimension"/>
|
|
||||||
<attr name="yg_borderEnd" format="dimension"/>
|
|
||||||
<attr name="yg_borderHorizontal" format="dimension"/>
|
|
||||||
<attr name="yg_borderVertical" format="dimension"/>
|
|
||||||
<attr name="yg_borderAll" format="dimension"/>
|
|
||||||
|
|
||||||
<attr name="yg_direction" format="enum">
|
|
||||||
<enum name="inherit" value="0"/>
|
|
||||||
<enum name="ltr" value="1"/>
|
|
||||||
<enum name="rtl" value="2"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_display" format="enum">
|
|
||||||
<enum name="flex" value="0"/>
|
|
||||||
<enum name="none" value="1"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_flex" format="float"/>
|
|
||||||
|
|
||||||
<attr name="yg_flexBasis" format="float|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_flexDirection" format="enum">
|
|
||||||
<enum name="column" value="0"/>
|
|
||||||
<enum name="column_reverse" value="1"/>
|
|
||||||
<enum name="row" value="2"/>
|
|
||||||
<enum name="row_reverse" value="3"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_flexGrow" format="float"/>
|
|
||||||
|
|
||||||
<attr name="yg_flexShrink" format="float"/>
|
|
||||||
|
|
||||||
<attr name="yg_height" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_justifyContent" format="enum">
|
|
||||||
<enum name="flex_start" value="0"/>
|
|
||||||
<enum name="center" value="1"/>
|
|
||||||
<enum name="flex_end" value="2"/>
|
|
||||||
<enum name="space_between" value="3"/>
|
|
||||||
<enum name="space_around" value="4"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_marginLeft" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginTop" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginRight" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginBottom" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginStart" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginEnd" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginHorizontal" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginVertical" format="dimension|string"/>
|
|
||||||
<attr name="yg_marginAll" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_maxHeight" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_maxWidth" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_minHeight" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_minWidth" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_overflow" format="enum">
|
|
||||||
<enum name="visible" value="0"/>
|
|
||||||
<enum name="hidden" value="1"/>
|
|
||||||
<enum name="scroll" value="2"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_paddingLeft" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingTop" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingRight" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingBottom" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingStart" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingEnd" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingHorizontal" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingVertical" format="dimension|string"/>
|
|
||||||
<attr name="yg_paddingAll" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_positionLeft" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionTop" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionRight" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionBottom" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionStart" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionEnd" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionHorizontal" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionVertical" format="dimension|string"/>
|
|
||||||
<attr name="yg_positionAll" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_positionType" format="enum">
|
|
||||||
<!-- "static" is a reserved keyword
|
|
||||||
<enum name="static" value="0"/>
|
|
||||||
-->
|
|
||||||
<enum name="relative" value="1"/>
|
|
||||||
<enum name="absolute" value="2"/>
|
|
||||||
<enum name="position_static" value="0"/>
|
|
||||||
<enum name="position_relative" value="1"/>
|
|
||||||
<enum name="position_absolute" value="2"/>
|
|
||||||
</attr>
|
|
||||||
|
|
||||||
<attr name="yg_width" format="dimension|string"/>
|
|
||||||
|
|
||||||
<attr name="yg_wrap" format="enum">
|
|
||||||
<enum name="no_wrap" value="0"/>
|
|
||||||
<enum name="wrap" value="1"/>
|
|
||||||
</attr>
|
|
||||||
</declare-styleable>
|
|
||||||
</resources>
|
|
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("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")
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
<?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>
|
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
@@ -1,34 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,50 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,30 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,28 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,104 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,95 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,206 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,204 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?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"
|
|
||||||
/>
|
|
@@ -1,137 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,20 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,35 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,23 +0,0 @@
|
|||||||
<?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>
|
|
@@ -15,14 +15,12 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins { id("com.gradle.enterprise").version("3.7.1") }
|
plugins { id("com.gradle.enterprise").version("3.7.1") }
|
||||||
|
|
||||||
include(":sample", ":yoga", ":yoga-layout")
|
include(":yoga")
|
||||||
|
|
||||||
includeBuild("build-logic")
|
includeBuild("build-logic")
|
||||||
|
|
||||||
project(":yoga").projectDir = file("java")
|
project(":yoga").projectDir = file("java")
|
||||||
|
|
||||||
project(":yoga-layout").projectDir = file("android")
|
|
||||||
|
|
||||||
rootProject.name = "yoga-github"
|
rootProject.name = "yoga-github"
|
||||||
|
|
||||||
// If you specify a file inside gradle/gradle-enterprise.gradle.kts
|
// If you specify a file inside gradle/gradle-enterprise.gradle.kts
|
||||||
|
Reference in New Issue
Block a user