Add resource support in binding expression.
Change-Id: Iccb8c3a5856c247d8245fe97a3c37cd60bb7e758
This commit is contained in:
@@ -143,6 +143,11 @@ public class ExpressionVisitor extends BindingExpressionBaseVisitor<Expr> {
|
||||
return mModel.math(ctx.left.accept(this), ctx.op.getText(), ctx.right.accept(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr visitResource(@NotNull BindingExpressionParser.ResourceContext ctx) {
|
||||
return mModel.resourceExpr(ctx.getText());
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Expr visitIdentifier(@NotNull BindingExpressionParser.IdentifierContext ctx) {
|
||||
// final String identifier = ctx.Identifier().getText();
|
||||
|
||||
@@ -124,7 +124,7 @@ abstract public class Expr {
|
||||
|
||||
private BitSet resolveInvalidFlags() {
|
||||
BitSet bitSet = new BitSet();
|
||||
if (mCanBeInvalidated) {
|
||||
if (mCanBeInvalidated || getDependants().isEmpty()) {
|
||||
bitSet.set(getId(), true);
|
||||
}
|
||||
for (Dependency dependency : getDependencies()) {
|
||||
|
||||
@@ -142,6 +142,10 @@ public class ExprModel {
|
||||
return register(new GroupExpr(grouped));
|
||||
}
|
||||
|
||||
public Expr resourceExpr(String resourceText) {
|
||||
return register(new ResourceExpr(resourceText));
|
||||
}
|
||||
|
||||
public List<Expr> getBindingExpressions() {
|
||||
return mBindingExpressions;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.databinding.expr;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import com.android.databinding.ClassAnalyzer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ResourceExpr extends Expr {
|
||||
|
||||
private final static Map<String, String> RESOURCE_TYPE_TO_R_OBJECT =
|
||||
ImmutableMap.<String, String>builder()
|
||||
.put("colorStateList", "color ")
|
||||
.put("dimenOffset", "dimen ")
|
||||
.put("dimenSize", "dimen ")
|
||||
.put("intArray", "array ")
|
||||
.put("stateListAnimator", "animator ")
|
||||
.put("stringArray", "array ")
|
||||
.put("typedArray", "array")
|
||||
.build();
|
||||
|
||||
private final String mPackage;
|
||||
|
||||
private final String mResourceType;
|
||||
|
||||
private final String mResourceId;
|
||||
|
||||
public ResourceExpr(String resourceText) {
|
||||
int colonIndex = resourceText.indexOf(':');
|
||||
int slashIndex = resourceText.indexOf('/');
|
||||
mResourceType = resourceText.substring(colonIndex + 1, slashIndex).trim();
|
||||
mResourceId = resourceText.substring(slashIndex + 1).trim();
|
||||
String packageName = "";
|
||||
if (colonIndex > 1) {
|
||||
if ("android".equals(resourceText.substring(1, colonIndex).trim())) {
|
||||
packageName = "android.";
|
||||
} else {
|
||||
packageName = "";
|
||||
}
|
||||
}
|
||||
mPackage = packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class resolveType(ClassAnalyzer classAnalyzer) {
|
||||
String type;
|
||||
switch (mResourceType) {
|
||||
case "anim":
|
||||
type = "android.view.animation.Animation";
|
||||
break;
|
||||
case "animator":
|
||||
type = "android.animation.Animator";
|
||||
break;
|
||||
case "bool":
|
||||
return boolean.class;
|
||||
case "color":
|
||||
return int.class;
|
||||
case "colorStateList":
|
||||
type = "android.content.res.ColorStateList";
|
||||
break;
|
||||
case "dimen":
|
||||
return float.class;
|
||||
case "dimenOffset":
|
||||
return int.class;
|
||||
case "dimenSize":
|
||||
return int.class;
|
||||
case "drawable":
|
||||
type = "android.graphics.drawable.Drawable";
|
||||
break;
|
||||
case "fraction":
|
||||
return float.class;
|
||||
case "id":
|
||||
return int.class;
|
||||
case "intArray":
|
||||
return int[].class;
|
||||
case "integer":
|
||||
return int.class;
|
||||
case "interpolator":
|
||||
type = "";
|
||||
break;
|
||||
case "layout":
|
||||
return int.class;
|
||||
case "plurals":
|
||||
return int.class;
|
||||
case "stateListAnimator":
|
||||
type = "android.animation.StateListAnimator";
|
||||
break;
|
||||
case "string":
|
||||
return String.class;
|
||||
case "stringArray":
|
||||
return String[].class;
|
||||
case "transition":
|
||||
type = "android.transition.Transition";
|
||||
break;
|
||||
case "typedArray":
|
||||
type = "android.content.res.TypedArray";
|
||||
break;
|
||||
default:
|
||||
type = mResourceType;
|
||||
break;
|
||||
}
|
||||
return classAnalyzer.findClass(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Dependency> constructDependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String computeUniqueKey() {
|
||||
if (mPackage == null) {
|
||||
return "@" + mResourceType + "/" + mResourceId;
|
||||
} else {
|
||||
return "@" + "android:" + mResourceType + "/" + mResourceId;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeInvalidated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toJava() {
|
||||
final String context = "mRoot.getContext()";
|
||||
final String resources = context + ".getResources()";
|
||||
final String resourceName = mPackage + "R." + getResourceObject() + "." + mResourceId;
|
||||
switch (mResourceType) {
|
||||
case "anim": return "android.view.animation.AnimationUtils.loadAnimation(" + context + ", " + resourceName + ")";
|
||||
case "animator": return "android.animation.AnimatorInflater.loadAnimator(" + context + ", " + resourceName + ")";
|
||||
case "bool": return resources + ".getBoolean(" + resourceName + ")";
|
||||
case "color": return resources + ".getColor(" + resourceName + ")";
|
||||
case "colorStateList": return resources + ".getColorStateList(" + resourceName + ")";
|
||||
case "dimen": return resources + ".getDimension(" + resourceName + ")";
|
||||
case "dimenOffset": return resources + ".getDimensionPixelOffset(" + resourceName + ")";
|
||||
case "dimenSize": return resources + ".getDimensionPixelSize(" + resourceName + ")";
|
||||
case "drawable": return resources + ".getDrawable(" + resourceName + ")";
|
||||
case "fraction": return resources + ".getFraction(" + resourceName + ", 1, 1)";
|
||||
case "id": return resourceName;
|
||||
case "intArray": return resources + ".getIntArray(" + resourceName + ")";
|
||||
case "integer": return resources + ".getInteger(" + resourceName + ")";
|
||||
case "interpolator": return "android.view.animation.AnimationUtils.loadInterpolator(" + context + ", " + resourceName + ")";
|
||||
case "layout": return resourceName;
|
||||
case "plurals": return resourceName;
|
||||
case "stateListAnimator": return "android.animation.AnimatorInflater.loadStateListAnimator(" + context + ", " + resourceName + ")";
|
||||
case "string": return resources + ".getString(" + resourceName + ")";
|
||||
case "stringArray": return resources + ".getStringArray(" + resourceName + ")";
|
||||
case "transition": return "android.transition.TransitionInflater.from(" + context + ").inflateTransition(" + resourceName + ")";
|
||||
case "typedArray": return resources + ".obtainTypedArray(" + resourceName + ")";
|
||||
}
|
||||
final String property = Character.toUpperCase(mResourceType.charAt(0)) +
|
||||
mResourceType.substring(1);
|
||||
return resources + ".get" + property + "(" + resourceName + ")";
|
||||
|
||||
}
|
||||
|
||||
private String getResourceObject() {
|
||||
String rFileObject = RESOURCE_TYPE_TO_R_OBJECT.get(mResourceType);
|
||||
if (rFileObject == null) {
|
||||
rFileObject = mResourceType;
|
||||
}
|
||||
return rFileObject;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.databinding.store;
|
||||
|
||||
import com.android.databinding.ClassAnalyzer;
|
||||
import com.android.databinding.util.L;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -318,8 +317,6 @@ public class SetterStore {
|
||||
|
||||
public String getSetterCall(String attribute, Class<?> viewType, Class<?> valueType,
|
||||
String viewExpression, String valueExpression) {
|
||||
L.d("getting setter call for %s %s %s %s %s", attribute, viewType, valueType,
|
||||
viewExpression, valueExpression);
|
||||
if (!attribute.startsWith("android:")) {
|
||||
int colon = attribute.indexOf(':');
|
||||
if (colon >= 0) {
|
||||
@@ -327,11 +324,9 @@ public class SetterStore {
|
||||
}
|
||||
}
|
||||
ArrayList<AdaptedMethod> adapters = mAdaptedMethods.get(attribute);
|
||||
L.d("returned adapter count %d", adapters == null ? -1 : adapters.size());
|
||||
AdaptedMethod adapter = null;
|
||||
String setterName = null;
|
||||
Method bestSetterMethod = getBestSetter(viewType, valueType, attribute);
|
||||
L.d("setter method: %s", bestSetterMethod == null ? "null" : bestSetterMethod.getName());
|
||||
Class<?> bestViewType = null;
|
||||
Class<?> bestValueType = null;
|
||||
if (bestSetterMethod != null) {
|
||||
@@ -342,7 +337,6 @@ public class SetterStore {
|
||||
|
||||
if (adapters != null) {
|
||||
for (AdaptedMethod adaptedMethod : adapters) {
|
||||
L.d("checking adapter method %s", adaptedMethod);
|
||||
if (adaptedMethod.viewType.isAssignableFrom(viewType)) {
|
||||
boolean isBetterView = bestViewType == null ||
|
||||
bestValueType.isAssignableFrom(adaptedMethod.valueType);
|
||||
@@ -351,12 +345,7 @@ public class SetterStore {
|
||||
bestViewType = adaptedMethod.viewType;
|
||||
bestValueType = adaptedMethod.valueType;
|
||||
adapter = adaptedMethod;
|
||||
L.d("chosen %s", adaptedMethod);
|
||||
} else {
|
||||
L.d("not better");
|
||||
}
|
||||
} else {
|
||||
L.d("not assignable");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,16 +458,12 @@ public class SetterStore {
|
||||
}
|
||||
|
||||
private ConversionMethod getConversionMethod(Class<?> from, Class<?> to) {
|
||||
System.out.println("Getting conversion from " + from + " to " + to);
|
||||
if (from != null && to != null) {
|
||||
for (ConversionMethod conversion : mConversionMethods) {
|
||||
System.out.println("Testing " + conversion.fromType + " to " + conversion.toType);
|
||||
if (canUseForConversion(from, conversion.fromType) &&
|
||||
canUseForConversion(conversion.toType, to)) {
|
||||
System.out.println("Yes!");
|
||||
return conversion;
|
||||
}
|
||||
System.out.println("Nope!");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.android.databinding.ext.lazy
|
||||
import com.android.databinding.ext.br
|
||||
import com.android.databinding.ext.toJavaCode
|
||||
import com.android.databinding.ext.isObservable
|
||||
import com.android.databinding.expr.ResourceExpr
|
||||
|
||||
fun Expr.isObservable() = com.android.databinding.ClassAnalyzer.getInstance().isObservable(this.getResolvedType())
|
||||
|
||||
@@ -190,6 +191,9 @@ fun Expr.toCode(full : Boolean = false) : KCode {
|
||||
app("?", it.getIfTrue().toCode())
|
||||
app(":", it.getIfFalse().toCode())
|
||||
}
|
||||
is ResourceExpr -> kcode("") {
|
||||
app("", it.toJava())
|
||||
}
|
||||
else -> kcode("//NOT IMPLEMENTED YET")
|
||||
}
|
||||
|
||||
|
||||
@@ -445,25 +445,25 @@ fragment
|
||||
ResourceType
|
||||
: 'anim'
|
||||
| 'animator'
|
||||
| 'array'
|
||||
| 'attr'
|
||||
| 'bool'
|
||||
| 'color'
|
||||
| 'colorStateList'
|
||||
| 'dimen'
|
||||
| 'dimenOffset'
|
||||
| 'dimenSize'
|
||||
| 'drawable'
|
||||
| 'fraction'
|
||||
| 'id'
|
||||
| 'integer'
|
||||
| 'intArray'
|
||||
| 'interpolator'
|
||||
| 'layout'
|
||||
| 'menu'
|
||||
| 'mipmap'
|
||||
| 'plurals'
|
||||
| 'raw'
|
||||
| 'stateListAnimator'
|
||||
| 'string'
|
||||
| 'style'
|
||||
| 'stringArray'
|
||||
| 'transition'
|
||||
| 'xml'
|
||||
| 'typedArray'
|
||||
;
|
||||
|
||||
ResourceName
|
||||
|
||||
@@ -39,11 +39,6 @@ import android.view.View;
|
||||
})
|
||||
public class ViewBindingAdapter {
|
||||
|
||||
@BindingAdapter("android:background")
|
||||
public static void setBackground(View view, int color) {
|
||||
view.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
@BindingAdapter("android:padding")
|
||||
public static void setPadding(View view, int padding) {
|
||||
view.setPadding(padding, padding, padding, padding);
|
||||
|
||||
Reference in New Issue
Block a user