feat(autojs): base view attrs

This commit is contained in:
hyb1996 2018-10-12 19:41:16 +08:00
parent f0d9ef1367
commit d80d871a8d
6 changed files with 290 additions and 18 deletions

View File

@ -145,7 +145,7 @@ public class EventEmitter {
}
public String[] eventNames() {
return mListenersMap.keySet().toArray(new String[mListenersMap.size()]);
return mListenersMap.keySet().toArray(new String[0]);
}
public int listenerCount(String eventName) {

View File

@ -46,5 +46,21 @@ public class Functions {
R call(T1 t1, T2 t2, T3 t3, T4 t4);
}
public interface VoidFunc1<T1> extends Func {
void call(T1 t1);
}
public interface VoidFunc2<T1, T2> extends Func {
void call(T1 t1, T2 t2);
}
public interface VoidFunc3<T1, T2, T3> extends Func {
void call(T1 t1, T2 t2, T3 t3);
}
public interface VoidFunc4<T1, T2, T3, T4> extends Func {
void call(T1 t1, T2 t2, T3 t3, T4 t4);
}
}

View File

@ -1,26 +1,44 @@
package com.stardust.autojs.core.ui.attribute;
import android.annotation.SuppressLint;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.CallSuper;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.stardust.autojs.R;
import com.stardust.autojs.core.internal.Functions;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
import com.stardust.autojs.core.ui.inflater.util.Gravities;
import com.stardust.autojs.core.ui.inflater.util.Ids;
import com.stardust.autojs.core.ui.inflater.util.Strings;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.DRAWABLE_CACHE_QUALITIES;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.IMPORTANT_FOR_ACCESSIBILITY;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.LAYOUT_DIRECTIONS;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.SCROLLBARS_STYLES;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.SCROLL_INDICATORS;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.TEXT_ALIGNMENTS;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.TEXT_DIRECTIONS;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.TINT_MODES;
import static com.stardust.autojs.core.ui.inflater.inflaters.BaseViewInflater.VISIBILITY;
public class ViewAttributes {
public interface Attribute {
@ -118,6 +136,123 @@ public class ViewAttributes {
registerDrawableAttrs(new String[]{"bg", "background"}, mView::setBackground);
registerAttr("layout_gravity", Gravities::parse, this::setLayoutGravity);
registerAttr("layout_weight", Float::parseFloat, this::setLayoutWeight);
registerAttr("layout_margin", this::parseDimension, this::setMargin);
registerAttr("layout_marginLeft", this::parseDimension, this::setMarginLeft);
registerAttr("layout_marginRight", this::parseDimension, this::setMarginRight);
registerAttr("layout_marginTop", this::parseDimension, this::setMarginTop);
registerAttr("layout_marginBottom", this::parseDimension, this::setMarginBottom);
registerAttr("layout_marginStart", this::parseDimension, this::setMarginStart);
registerAttr("layout_marginEnd", this::parseDimension, this::setMarginEnd);
registerAttr("padding", this::parseDimension, this::setPadding);
registerAttr("paddingLeft", this::parseDimension, this::setPaddingLeft);
registerAttr("paddingRight", this::parseDimension, this::setPaddingRight);
registerAttr("paddingTop", this::parseDimension, this::setPaddingTop);
registerAttr("paddingBottom", this::parseDimension, this::setPaddingBottom);
registerAttr("paddingStart", this::parseDimension, this::setPaddingStart);
registerAttr("paddingEnd", this::parseDimension, this::setPaddingEnd);
registerAttr("alpha", Float::parseFloat, mView::setAlpha);
registerAttr("backgroundTint", Color::parseColor, this::setBackgroundTint);
registerAttr("backgroundTintMode", TINT_MODES::get,
bind(ViewCompat::setBackgroundTintMode, mView));
registerAttr("clickable", Boolean::parseBoolean, mView::setClickable);
registerAttr("checked", Boolean::parseBoolean, this::setChecked);
registerAttr("contentDescription", this::parseString, mView::setContentDescription);
registerAttr("contextClickable", Boolean::parseBoolean, this::setContextClickable);
registerAttr("scaleX", Float::parseFloat, mView::setScaleX);
registerAttr("scaleY", Float::parseFloat, mView::setScaleY);
registerAttr("rotation", Float::parseFloat, mView::setRotation);
registerAttr("rotationX", Float::parseFloat, mView::setRotationX);
registerAttr("rotationY", Float::parseFloat, mView::setRotationY);
registerAttr("saveEnabled", Boolean::parseBoolean, mView::setSaveEnabled);
registerAttr("transformPivotX", this::parseDimensionToPixel, mView::setPivotX);
registerAttr("transformPivotY", this::parseDimensionToPixel, mView::setPivotY);
registerAttr("translationX", this::parseDimensionToPixel, mView::setTranslationX);
registerAttr("translationY", this::parseDimensionToPixel, mView::setTranslationY);
registerAttr("visibility", VISIBILITY::get, mView::setVisibility);
registerAttr("tag", this::parseString, mView::setTag);
registerAttr("soundEffectsEnabled", Boolean::parseBoolean, mView::setSoundEffectsEnabled);
registerAttr("scrollbarStyle", SCROLLBARS_STYLES::get, mView::setScrollBarStyle);
registerAttr("scrollX", this::parseDimensionToIntPixel, mView::setScrollX);
registerAttr("scrollY", this::parseDimensionToIntPixel, mView::setScrollY);
registerAttr("scrollIndicators", SCROLL_INDICATORS::get, bind(ViewCompat::setScrollIndicators, mView));
registerAttr("scrollbarDefaultDelayBeforeFade", Integer::valueOf, mView::setScrollBarDefaultDelayBeforeFade);
registerAttr("scrollbarFadeDuration", Integer::valueOf, mView::setScrollBarFadeDuration);
registerAttr("scrollbarSize", this::parseDimensionToIntPixel, mView::setScrollBarSize);
registerAttr("textAlignment", TEXT_ALIGNMENTS::get, mView::setTextAlignment);
registerAttr("textDirection", TEXT_DIRECTIONS::get, mView::setTextDirection);
registerAttr("transitionName", this::parseString, bind(ViewCompat::setTransitionName, mView));
registerAttr("translationZ", this::parseDimensionToPixel, bind(ViewCompat::setTranslationZ, mView));
registerAttr("scrollbars", this::setScrollbars);
registerAttr("drawingCacheQuality", DRAWABLE_CACHE_QUALITIES::get, mView::setDrawingCacheQuality);
registerAttr("duplicateParentState", Boolean::parseBoolean, mView::setDuplicateParentStateEnabled);
registerAttr("fadeScrollbars", Boolean::valueOf, mView::setScrollbarFadingEnabled);
registerAttr("fadingEdgeLength", this::parseDimensionToIntPixel, mView::setFadingEdgeLength);
registerAttr("filterTouchesWhenObscured", Boolean::valueOf, mView::setFilterTouchesWhenObscured);
registerAttr("fitsSystemWindows", Boolean::valueOf, mView::setFitsSystemWindows);
registerAttr("focusable", Boolean::valueOf, mView::setFocusable);
registerAttr("focusableInTouchMode", Boolean::valueOf, mView::setFocusableInTouchMode);
registerAttr("hapticFeedbackEnabled", Boolean::valueOf, mView::setHapticFeedbackEnabled);
registerAttr("isScrollContainer", Boolean::valueOf, mView::setScrollContainer);
registerAttr("keepScreenOn", Boolean::valueOf, mView::setKeepScreenOn);
registerAttr("longClickable", Boolean::valueOf, mView::setLongClickable);
registerAttr("minHeight", this::parseDimensionToIntPixel, mView::setMinimumHeight);
registerAttr("minWidth", this::parseDimensionToIntPixel, mView::setMinimumWidth);
registerAttr("elevation", this::parseDimensionToIntPixel, this::setElevation);
registerAttr("forceHasOverlappingRendering", Boolean::valueOf, this::forceHasOverlappingRendering);
registerDrawableAttr("foreground", this::setForeground);
registerAttr("foregroundGravity", Gravities::parse, this::setForegroundGravity);
registerAttr("foregroundTintMode", TINT_MODES::get, this::setForegroundTintMode);
registerAttr("importantForAccessibility", IMPORTANT_FOR_ACCESSIBILITY::get, mView::setImportantForAccessibility);
registerAttr("layoutDirection", LAYOUT_DIRECTIONS::get, mView::setLayoutDirection);
}
private void setForegroundTintMode(PorterDuff.Mode mode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mView.setForegroundTintMode(mode);
}
}
private void setForegroundGravity(int g) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mView.setForegroundGravity(g);
}
}
private void setForeground(Drawable foreground) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mView.setForeground(foreground);
}
}
private void forceHasOverlappingRendering(boolean b) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mView.forceHasOverlappingRendering(b);
}
}
private void setElevation(int e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mView.setElevation(e);
}
}
private void setScrollbars(String scrollbars) {
for (String str : scrollbars.split("\\|")) {
if (str.equals("horizontal")) {
mView.setHorizontalScrollBarEnabled(true);
} else if (str.equals("vertical")) {
mView.setVerticalScrollBarEnabled(true);
}
}
}
private float parseDimensionToPixel(String value) {
return Dimensions.parseToPixel(mView, value);
}
private int parseDimensionToIntPixel(String value) {
return Dimensions.parseToIntPixel(value, mView);
}
@ -200,6 +335,112 @@ public class ViewAttributes {
}
}
private void setMargin(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.bottomMargin = params.leftMargin = params.topMargin = params.rightMargin = margin;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginStart(margin);
params.setMarginEnd(margin);
}
}
}
private void setMarginLeft(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.leftMargin = margin;
}
}
private void setMarginRight(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.rightMargin = margin;
}
}
private void setMarginTop(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.topMargin = margin;
}
}
private void setMarginBottom(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.bottomMargin = margin;
}
}
private void setMarginStart(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.setMarginStart(margin);
}
}
private void setMarginEnd(int margin) {
if (mView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mView.getLayoutParams();
params.setMarginEnd(margin);
}
}
private void setPadding(int padding) {
mView.setPadding(padding, padding, padding, padding);
}
private void setPaddingLeft(int padding) {
mView.setPadding(padding, mView.getPaddingTop(), mView.getPaddingRight(), mView.getPaddingBottom());
}
private void setPaddingRight(int padding) {
mView.setPadding(mView.getPaddingLeft(), mView.getPaddingTop(), padding, mView.getPaddingBottom());
}
private void setPaddingTop(int padding) {
mView.setPadding(mView.getPaddingLeft(), padding, mView.getPaddingRight(), mView.getPaddingBottom());
}
private void setPaddingStart(int padding) {
mView.setPaddingRelative(padding, mView.getPaddingTop(), mView.getPaddingEnd(), mView.getPaddingBottom());
}
private void setPaddingEnd(int padding) {
mView.setPaddingRelative(mView.getPaddingStart(), mView.getPaddingTop(), padding, mView.getPaddingBottom());
}
private void setPaddingBottom(int padding) {
mView.setPadding(mView.getPaddingLeft(), mView.getPaddingTop(), mView.getPaddingRight(), padding);
}
private void setBackgroundTint(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mView.setBackgroundTintList(ColorStateList.valueOf(color));
}
}
private void setContextClickable(boolean clickable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mView.setContextClickable(clickable);
}
}
private void setChecked(boolean checked) {
if (mView instanceof CompoundButton) {
((CompoundButton) mView).setChecked(checked);
}
}
private void setLayoutGravity(int gravity) {
ViewParent parent = mView.getParent();
ViewGroup.LayoutParams layoutParams = mView.getLayoutParams();
@ -244,4 +485,12 @@ public class ViewAttributes {
mView.setLayoutParams(layoutParams);
}
private String parseString(String value) {
return Strings.parse(mView, value);
}
private static <
T1, T2> ValueApplier<T2> bind(Functions.VoidFunc2<T1, T2> func2, T1 t1) {
return value -> func2.call(t1, value);
}
}

