Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Commit eb5afdd

Browse files
authored
add a standard constraint chain syntax (#613)
* fix desig time lockout of on click * fix ConstraintLayout Compose chain * add support for weights and margins * resolve comments & clean up spaces * resolve comments & clean up spaces * resolve oscar comments
1 parent 3593174 commit eb5afdd

File tree

96 files changed

+3285
-54
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+3285
-54
lines changed

constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java

Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,16 @@ public static void parseJSON(String content, State state,
514514
case "barrier":
515515
parseBarrier(state, elementName, (CLObject) element);
516516
break;
517+
case "vChain":
518+
case "hChain":
519+
parseChainType(
520+
type,
521+
state,
522+
elementName,
523+
layoutVariables,
524+
(CLObject) element
525+
);
526+
break;
517527
}
518528
} else {
519529
parseWidget(state, layoutVariables,
@@ -726,6 +736,110 @@ static void parseChain(int orientation, State state,
726736
}
727737
}
728738

739+
private static float toPix(State state, float dp){
740+
return state.getDpToPixel().toPixels(dp);
741+
}
742+
/**
743+
* Support parsing Chain in the following manner
744+
* chainId : {
745+
* type:'hChain' // or vChain
746+
* contains: ['id1', 'id2', 'id3' ]
747+
* contains: [['id', weight, marginL ,marginR], 'id2', 'id3' ]
748+
* start: ['parent', 'start',0],
749+
* end: ['parent', 'end',0],
750+
* top: ['parent', 'top',0],
751+
* bottom: ['parent', 'bottom',0],
752+
* style: 'spread'
753+
* }
754+
755+
* @throws CLParsingException
756+
*/
757+
private static void parseChainType(String orientation,
758+
State state,
759+
String chainName,
760+
LayoutVariables margins,
761+
CLObject object) throws CLParsingException {
762+
763+
ChainReference chain = (orientation.charAt(0) == 'h')
764+
? state.horizontalChain() : state.verticalChain();
765+
chain.setKey(chainName);
766+
767+
for (String params : object.names()) {
768+
switch (params) {
769+
case "contains":
770+
CLElement refs = object.get(params);
771+
if (!(refs instanceof CLArray) || ((CLArray) refs).size() < 1) {
772+
System.err.println(
773+
chainName + " contains should be an array \"" + refs.content()
774+
+ "\"");
775+
return;
776+
}
777+
for (int i = 0; i < ((CLArray) refs).size(); i++) {
778+
CLElement chainElement = ((CLArray) refs).get(i);
779+
if (chainElement instanceof CLArray) {
780+
CLArray array = (CLArray) chainElement;
781+
if (array.size() > 0) {
782+
String id = array.get(0).content();
783+
chain.add(id);
784+
float weight = Float.NaN;
785+
float preMargin = Float.NaN;
786+
float postMargin = Float.NaN;
787+
switch (array.size()) {
788+
case 2: // sets only the weight
789+
weight = array.getFloat(1);
790+
break;
791+
case 3: // sets the pre and post margin to the 2 arg
792+
weight = array.getFloat(1);
793+
postMargin = preMargin = toPix(state, array.getFloat(2));
794+
break;
795+
case 4: // sets the pre and post margin
796+
weight = array.getFloat(1);
797+
preMargin = toPix(state, array.getFloat(2));
798+
postMargin = toPix(state, array.getFloat(3));
799+
break;
800+
}
801+
chain.addChainElement(id, weight, preMargin, postMargin);
802+
}
803+
} else {
804+
chain.add(chainElement.content());
805+
}
806+
}
807+
break;
808+
case "start":
809+
case "end":
810+
case "top":
811+
case "bottom":
812+
case "left":
813+
case "right":
814+
parseConstraint(state, margins, object, chain, params);
815+
break;
816+
case "style":
817+
818+
CLElement styleObject = object.get(params);
819+
String styleValue;
820+
if (styleObject instanceof CLArray && ((CLArray) styleObject).size() > 1) {
821+
styleValue = ((CLArray) styleObject).getString(0);
822+
float biasValue = ((CLArray) styleObject).getFloat(1);
823+
chain.bias(biasValue);
824+
} else {
825+
styleValue = styleObject.content();
826+
}
827+
switch (styleValue) {
828+
case "packed":
829+
chain.style(State.Chain.PACKED);
830+
break;
831+
case "spread_inside":
832+
chain.style(State.Chain.SPREAD_INSIDE);
833+
break;
834+
default:
835+
chain.style(State.Chain.SPREAD);
836+
break;
837+
}
838+
839+
break;
840+
}
841+
}
842+
}
729843

730844
static void parseGuideline(int orientation,
731845
State state, CLArray helper) throws CLParsingException {
@@ -738,7 +852,6 @@ static void parseGuideline(int orientation,
738852
parseGuidelineParams(orientation, state, guidelineId, (CLObject) params);
739853
}
740854

741-
742855
static void parseGuidelineParams(
743856
int orientation,
744857
State state,
@@ -980,10 +1093,8 @@ static void parseWidget(
9801093

9811094
}
9821095
}
983-
9841096
}
9851097

986-
9871098
static void parseCustomProperties(
9881099
CLObject element,
9891100
ConstraintReference reference,
@@ -1019,7 +1130,6 @@ private static int indexOf(String val, String... types) {
10191130
return -1;
10201131
}
10211132

1022-
10231133
/**
10241134
* parse the motion section of a constraint
10251135
* <pre>

constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@
1919
import androidx.constraintlayout.core.state.HelperReference;
2020
import androidx.constraintlayout.core.state.State;
2121

22+
import java.util.HashMap;
23+
2224
public class ChainReference extends HelperReference {
2325

2426
protected float mBias = 0.5f;
27+
protected HashMap<String ,Float> mMapWeights;
28+
protected HashMap<String,Float> mMapPreMargin;
29+
protected HashMap<String,Float> mMapPostMargin;
30+
2531
protected State.Chain mStyle = State.Chain.SPREAD;
2632

2733
public ChainReference(State state, State.Helper type) {
@@ -40,6 +46,52 @@ public ChainReference style(State.Chain style) {
4046
return this;
4147
}
4248

49+
public void addChainElement(String id, float weight, float preMargin, float postMargin ) {
50+
super.add(id);
51+
if (!Float.isNaN(weight)) {
52+
if (mMapWeights == null) {
53+
mMapWeights = new HashMap<>();
54+
}
55+
mMapWeights.put(id, weight);
56+
}
57+
if (!Float.isNaN(preMargin)) {
58+
if (mMapPreMargin == null) {
59+
mMapPreMargin = new HashMap<>();
60+
}
61+
mMapPreMargin.put(id, preMargin);
62+
}
63+
if (!Float.isNaN(postMargin)) {
64+
if (mMapPostMargin == null) {
65+
mMapPostMargin = new HashMap<>();
66+
}
67+
mMapPostMargin.put(id, postMargin);
68+
}
69+
}
70+
71+
protected float getWeight(String id) {
72+
if (mMapWeights == null) {
73+
return -1;
74+
}
75+
if (mMapWeights.containsKey(id)) {
76+
return mMapWeights.get(id);
77+
}
78+
return 1;
79+
}
80+
81+
protected float getPostMargin(String id) {
82+
if (mMapPostMargin != null && mMapPostMargin.containsKey(id)) {
83+
return mMapPostMargin.get(id);
84+
}
85+
return 0;
86+
}
87+
88+
protected float getPreMargin(String id) {
89+
if (mMapPreMargin != null && mMapPreMargin.containsKey(id)) {
90+
return mMapPreMargin.get(id);
91+
}
92+
return 0;
93+
}
94+
4395
public float getBias() {
4496
return mBias;
4597
}

constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/helpers/HorizontalChainReference.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public void apply() {
3939

4040
for (Object key : mReferences) {
4141
ConstraintReference reference = mState.constraints(key);
42+
4243
if (first == null) {
4344
first = reference;
4445
if (mStartToStart != null) {
@@ -55,13 +56,17 @@ public void apply() {
5556
first.startToEnd(mLeftToRight).margin(mMarginLeft).marginGone(mMarginLeftGone);
5657
} else {
5758
// No constraint declared, default to Parent.
58-
first.startToStart(State.PARENT);
59+
String refKey = reference.getKey().toString();
60+
first.startToStart(State.PARENT).margin(getPreMargin(refKey));
5961
}
6062
}
6163
if (previous != null) {
62-
previous.endToStart(reference.getKey());
63-
reference.startToEnd(previous.getKey());
64+
String preKey = previous.getKey().toString();
65+
String refKey = reference.getKey().toString();
66+
previous.endToStart(reference.getKey()).margin(getPostMargin(preKey));
67+
reference.startToEnd(previous.getKey()).margin(getPreMargin(refKey));
6468
}
69+
reference.setHorizontalChainWeight(getWeight(key.toString()));
6570
previous = reference;
6671
}
6772

@@ -78,7 +83,8 @@ public void apply() {
7883
previous.endToEnd(mRightToRight).margin(mMarginRight).marginGone(mMarginRightGone);
7984
} else {
8085
// No constraint declared, default to Parent.
81-
previous.endToEnd(State.PARENT);
86+
String preKey = previous.getKey().toString();
87+
previous.endToEnd(State.PARENT).margin(getPostMargin(preKey));
8288
}
8389
}
8490

constraintlayout/core/src/main/java/androidx/constraintlayout/core/state/helpers/VerticalChainReference.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ public void apply() {
4747
first.topToBottom(mTopToBottom).margin(mMarginTop).marginGone(mMarginTopGone);
4848
} else {
4949
// No constraint declared, default to Parent.
50-
first.topToTop(State.PARENT);
50+
String refKey = reference.getKey().toString();
51+
first.topToTop(State.PARENT).margin(getPreMargin(refKey));
5152
}
5253
}
5354
if (previous != null) {
54-
previous.bottomToTop(reference.getKey());
55-
reference.topToBottom(previous.getKey());
55+
String preKey = previous.getKey().toString();
56+
String refKey = reference.getKey().toString();
57+
previous.bottomToTop(reference.getKey()).margin(getPostMargin(preKey));
58+
reference.topToBottom(previous.getKey()).margin(getPreMargin(refKey));
5659
}
60+
reference.setVerticalChainWeight(getWeight(key.toString()));
5761
previous = reference;
5862
}
5963

@@ -68,7 +72,8 @@ public void apply() {
6872
.marginGone(mMarginBottomGone);
6973
} else {
7074
// No constraint declared, default to Parent.
71-
previous.bottomToBottom(State.PARENT);
75+
String preKey = previous.getKey().toString();
76+
previous.bottomToBottom(State.PARENT).margin(getPostMargin(preKey));
7277
}
7378
}
7479

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/caches
5+
/.idea/libraries
6+
/.idea/modules.xml
7+
/.idea/workspace.xml
8+
/.idea/navEditor.xml
9+
/.idea/assetWizardSettings.xml
10+
.DS_Store
11+
/build
12+
/captures
13+
.externalNativeBuild
14+
.cxx
15+
local.properties

demoProjects/ComposeConstraintLayoutDemo/.idea/.gitignore

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
plugins {
2+
id 'com.android.application'
3+
id 'org.jetbrains.kotlin.android'
4+
}
5+
6+
android {
7+
namespace 'androidx.demo.motiondemos'
8+
compileSdk 32
9+
10+
defaultConfig {
11+
applicationId "androidx.demo.motiondemos"
12+
minSdk 21
13+
targetSdk 32
14+
versionCode 1
15+
versionName "1.0"
16+
17+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18+
vectorDrawables {
19+
useSupportLibrary true
20+
}
21+
}
22+
23+
buildTypes {
24+
release {
25+
minifyEnabled false
26+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
27+
}
28+
}
29+
compileOptions {
30+
sourceCompatibility JavaVersion.VERSION_1_8
31+
targetCompatibility JavaVersion.VERSION_1_8
32+
}
33+
kotlinOptions {
34+
jvmTarget = '1.8'
35+
}
36+
buildFeatures {
37+
compose true
38+
}
39+
composeOptions {
40+
kotlinCompilerExtensionVersion '1.1.1'
41+
}
42+
packagingOptions {
43+
resources {
44+
excludes += '/META-INF/{AL2.0,LGPL2.1}'
45+
}
46+
}
47+
}
48+
49+
dependencies {
50+
51+
implementation 'androidx.core:core-ktx:1.7.0'
52+
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
53+
implementation 'androidx.activity:activity-compose:1.3.1'
54+
implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha01'
55+
implementation "androidx.compose.ui:ui:$compose_ui_version"
56+
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
57+
implementation 'androidx.compose.material:material:1.1.1'
58+
testImplementation 'junit:junit:4.13.2'
59+
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
60+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
61+
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
62+
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
63+
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
64+
}

0 commit comments

Comments
 (0)