feat: relative path support for ui image source

This commit is contained in:
hyb1996
2018-01-24 12:31:12 +08:00
parent c8450dfc3a
commit 316415343f
21 changed files with 280 additions and 136 deletions

View File

@@ -87,7 +87,7 @@ public class App extends MultiDexApplication {
}
private void setupDrawableImageLoader() {
Drawables.setImageLoader(new ImageLoader() {
Drawables.setDefaultImageLoader(new ImageLoader() {
@Override
public void loadInto(ImageView imageView, Uri uri) {
GlideApp.with(App.this)

View File

@@ -5,8 +5,6 @@ import android.view.View;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
import com.stardust.autojs.core.ui.widget.JsFrameLayout;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.inflater.attrsetter.JsImageViewAttrSetter;
import com.stardust.autojs.core.ui.xml.XmlConverter;
@@ -18,22 +16,12 @@ public class ConvertLayoutInflater implements JsLayoutInflater {
private DynamicLayoutInflater mDynamicLayoutInflater;
public ConvertLayoutInflater() {
}
private void ensureInflater(Context context) {
if (mDynamicLayoutInflater != null) {
return;
}
mDynamicLayoutInflater = new DynamicLayoutInflater(context);
mDynamicLayoutInflater.registerViewAttrSetter(JsImageView.class.getName(),
new JsImageViewAttrSetter<>());
public ConvertLayoutInflater(DynamicLayoutInflater dynamicLayoutInflater) {
mDynamicLayoutInflater = dynamicLayoutInflater;
}
@Override
public View inflate(Context context, String xml) {
ensureInflater(context);
try {
String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml);
JsFrameLayout root = new JsFrameLayout(context);

View File

@@ -32,7 +32,9 @@ import com.stardust.autojs.core.ui.inflater.attrsetter.TextViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.TimePickerAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.ToolbarAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.ViewGroupAttrSetter;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
import com.stardust.autojs.core.ui.inflater.util.Res;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@@ -77,22 +79,27 @@ public class DynamicLayoutInflater {
private Map<String, ViewAttrSetter<?>> mViewAttrSetters = new HashMap<>();
private Map<String, com.stardust.autojs.core.ui.inflater.ViewCreator<?>> mViewCreators = new HashMap<>();
private Context mContext;
private ValueParser mValueParser;
public DynamicLayoutInflater(Context context) {
public DynamicLayoutInflater(Context context, ValueParser valueParser) {
mContext = context;
registerViewAttrSetter(TextView.class.getName(), new TextViewAttrSetter<>());
registerViewAttrSetter(EditText.class.getName(), new TextViewAttrSetter<>());
registerViewAttrSetter(ImageView.class.getName(), new ImageViewAttrSetter<>());
registerViewAttrSetter(LinearLayout.class.getName(), new LinearLayoutAttrSetter<>());
registerViewAttrSetter(FrameLayout.class.getName(), new FrameLayoutAttrSetter<>());
registerViewAttrSetter(View.class.getName(), new BaseViewAttrSetter<>());
registerViewAttrSetter(Toolbar.class.getName(), new ToolbarAttrSetter<>());
registerViewAttrSetter(DatePicker.class.getName(), new DatePickerAttrSetter());
registerViewAttrSetter(RadioGroup.class.getName(), new RadioGroupAttrSetter<>());
registerViewAttrSetter(ProgressBar.class.getName(), new ProgressBarAttrSetter<>());
registerViewAttrSetter(Spinner.class.getName(), new SpinnerAttrSetter());
registerViewAttrSetter(TimePicker.class.getName(), new TimePickerAttrSetter());
mValueParser = valueParser;
registerViewAttrSetters();
}
protected void registerViewAttrSetters() {
registerViewAttrSetter(TextView.class.getName(), new TextViewAttrSetter<>(mValueParser));
registerViewAttrSetter(EditText.class.getName(), new TextViewAttrSetter<>(mValueParser));
registerViewAttrSetter(ImageView.class.getName(), new ImageViewAttrSetter<>(mValueParser));
registerViewAttrSetter(LinearLayout.class.getName(), new LinearLayoutAttrSetter<>(mValueParser));
registerViewAttrSetter(FrameLayout.class.getName(), new FrameLayoutAttrSetter<>(mValueParser));
registerViewAttrSetter(View.class.getName(), new BaseViewAttrSetter<>(mValueParser));
registerViewAttrSetter(Toolbar.class.getName(), new ToolbarAttrSetter<>(mValueParser));
registerViewAttrSetter(DatePicker.class.getName(), new DatePickerAttrSetter(mValueParser));
registerViewAttrSetter(RadioGroup.class.getName(), new RadioGroupAttrSetter<>(mValueParser));
registerViewAttrSetter(ProgressBar.class.getName(), new ProgressBarAttrSetter<>(mValueParser));
registerViewAttrSetter(Spinner.class.getName(), new SpinnerAttrSetter(mValueParser));
registerViewAttrSetter(TimePicker.class.getName(), new TimePickerAttrSetter(mValueParser));
}
public void registerViewAttrSetter(String fullName, ViewAttrSetter<?> setter) {

View File

@@ -0,0 +1,22 @@
package com.stardust.autojs.core.ui.inflater;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
/**
* Created by Stardust on 2018/1/24.
*/
public class ValueParser {
private final Drawables mDrawables;
public ValueParser(Drawables drawables) {
mDrawables = drawables;
}
public Drawables getDrawables() {
return mDrawables;
}
}

View File

@@ -12,6 +12,7 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.inflater.util.Colors;
@@ -90,6 +91,17 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
.map("viewEnd", 6)
.map("viewStart", 5);
private final ValueParser mValueParser;
public BaseViewAttrSetter(ValueParser valueParser) {
mValueParser = valueParser;
}
public Drawables getDrawables(){
return mValueParser.getDrawables();
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
Integer layoutRule = null;
@@ -252,7 +264,7 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), Dimensions.parseToIntPixel(value, view));
break;
case "background":
Drawables.setupWithViewBackground(view, value);
getDrawables().setupWithViewBackground(view, value);
break;
case "accessibilityLiveRegion":
case "accessibilityTraversalAfter":
@@ -333,7 +345,7 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
break;
case "foreground":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
view.setForeground(Drawables.parse(view, value));
view.setForeground(getDrawables().parse(view, value));
}
break;
case "foregroundGravity":

View File

@@ -9,6 +9,7 @@ import android.widget.DatePicker;
import com.stardust.autojs.R;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import java.text.ParseException;
@@ -24,6 +25,10 @@ public class DatePickerAttrSetter extends BaseViewAttrSetter<DatePicker> {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("mm/dd/yyyy", Locale.getDefault());
public DatePickerAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(DatePicker view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {

View File

@@ -4,6 +4,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Gravities;
import java.util.Map;
@@ -16,6 +17,10 @@ public class FrameLayoutAttrSetter<V extends FrameLayout> extends ViewGroupAttrS
private Integer mGravity;
public FrameLayoutAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
if (attr.equals("gravity")) {

View File

@@ -5,6 +5,7 @@ import android.view.InflateException;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
@@ -17,6 +18,10 @@ import java.util.Map;
public class ImageViewAttrSetter<V extends ImageView> extends BaseViewAttrSetter<V> {
public ImageViewAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
if (super.setAttr(view, attr, value, parent, attrs)) {
@@ -44,13 +49,13 @@ public class ImageViewAttrSetter<V extends ImageView> extends BaseViewAttrSetter
view.setMaxWidth(Dimensions.parseToIntPixel(value, view));
break;
case "path":
Drawables.setupWithImage(view, wrapAsPath(value));
getDrawables().setupWithImage(view, wrapAsPath(value));
break;
case "scaleType":
view.setScaleType(parseScaleType(value));
break;
case "src":
Drawables.setupWithImage(view, value);
getDrawables().setupWithImage(view, value);
break;
case "tint":
view.setColorFilter(Colors.parse(view, value));
@@ -61,7 +66,7 @@ public class ImageViewAttrSetter<V extends ImageView> extends BaseViewAttrSetter
}
break;
case "url":
Drawables.setupWithImage(view, wrapAsUrl(value));
getDrawables().setupWithImage(view, wrapAsUrl(value));
break;
default:
return false;

View File

@@ -1,9 +1,13 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
import android.content.Context;
import android.support.annotation.Nullable;
import android.view.ViewGroup;
import android.widget.ImageView.ScaleType;
import com.makeramen.roundedimageview.Corner;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
@@ -16,7 +20,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/30.
*/
public class JsImageViewAttrSetter<V extends JsImageView> extends ImageViewAttrSetter<V> {
public class JsImageViewAttrSetter extends ImageViewAttrSetter<JsImageView> {
protected static final ValueMapper<ScaleType> SCALE_TYPES = new ValueMapper<ScaleType>("scaleType")
@@ -29,8 +33,12 @@ public class JsImageViewAttrSetter<V extends JsImageView> extends ImageViewAttrS
.map("fitXY", ScaleType.FIT_XY)
.map("matrix", ScaleType.MATRIX);
public JsImageViewAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
public boolean setAttr(JsImageView view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
case "radius":
view.setCornerRadius(Dimensions.parseToPixel(value, view));
@@ -64,4 +72,14 @@ public class JsImageViewAttrSetter<V extends JsImageView> extends ImageViewAttrS
}
return true;
}
@Nullable
@Override
public ViewCreator<JsImageView> getCreator() {
return (context, attrs) -> {
JsImageView imageView = new JsImageView(context);
imageView.setDrawables(getDrawables());
return imageView;
};
}
}

View File

@@ -3,6 +3,7 @@ package com.stardust.autojs.core.ui.inflater.attrsetter;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.stardust.autojs.core.ui.inflater.ValueParser;
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.ValueMapper;
@@ -19,6 +20,10 @@ public class LinearLayoutAttrSetter<V extends LinearLayout> extends ViewGroupAtt
.map("vertical", LinearLayout.VERTICAL)
.map("horizontal", LinearLayout.HORIZONTAL);
public LinearLayoutAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
@@ -29,7 +34,7 @@ public class LinearLayoutAttrSetter<V extends LinearLayout> extends ViewGroupAtt
view.setBaselineAlignedChildIndex(Integer.valueOf(value));
break;
case "divider":
view.setDividerDrawable(Drawables.parse(view, value));
view.setDividerDrawable(getDrawables().parse(view, value));
break;
case "gravity":
view.setGravity(Gravities.parse(value));

View File

@@ -5,6 +5,7 @@ import android.os.Build;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
@@ -17,6 +18,10 @@ import java.util.Map;
public class ProgressBarAttrSetter<V extends ProgressBar> extends BaseViewAttrSetter<V> {
public ProgressBarAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
@@ -30,7 +35,7 @@ public class ProgressBarAttrSetter<V extends ProgressBar> extends BaseViewAttrSe
Exceptions.unsupports(view, attr, value);
break;
case "indeterminateDrawable":
view.setIndeterminateDrawable(Drawables.parse(view, value));
view.setIndeterminateDrawable(getDrawables().parse(view, value));
break;
case "indeterminateDuration":
Exceptions.unsupports(view, attr, value);
@@ -86,7 +91,7 @@ public class ProgressBarAttrSetter<V extends ProgressBar> extends BaseViewAttrSe
}
break;
case "progressDrawable":
view.setProgressDrawable(Drawables.parse(view, value));
view.setProgressDrawable(getDrawables().parse(view, value));
break;
case "progressTint":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

View File

@@ -3,6 +3,7 @@ package com.stardust.autojs.core.ui.inflater.attrsetter;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Ids;
import java.util.Map;
@@ -15,6 +16,10 @@ public class RadioGroupAttrSetter<V extends RadioGroup> extends LinearLayoutAttr
private Integer mCheckedButton;
public RadioGroupAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
if (attr.equals("checkedButton")) {

View File

@@ -8,6 +8,7 @@ import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
@@ -27,6 +28,10 @@ public class SpinnerAttrSetter extends BaseViewAttrSetter<Spinner> {
.map("dialog", Spinner.MODE_DIALOG)
.map("dropdown", Spinner.MODE_DROPDOWN);
public SpinnerAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(Spinner view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
@@ -50,7 +55,7 @@ public class SpinnerAttrSetter extends BaseViewAttrSetter<Spinner> {
break;
case "popupBackground":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setPopupBackgroundDrawable(Drawables.parse(view, value));
view.setPopupBackgroundDrawable(getDrawables().parse(view, value));
}
break;
case "prompt":

View File

@@ -14,6 +14,7 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
@@ -122,6 +123,10 @@ public class TextViewAttrSetter<V extends TextView> extends BaseViewAttrSetter<V
private Integer mTextStyle;
private String mTypeface;
public TextViewAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
if (super.setAttr(view, attrName, value, parent, attrs)) {
@@ -148,16 +153,16 @@ public class TextViewAttrSetter<V extends TextView> extends BaseViewAttrSetter<V
}
break;
case "drawableBottom":
mDrawableBottom = Drawables.parse(view, value);
mDrawableBottom = getDrawables().parse(view, value);
break;
case "drawableTop":
mDrawableTop = Drawables.parse(view, value);
mDrawableTop = getDrawables().parse(view, value);
break;
case "drawableLeft":
mDrawableLeft = Drawables.parse(view, value);
mDrawableLeft = getDrawables().parse(view, value);
break;
case "drawableRight":
mDrawableRight = Drawables.parse(view, value);
mDrawableRight = getDrawables().parse(view, value);
break;
case "drawablePadding":
view.setCompoundDrawablePadding(Dimensions.parseToIntPixel(value, view));

View File

@@ -5,6 +5,7 @@ import android.view.View;
import android.widget.TimePicker;
import com.stardust.autojs.R;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
/**
@@ -13,6 +14,10 @@ import com.stardust.autojs.core.ui.inflater.ViewCreator;
public class TimePickerAttrSetter extends BaseViewAttrSetter<TimePicker> {
public TimePickerAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Nullable
@Override
public ViewCreator<TimePicker> getCreator() {

View File

@@ -3,6 +3,7 @@ package com.stardust.autojs.core.ui.inflater.attrsetter;
import android.support.v7.widget.Toolbar;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.Strings;
import java.util.Map;
@@ -14,6 +15,10 @@ import java.util.Map;
public class ToolbarAttrSetter<V extends Toolbar> extends BaseViewAttrSetter<V> {
public ToolbarAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
return super.setAttr(view, attr, value, parent, attrs);

View File

@@ -4,6 +4,7 @@ import android.animation.LayoutTransition;
import android.os.Build;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
import java.util.Map;
@@ -29,6 +30,10 @@ public class ViewGroupAttrSetter<V extends ViewGroup> extends BaseViewAttrSetter
.map("beforeDescendants", ViewGroup.FOCUS_BEFORE_DESCENDANTS)
.map("blocksDescendants", ViewGroup.FOCUS_BLOCK_DESCENDANTS);
public ViewGroupAttrSetter(ValueParser valueParser) {
super(valueParser);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {

View File

@@ -26,8 +26,106 @@ import java.util.regex.Pattern;
public class Drawables {
private static final Pattern DATA_PATTERN = Pattern.compile("data:(\\w+/\\w+);base64,(.+)");
private static ImageLoader sImageLoader = new ImageLoader() {
private final Pattern DATA_PATTERN = Pattern.compile("data:(\\w+/\\w+);base64,(.+)");
private static ImageLoader sDefaultImageLoader = new DefaultImageLoader();
private ImageLoader mImageLoader = sDefaultImageLoader;
public static void setDefaultImageLoader(ImageLoader defaultImageLoader) {
sDefaultImageLoader = defaultImageLoader;
}
public Drawable parse(Context context, String value) {
Resources resources = context.getResources();
if (value.startsWith("@color/") || value.startsWith("@android:color/") || value.startsWith("#")) {
return new ColorDrawable(Colors.parse(context, value));
}
if (value.startsWith("?")) {
return loadAttrResources(context, value);
}
if (value.startsWith("file://")) {
return decodeImage(value.substring(7));
}
return loadDrawableResources(context, value);
}
public Drawable loadDrawableResources(Context context, String value) {
return context.getResources().getDrawable(context.getResources().getIdentifier(value, "drawable",
context.getPackageName()));
}
public Drawable loadAttrResources(Context context, String value) {
int[] attr = {context.getResources().getIdentifier(value.substring(1), "attr",
context.getPackageName())};
TypedArray ta = context.obtainStyledAttributes(attr);
Drawable drawable = ta.getDrawable(0 /* index */);
ta.recycle();
return drawable;
}
public Drawable decodeImage(String path) {
return new BitmapDrawable(BitmapFactory.decodeFile(path));
}
public Drawable parse(View view, String name) {
return parse(view.getContext(), name);
}
public void loadInto(ImageView view, Uri uri) {
mImageLoader.loadInto(view, uri);
}
public void loadIntoBackground(View view, Uri uri) {
mImageLoader.loadIntoBackground(view, uri);
}
public <V extends ImageView> void setupWithImage(V view, String value) {
if (value.startsWith("http://") || value.startsWith("https://")) {
loadInto(view, Uri.parse(value));
} else if (value.startsWith("data:")) {
loadDataInto(view, value);
} else {
view.setImageDrawable(parse(view, value));
}
}
private void loadDataInto(ImageView view, String data) {
Bitmap bitmap = loadData(data);
view.setImageBitmap(bitmap);
}
public Bitmap loadData(String data) {
Matcher matcher = DATA_PATTERN.matcher(data);
if (!matcher.matches() || matcher.groupCount() != 2) {
return null;
}
String mimeType = matcher.group(1);
String base64 = matcher.group(2);
byte[] bytes = Base64.decode(base64, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
public void setupWithViewBackground(View view, String value) {
if (value.startsWith("http://") || value.startsWith("https://")) {
loadIntoBackground(view, Uri.parse(value));
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setBackground(parse(view, value));
} else {
view.setBackgroundDrawable(parse(view, value));
}
}
}
public void setImageLoader(ImageLoader imageLoader) {
mImageLoader = imageLoader;
}
public ImageLoader getImageLoader() {
return mImageLoader;
}
private static class DefaultImageLoader implements ImageLoader {
@Override
public void loadInto(final ImageView view, Uri uri) {
load(view, uri, view::setImageDrawable);
@@ -66,87 +164,6 @@ public class Drawables {
}
}).start();
}
};
public static Drawable parse(Context context, String value) {
Resources resources = context.getResources();
if (value.startsWith("@color/") || value.startsWith("@android:color/") || value.startsWith("#")) {
return new ColorDrawable(Colors.parse(context, value));
}
if (value.startsWith("?")) {
int[] attr = {resources.getIdentifier(value.substring(1), "attr",
context.getPackageName())};
TypedArray ta = context.obtainStyledAttributes(attr);
Drawable drawable = ta.getDrawable(0 /* index */);
ta.recycle();
return drawable;
}
if (value.startsWith("file://")) {
return decodeImage(value.substring(7));
}
return resources.getDrawable(resources.getIdentifier(value, "drawable",
context.getPackageName()));
}
private static Drawable decodeImage(String path) {
return new BitmapDrawable(BitmapFactory.decodeFile(path));
}
public static Drawable parse(View view, String name) {
return parse(view.getContext(), name);
}
public static void loadInto(ImageView view, Uri uri) {
sImageLoader.loadInto(view, uri);
}
public static void loadIntoBackground(View view, Uri uri) {
sImageLoader.loadIntoBackground(view, uri);
}
public static <V extends ImageView> void setupWithImage(V view, String value) {
if (value.startsWith("http://") || value.startsWith("https://")) {
loadInto(view, Uri.parse(value));
} else if(value.startsWith("data:")) {
loadDataInto(view, value);
}else {
view.setImageDrawable(Drawables.parse(view, value));
}
}
private static void loadDataInto(ImageView view, String data) {
Bitmap bitmap = loadData(data);
view.setImageBitmap(bitmap);
}
public static Bitmap loadData(String data){
Matcher matcher = DATA_PATTERN.matcher(data);
if(!matcher.matches() || matcher.groupCount() != 2){
return null;
}
String mimeType = matcher.group(1);
String base64 = matcher.group(2);
byte[] bytes = Base64.decode(base64, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
public static void setupWithViewBackground(View view, String value) {
if (value.startsWith("http://") || value.startsWith("https://")) {
loadIntoBackground(view, Uri.parse(value));
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setBackground(com.stardust.autojs.core.ui.inflater.util.Drawables.parse(view, value));
} else {
view.setBackgroundDrawable(com.stardust.autojs.core.ui.inflater.util.Drawables.parse(view, value));
}
}
}
public static void setImageLoader(ImageLoader imageLoader) {
sImageLoader = imageLoader;
}
public static ImageLoader getImageLoader() {
return sImageLoader;
}
}

View File

@@ -14,6 +14,7 @@ import com.stardust.autojs.core.ui.inflater.util.Drawables;
public class JsImageView extends RoundedImageView {
private boolean mCircle;
private Drawables mDrawables;
public JsImageView(Context context) {
super(context);
@@ -39,7 +40,7 @@ public class JsImageView extends RoundedImageView {
}
public void setSource(String uri) {
Drawables.setupWithImage(this, uri);
getDrawables().setupWithImage(this, uri);
}
@Override
@@ -50,4 +51,12 @@ public class JsImageView extends RoundedImageView {
setCornerRadius(getMeasuredWidth() / 2);
}
}
public void setDrawables(Drawables drawables) {
mDrawables = drawables;
}
public Drawables getDrawables() {
return mDrawables;
}
}

View File

@@ -189,7 +189,7 @@ public class ScriptRuntime {
console = builder.mConsole;
accessibilityBridge = builder.mAccessibilityBridge;
mShellSupplier = builder.mShellSupplier;
ui = new UI(uiHandler.getContext());
ui = new UI(uiHandler.getContext(), this);
this.automator = new SimpleActionAutomator(accessibilityBridge, this);
automator.setScreenMetrics(mScreenMetrics);
this.info = accessibilityBridge.getInfoProvider();

View File

@@ -1,10 +1,16 @@
package com.stardust.autojs.runtime.api;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.stardust.autojs.core.ui.ConvertLayoutInflater;
import com.stardust.autojs.core.ui.JsLayoutInflater;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.attrsetter.JsImageViewAttrSetter;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.rhino.ProxyObject;
import com.stardust.autojs.runtime.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.UniqueTag;
@@ -22,15 +28,18 @@ public class UI extends ProxyObject {
private Context mContext;
private Map<String, Object> mProperties = new ConcurrentHashMap<>();
private JsLayoutInflater mJsLayoutInflater;
private ScriptRuntime mRuntime;
private ValueParser mValueParser;
public UI(Context context, JsLayoutInflater layoutInflater) {
public UI(Context context, ScriptRuntime runtime) {
mContext = context;
mProperties.put("layoutInflater", layoutInflater);
mJsLayoutInflater = layoutInflater;
}
public UI(Context context) {
this(context, new ConvertLayoutInflater());
mRuntime = runtime;
mValueParser = new ValueParser(new Drawables());
DynamicLayoutInflater inflater = new DynamicLayoutInflater(context, mValueParser);
inflater.registerViewAttrSetter(JsImageView.class.getName(),
new JsImageViewAttrSetter(mValueParser));
mJsLayoutInflater = new ConvertLayoutInflater(inflater);
mProperties.put("layoutInflater", mJsLayoutInflater);
}
@@ -57,6 +66,13 @@ public class UI extends ProxyObject {
}
private class Drawables extends com.stardust.autojs.core.ui.inflater.util.Drawables {
@Override
public Drawable decodeImage(String path) {
return super.decodeImage(mRuntime.files.path(path));
}
}
}