View File

@ -38,7 +38,7 @@ import java.util.Map;
public class BaseViewInflater<V extends View> implements ViewInflater<V> {
protected static final ValueMapper<PorterDuff.Mode> TINT_MODES = new ValueMapper<PorterDuff.Mode>("tintMode")
public static final ValueMapper<PorterDuff.Mode> TINT_MODES = new ValueMapper<PorterDuff.Mode>("tintMode")
.map("add", PorterDuff.Mode.ADD)
.map("multiply", PorterDuff.Mode.MULTIPLY)
.map("screen", PorterDuff.Mode.SCREEN)
@ -46,27 +46,27 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
.map("src_in", PorterDuff.Mode.SRC_IN)
.map("src_over", PorterDuff.Mode.SRC_OVER);
private static final ValueMapper<Integer> DRAWABLE_CACHE_QUALITIES = new ValueMapper<Integer>("drawingCacheQuality")
public static final ValueMapper<Integer> DRAWABLE_CACHE_QUALITIES = new ValueMapper<Integer>("drawingCacheQuality")
.map("auto", View.DRAWING_CACHE_QUALITY_AUTO)
.map("high", View.DRAWING_CACHE_QUALITY_HIGH)
.map("low", View.DRAWING_CACHE_QUALITY_LOW);
private static final ValueMapper<Integer> IMPORTANT_FOR_ACCESSIBILITY = new ValueMapper<Integer>("importantForAccessibility")
public static final ValueMapper<Integer> IMPORTANT_FOR_ACCESSIBILITY = new ValueMapper<Integer>("importantForAccessibility")
.map("auto", 0) //View.IMPORTANT_FOR_ACCESSIBILITY_AUTO)
.map("no", 2) //View.IMPORTANT_FOR_ACCESSIBILITY_NO)
.map("noHideDescendants", 4) //View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
.map("yes", 1); //View.IMPORTANT_FOR_ACCESSIBILITY_YES);
private static final ValueMapper<Integer> LAYOUT_DIRECTIONS = new ValueMapper<Integer>("layoutDirection")
public static final ValueMapper<Integer> LAYOUT_DIRECTIONS = new ValueMapper<Integer>("layoutDirection")
.map("inherit", 2)
.map("locale", 3)
.map("ltr", 0)
.map("rtl", 1);
private static final ValueMapper<Integer> SCROLLBARS_STYLES = new ValueMapper<Integer>("scrollbarStyle")
public static final ValueMapper<Integer> SCROLLBARS_STYLES = new ValueMapper<Integer>("scrollbarStyle")
.map("insideInset", View.SCROLLBARS_INSIDE_INSET)
.map("insideOverlay", View.SCROLLBARS_INSIDE_OVERLAY)
.map("outsideInset", View.SCROLLBARS_OUTSIDE_INSET)
.map("outsideOverlay", View.SCROLLBARS_OUTSIDE_OVERLAY);
private static final ValueMapper<Integer> SCROLL_INDICATORS = new ValueMapper<Integer>("scrollIndicators")
public static final ValueMapper<Integer> SCROLL_INDICATORS = new ValueMapper<Integer>("scrollIndicators")
.map("bottom", 2) //View.SCROLL_INDICATOR_BOTTOM)
.map("end", 20) //View.SCROLL_INDICATOR_END)
.map("left", 4) //View.SCROLL_INDICATOR_LEFT)
@ -74,11 +74,11 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
.map("right", 8) //View.SCROLL_INDICATOR_RIGHT)
.map("start", 10) //View.SCROLL_INDICATOR_START)
.map("top", 1); //View.SCROLL_INDICATOR_TOP)
private static final ValueMapper<Integer> VISIBILITY = new ValueMapper<Integer>("visibility")
public static final ValueMapper<Integer> VISIBILITY = new ValueMapper<Integer>("visibility")
.map("visible", View.VISIBLE)
.map("invisible", View.INVISIBLE)
.map("gone", View.GONE);
private static final ValueMapper<Integer> TEXT_DIRECTIONS = new ValueMapper<Integer>("textDirection")
public static final ValueMapper<Integer> TEXT_DIRECTIONS = new ValueMapper<Integer>("textDirection")
.map("anyRtl", 2)
.map("firstStrong", 1)
.map("firstStrongLtr", 6)
@ -87,7 +87,7 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
.map("locale", 5)
.map("ltr", 3)
.map("rtl", 4);
private static final ValueMapper<Integer> TEXT_ALIGNMENTS = new ValueMapper<Integer>("textAlignment")
public static final ValueMapper<Integer> TEXT_ALIGNMENTS = new ValueMapper<Integer>("textAlignment")
.map("center", 4)
.map("gravity", 1)
.map("inherit", 0)
@ -451,7 +451,7 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
}
break;
case "requiresFadingEdge":
for (String str : value.split("|")) {
for (String str : value.split("\\|")) {
if (str.equals("horizontal")) {
view.setHorizontalFadingEdgeEnabled(true);
} else if (str.equals("vertical")) {
@ -472,10 +472,10 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
view.setSaveEnabled(Boolean.valueOf(value));
break;
case "scaleX":
view.setScaleX(Dimensions.parseToPixel(value, view));
view.setScaleX(Float.parseFloat(value));
break;
case "scaleY":
view.setScaleY(Dimensions.parseToPixel(value, view));
view.setScaleY(Float.parseFloat(value));
break;
case "scrollIndicators":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

View File

@ -42,6 +42,10 @@ public class Dimensions {
return parseToPixel(dimension, view.getContext());
}
public static float parseToPixel(View view, String dimension) {
return parseToPixel(dimension, view.getContext());
}
public static float parseToPixel(String dimension, Context context) {
if (dimension.startsWith("?")) {
int[] attr = {context.getResources().getIdentifier(dimension.substring(1), "attr",

View File

@ -79,10 +79,13 @@ public class NativeView extends NativeJavaObjectWithPrototype {
@Override
public void put(String name, Scriptable start, Object value) {
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
if (attribute != null) {
attribute.set(ScriptRuntime.toString(value));
return;
if (value != null && (value instanceof CharSequence ||
value.getClass().getName().equals("org.mozilla.javascript.NativeString"))) {
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
if (attribute != null) {
attribute.set(ScriptRuntime.toString(value));
return;
}
}
super.put(name, start, value);
}