summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/src/main/java/android/databinding/tool/Binding.java46
-rw-r--r--compiler/src/main/java/android/databinding/tool/store/SetterStore.java86
-rw-r--r--integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/IncludeTagTest.java5
-rw-r--r--integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/IncludeTagAdapter.java29
-rw-r--r--integration-tests/TestApp/app/src/main/res/layout/layout_with_include.xml10
5 files changed, 119 insertions, 57 deletions
diff --git a/compiler/src/main/java/android/databinding/tool/Binding.java b/compiler/src/main/java/android/databinding/tool/Binding.java
index 3c2ed67e..530b6b7c 100644
--- a/compiler/src/main/java/android/databinding/tool/Binding.java
+++ b/compiler/src/main/java/android/databinding/tool/Binding.java
@@ -120,9 +120,7 @@ public class Binding implements LocationScopeProvider {
private void resolveSetterCall() {
ModelClass viewType = mTarget.getResolvedType();
- if ("android:visibility".equals(mName) && viewType != null && viewType.isViewDataBinding()) {
- mSetterCall = new IncludeVisibilityCall();
- } else if (viewType != null && viewType.getExtendsViewStub()) {
+ if (viewType != null && viewType.getExtendsViewStub()) {
mExpr = mExpr.unwrapObservableField();
if (isListenerAttribute(mName)) {
ModelAnalyzer modelAnalyzer = ModelAnalyzer.getInstance();
@@ -361,46 +359,4 @@ public class Binding implements LocationScopeProvider {
return mWrappedCall.getDescription();
}
}
-
- private static class IncludeVisibilityCall extends SetterCall {
-
- @Override
- public boolean requiresOldValue() {
- return false;
- }
-
- @Override
- public ModelClass[] getParameterTypes() {
- return new ModelClass[] {
- ModelAnalyzer.getInstance().loadPrimitive("int")
- };
- }
-
- @Override
- public String getBindingAdapterInstanceClass() {
- return null;
- }
-
- @Override
- public String getDescription() {
- return "setVisibility(value)";
- }
-
- @Override
- protected String toJavaInternal(String componentExpression, String viewExpression,
- String converted) {
- return viewExpression + ".getRoot().setVisibility(" + converted + ")";
- }
-
- @Override
- protected String toJavaInternal(String componentExpression, String viewExpression,
- String oldValue, String converted) {
- return null;
- }
-
- @Override
- public int getMinApi() {
- return 0;
- }
- }
}
diff --git a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
index c04d73db..12a397c0 100644
--- a/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
+++ b/compiler/src/main/java/android/databinding/tool/store/SetterStore.java
@@ -25,10 +25,19 @@ import android.databinding.tool.util.GenerationalClassUtil;
import android.databinding.tool.util.L;
import android.databinding.tool.util.Preconditions;
import android.databinding.tool.util.StringUtils;
-
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
@@ -45,17 +54,6 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Types;
-
public class SetterStore {
private static final int ASSIGNABLE_CONVERSION = 1;
private final BindingAdapterStore mStore;
@@ -625,6 +623,18 @@ public class SetterStore {
bestSetter.setterCall.setConverter(conversionMethod);
}
+ if (bestSetter.setterCall == null && viewType.isViewDataBinding()) {
+ // if it is a binding, try to find setter on the view class.
+ SetterCall rootViewSetter = getSetterCall(
+ attribute,
+ viewType.findInstanceGetter("getRoot").getReturnType(),
+ valueType,
+ imports);
+ if (rootViewSetter != null) {
+ // replace with a root view getter and return it
+ return new ViewBindingRootViewSetterCall(rootViewSetter);
+ }
+ }
return bestSetter.setterCall;
}
@@ -2091,4 +2101,56 @@ public class SetterStore {
this.viewType = viewType;
}
}
+
+ /**
+ * A ViewBinding can support setters on its root view. This wrapper is injected when include tag
+ * has a binding on directly its view.
+ */
+ private static class ViewBindingRootViewSetterCall extends SetterCall {
+
+ private final SetterCall mWrapped;
+
+ public ViewBindingRootViewSetterCall(SetterCall wrapped) {
+ mWrapped = wrapped;
+ }
+
+ @Override
+ public boolean requiresOldValue() {
+ return mWrapped.requiresOldValue();
+ }
+
+ @Override
+ public ModelClass[] getParameterTypes() {
+ return mWrapped.getParameterTypes();
+ }
+
+ @Override
+ public String getBindingAdapterInstanceClass() {
+ return mWrapped.getBindingAdapterInstanceClass();
+ }
+
+ @Override
+ public String getDescription() {
+ return mWrapped.getDescription();
+ }
+
+ @Override
+ protected String toJavaInternal(String componentExpression, String viewExpression,
+ String converted) {
+ return mWrapped.toJavaInternal(componentExpression, viewExpression + ".getRoot()",
+ converted);
+ }
+
+ @Override
+ protected String toJavaInternal(String componentExpression, String viewExpression,
+ String oldValue, String converted) {
+ return mWrapped.toJavaInternal(componentExpression, viewExpression + ".getRoot()",
+ oldValue, converted);
+ }
+
+ @Override
+ public int getMinApi() {
+ return mWrapped.getMinApi();
+ }
+ }
}
diff --git a/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/IncludeTagTest.java b/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/IncludeTagTest.java
index 1b5013fa..1d45e23c 100644
--- a/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/IncludeTagTest.java
+++ b/integration-tests/TestApp/app/src/androidTest/java/android/databinding/testapp/IncludeTagTest.java
@@ -103,6 +103,11 @@ public class IncludeTagTest extends BaseDataBinderTest<LayoutWithIncludeBinding>
assertEquals(mBinder.includedPlainLayout.getClass(), FrameLayout.class);
assertEquals(((FrameLayout) mBinder.includedPlainLayout).getChildCount(), 0);
assertNull(mBinder.includedMergeLayout);
+
+ mBinder.setMinHeight(41);
+ mBinder.executePendingBindings();
+ assertEquals(mBinder.bindingLayoutWithRootViewAdapter.getRoot().getMinimumHeight(), 41);
+ assertEquals(mBinder.plainLayoutWithBinding.getMinimumHeight(), 41);
}
// Make sure that when an included layout's executePendingBindings is run that the include
diff --git a/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/IncludeTagAdapter.java b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/IncludeTagAdapter.java
new file mode 100644
index 00000000..be79a409
--- /dev/null
+++ b/integration-tests/TestApp/app/src/main/java/android/databinding/testapp/adapter/IncludeTagAdapter.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.databinding.testapp.adapter;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.databinding.BindingAdapter;
+
+public class IncludeTagAdapter {
+ @BindingAdapter("includeMinHeightAdapter")
+ public static void setMinHeightVia(View view, int minHeight) {
+ view.setMinimumHeight(minHeight);
+ }
+}
diff --git a/integration-tests/TestApp/app/src/main/res/layout/layout_with_include.xml b/integration-tests/TestApp/app/src/main/res/layout/layout_with_include.xml
index 1b478586..dfffd996 100644
--- a/integration-tests/TestApp/app/src/main/res/layout/layout_with_include.xml
+++ b/integration-tests/TestApp/app/src/main/res/layout/layout_with_include.xml
@@ -19,6 +19,7 @@
<variable name="outerObject" type="android.databinding.testapp.vo.NotBindableVo"/>
<variable name="map" type="ObservableArrayMap&lt;String, String&gt;"/>
<variable name="visibility" type="int"/>
+ <variable name="minHeight" type="int" />
</data>
<FrameLayout
android:layout_width="match_parent"
@@ -78,6 +79,15 @@
android:id="@+id/trackedInclude"
layout="@layout/include_tracker"
android:innerObject="@{outerObject}"/>
+ <include
+ layout="@layout/simple_text"
+ android:id="@+id/plainLayoutWithBinding"
+ bind:includeMinHeightAdapter="@{minHeight}"/>
+ <include
+ layout="@layout/included_layout"
+ android:id="@+id/bindingLayoutWithRootViewAdapter"
+ bind:includeMinHeightAdapter="@{minHeight}"/>
+
</LinearLayout>
</FrameLayout>
</layout>