diff --git a/autojs/src/main/java/com/stardust/autojs/core/eventloop/EventEmitter.java b/autojs/src/main/java/com/stardust/autojs/core/eventloop/EventEmitter.java index e10aeb5d..e1c5d7f7 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/eventloop/EventEmitter.java +++ b/autojs/src/main/java/com/stardust/autojs/core/eventloop/EventEmitter.java @@ -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) { diff --git a/autojs/src/main/java/com/stardust/autojs/core/internal/Functions.java b/autojs/src/main/java/com/stardust/autojs/core/internal/Functions.java index f26b0f6c..05c52382 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/internal/Functions.java +++ b/autojs/src/main/java/com/stardust/autojs/core/internal/Functions.java @@ -46,5 +46,21 @@ public class Functions { R call(T1 t1, T2 t2, T3 t3, T4 t4); } + public interface VoidFunc1 extends Func { + void call(T1 t1); + } + + public interface VoidFunc2 extends Func { + void call(T1 t1, T2 t2); + } + + public interface VoidFunc3 extends Func { + void call(T1 t1, T2 t2, T3 t3); + } + + public interface VoidFunc4 extends Func { + void call(T1 t1, T2 t2, T3 t3, T4 t4); + } + } diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/attribute/ViewAttributes.java b/autojs/src/main/java/com/stardust/autojs/core/ui/attribute/ViewAttributes.java index 7722f44d..741718ea 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/ui/attribute/ViewAttributes.java +++ b/autojs/src/main/java/com/stardust/autojs/core/ui/attribute/ViewAttributes.java @@ -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 bind(Functions.VoidFunc2 func2, T1 t1) { + return value -> func2.call(t1, value); + } } diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/BaseViewInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/BaseViewInflater.java index 8a4a8b88..69d04b1f 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/BaseViewInflater.java +++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/BaseViewInflater.java @@ -38,7 +38,7 @@ import java.util.Map; public class BaseViewInflater implements ViewInflater { - protected static final ValueMapper TINT_MODES = new ValueMapper("tintMode") + public static final ValueMapper TINT_MODES = new ValueMapper("tintMode") .map("add", PorterDuff.Mode.ADD) .map("multiply", PorterDuff.Mode.MULTIPLY) .map("screen", PorterDuff.Mode.SCREEN) @@ -46,27 +46,27 @@ public class BaseViewInflater implements ViewInflater { .map("src_in", PorterDuff.Mode.SRC_IN) .map("src_over", PorterDuff.Mode.SRC_OVER); - private static final ValueMapper DRAWABLE_CACHE_QUALITIES = new ValueMapper("drawingCacheQuality") + public static final ValueMapper DRAWABLE_CACHE_QUALITIES = new ValueMapper("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 IMPORTANT_FOR_ACCESSIBILITY = new ValueMapper("importantForAccessibility") + public static final ValueMapper IMPORTANT_FOR_ACCESSIBILITY = new ValueMapper("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 LAYOUT_DIRECTIONS = new ValueMapper("layoutDirection") + public static final ValueMapper LAYOUT_DIRECTIONS = new ValueMapper("layoutDirection") .map("inherit", 2) .map("locale", 3) .map("ltr", 0) .map("rtl", 1); - private static final ValueMapper SCROLLBARS_STYLES = new ValueMapper("scrollbarStyle") + public static final ValueMapper SCROLLBARS_STYLES = new ValueMapper("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 SCROLL_INDICATORS = new ValueMapper("scrollIndicators") + public static final ValueMapper SCROLL_INDICATORS = new ValueMapper("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 implements ViewInflater { .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 VISIBILITY = new ValueMapper("visibility") + public static final ValueMapper VISIBILITY = new ValueMapper("visibility") .map("visible", View.VISIBLE) .map("invisible", View.INVISIBLE) .map("gone", View.GONE); - private static final ValueMapper TEXT_DIRECTIONS = new ValueMapper("textDirection") + public static final ValueMapper TEXT_DIRECTIONS = new ValueMapper("textDirection") .map("anyRtl", 2) .map("firstStrong", 1) .map("firstStrongLtr", 6) @@ -87,7 +87,7 @@ public class BaseViewInflater implements ViewInflater { .map("locale", 5) .map("ltr", 3) .map("rtl", 4); - private static final ValueMapper TEXT_ALIGNMENTS = new ValueMapper("textAlignment") + public static final ValueMapper TEXT_ALIGNMENTS = new ValueMapper("textAlignment") .map("center", 4) .map("gravity", 1) .map("inherit", 0) @@ -451,7 +451,7 @@ public class BaseViewInflater implements ViewInflater { } 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 implements ViewInflater { 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) { diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/util/Dimensions.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/util/Dimensions.java index d3cdcc29..4b29efea 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/util/Dimensions.java +++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/util/Dimensions.java @@ -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", diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/nativeview/NativeView.java b/autojs/src/main/java/com/stardust/autojs/core/ui/nativeview/NativeView.java index eaeb224d..7480808c 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/ui/nativeview/NativeView.java +++ b/autojs/src/main/java/com/stardust/autojs/core/ui/nativeview/NativeView.java @@ -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); }