refactor(ui): refactor dynamic layout inflater

feat(ui):  xml one way data binding
feat(ui): label `list`
This commit is contained in:
hyb1996
2018-03-29 16:50:21 +08:00
parent 9a61bbe64d
commit bac87f2591
36 changed files with 885 additions and 354 deletions

View File

@@ -1,15 +0,0 @@
package com.stardust.autojs.core.templatematching;
import android.media.Image;
/**
* Created by Stardust on 2017/10/5.
*/
public class Test {
public void test(Image image) {
}
}

View File

@@ -1,35 +0,0 @@
package com.stardust.autojs.core.ui;
import android.content.Context;
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.xml.XmlConverter;
/**
* Created by Stardust on 2017/5/14.
*/
public class ConvertLayoutInflater implements JsLayoutInflater {
private DynamicLayoutInflater mDynamicLayoutInflater;
public ConvertLayoutInflater(DynamicLayoutInflater dynamicLayoutInflater) {
mDynamicLayoutInflater = dynamicLayoutInflater;
}
@Override
public View inflate(Context context, String xml) {
try {
String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml);
JsFrameLayout root = new JsFrameLayout(context);
mDynamicLayoutInflater.setContext(context);
mDynamicLayoutInflater.inflate(androidLayoutXml, root);
return root;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,14 +0,0 @@
package com.stardust.autojs.core.ui;
import android.content.Context;
import android.view.View;
/**
* Created by Stardust on 2017/5/14.
*/
public interface JsLayoutInflater {
View inflate(Context context, String xml);
}

View File

@@ -2,6 +2,7 @@ package com.stardust.autojs.core.ui.inflater;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
@@ -20,20 +21,20 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import com.stardust.autojs.core.ui.inflater.attrsetter.BaseViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.DatePickerAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.FrameLayoutAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.ImageViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.LinearLayoutAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.ProgressBarAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.RadioGroupAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.SpinnerAttrSetter;
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.inflaters.BaseViewInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.DatePickerInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.FrameLayoutInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ImageViewInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.LinearLayoutInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ProgressBarInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.RadioGroupInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.SpinnerInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.TextViewInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.TimePickerInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ToolbarInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ViewGroupInflater;
import com.stardust.autojs.core.ui.inflater.util.Res;
import com.stardust.autojs.core.ui.xml.XmlConverter;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
@@ -41,8 +42,6 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
@@ -53,16 +52,30 @@ import javax.xml.parsers.DocumentBuilderFactory;
public class DynamicLayoutInflater {
private static final String LOG_TAG = "DynamicLayoutInflater";
private Map<String, ViewAttrSetter<?>> mViewAttrSetters = new HashMap<>();
private Map<String, com.stardust.autojs.core.ui.inflater.ViewCreator<?>> mViewCreators = new HashMap<>();
private Map<String, ViewInflater<?>> mViewAttrSetters = new HashMap<>();
private Map<String, ViewCreator<?>> mViewCreators = new HashMap<>();
private Context mContext;
private ValueParser mValueParser;
private ResourceParser mResourceParser;
@NonNull
private LayoutInflaterDelegate mLayoutInflaterDelegate = LayoutInflaterDelegate.NO_OP;
public DynamicLayoutInflater(ValueParser valueParser) {
mValueParser = valueParser;
public DynamicLayoutInflater(ResourceParser resourceParser) {
mResourceParser = resourceParser;
registerViewAttrSetters();
}
@SuppressWarnings("IncompleteCopyConstructor")
public DynamicLayoutInflater(DynamicLayoutInflater inflater) {
this.mResourceParser = inflater.mResourceParser;
this.mContext = inflater.mContext;
this.mViewAttrSetters = new HashMap<>(inflater.mViewAttrSetters);
this.mViewCreators = new HashMap<>(inflater.mViewCreators);
}
public ResourceParser getResourceParser() {
return mResourceParser;
}
public Context getContext() {
return mContext;
}
@@ -71,82 +84,121 @@ public class DynamicLayoutInflater {
mContext = context;
}
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));
@NonNull
public LayoutInflaterDelegate getLayoutInflaterDelegate() {
return mLayoutInflaterDelegate;
}
public void registerViewAttrSetter(String fullName, ViewAttrSetter<?> setter) {
mViewAttrSetters.put(fullName, setter);
com.stardust.autojs.core.ui.inflater.ViewCreator<?> creator = setter.getCreator();
public void setLayoutInflaterDelegate(@Nullable LayoutInflaterDelegate layoutInflaterDelegate) {
if (layoutInflaterDelegate == null)
layoutInflaterDelegate = LayoutInflaterDelegate.NO_OP;
mLayoutInflaterDelegate = layoutInflaterDelegate;
}
protected void registerViewAttrSetters() {
registerViewAttrSetter(TextView.class.getName(), new TextViewInflater<>(mResourceParser));
registerViewAttrSetter(EditText.class.getName(), new TextViewInflater<>(mResourceParser));
registerViewAttrSetter(ImageView.class.getName(), new ImageViewInflater<>(mResourceParser));
registerViewAttrSetter(LinearLayout.class.getName(), new LinearLayoutInflater<>(mResourceParser));
registerViewAttrSetter(FrameLayout.class.getName(), new FrameLayoutInflater<>(mResourceParser));
registerViewAttrSetter(View.class.getName(), new BaseViewInflater<>(mResourceParser));
registerViewAttrSetter(Toolbar.class.getName(), new ToolbarInflater<>(mResourceParser));
registerViewAttrSetter(DatePicker.class.getName(), new DatePickerInflater(mResourceParser));
registerViewAttrSetter(RadioGroup.class.getName(), new RadioGroupInflater<>(mResourceParser));
registerViewAttrSetter(ProgressBar.class.getName(), new ProgressBarInflater<>(mResourceParser));
registerViewAttrSetter(Spinner.class.getName(), new SpinnerInflater(mResourceParser));
registerViewAttrSetter(TimePicker.class.getName(), new TimePickerInflater(mResourceParser));
}
public void registerViewAttrSetter(String fullName, ViewInflater<?> inflater) {
mViewAttrSetters.put(fullName, inflater);
ViewCreator<?> creator = inflater.getCreator();
if (creator != null) {
mViewCreators.put(fullName, creator);
}
}
public View inflate(String xml) {
InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
return inflate(inputStream);
return inflate(xml, null);
}
public View inflate(String xml, ViewGroup parent) {
InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
return inflate(inputStream, parent);
public View inflate(String xml, @Nullable ViewGroup parent) {
View view = mLayoutInflaterDelegate.beforeInflation(xml, parent);
if (view != null)
return view;
xml = convertXml(xml);
return mLayoutInflaterDelegate.afterInflation(doInflation(xml, parent), xml, parent);
}
public View inflate(InputStream inputStream) {
return inflate(inputStream, null);
}
public View inflate(InputStream inputStream, ViewGroup parent) {
protected View doInflation(String xml, @Nullable ViewGroup parent) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(inputStream);
return inflate(document.getDocumentElement(), parent);
Document document = db.parse(new ByteArrayInputStream(xml.getBytes()));
return inflate(document.getDocumentElement(), parent, true);
} catch (Exception e) {
throw new InflateException(e);
}
}
protected String convertXml(String xml) {
String str = mLayoutInflaterDelegate.beforeConvertXml(xml);
if (str != null)
return str;
try {
return mLayoutInflaterDelegate.afterConvertXml(XmlConverter.convertToAndroidLayout(xml));
} catch (Exception e) {
throw new InflateException(e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
private View inflate(Node node, ViewGroup parent) {
public View inflate(Node node, @Nullable ViewGroup parent, boolean attachToParent) {
View view = mLayoutInflaterDelegate.beforeInflateView(node, parent, attachToParent);
if (view != null)
return view;
HashMap<String, String> attrs = getAttributesMap(node);
View view = createViewForName(node.getNodeName(), attrs);
if (parent != null) {
view = doCreateView(node, node.getNodeName(), attrs);
if (parent != null && attachToParent) {
parent.addView(view); // have to add to parent to enable certain layout attrs
}
ViewAttrSetter<View> setter = (ViewAttrSetter<View>) getViewAttrSetter(view);
applyAttributes(view, setter, attrs, parent);
if (view instanceof ViewGroup && node.hasChildNodes()) {
inflateChildren(node, (ViewGroup) view);
if (setter instanceof ViewGroupAttrSetter) {
((ViewGroupAttrSetter) setter).applyPendingAttributesAboutChildren((ViewGroup) view);
}
ViewInflater<View> inflater = applyAttributes(view, attrs, parent);
if (!(view instanceof ViewGroup) || !node.hasChildNodes()) {
return view;
}
return view;
inflateChildren(inflater, node, (ViewGroup) view);
if (inflater instanceof ViewGroupInflater) {
applyPendingAttributesOfChildren((ViewGroupInflater) inflater, (ViewGroup) view);
}
return mLayoutInflaterDelegate.afterInflateView(view, node, parent, attachToParent);
}
@SuppressWarnings("unchecked")
protected void applyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
if (mLayoutInflaterDelegate.beforeApplyPendingAttributesOfChildren(inflater, view)) {
return;
}
inflater.applyPendingAttributesOfChildren(view);
mLayoutInflaterDelegate.afterApplyPendingAttributesOfChildren(inflater, view);
}
@SuppressWarnings("unchecked")
public ViewInflater<View> applyAttributes(View view, HashMap<String, String> attrs, @Nullable ViewGroup parent) {
ViewInflater<View> inflater = (ViewInflater<View>) getViewInflater(view);
if (mLayoutInflaterDelegate.beforeApplyAttributes(view, inflater, attrs, parent)) {
return inflater;
}
applyAttributes(view, inflater, attrs, parent);
mLayoutInflaterDelegate.afterApplyAttributes(view, inflater, attrs, parent);
return inflater;
}
@Nullable
private ViewAttrSetter<?> getViewAttrSetter(View view) {
ViewAttrSetter<?> setter = mViewAttrSetters.get(view.getClass().getName());
public ViewInflater<?> getViewInflater(View view) {
ViewInflater<?> setter = mViewAttrSetters.get(view.getClass().getName());
Class c = view.getClass();
while (setter == null && c != View.class) {
c = c.getSuperclass();
@@ -155,16 +207,34 @@ public class DynamicLayoutInflater {
return setter;
}
private void inflateChildren(Node node, ViewGroup parent) {
protected void inflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
if (mLayoutInflaterDelegate.beforeInflateChildren(inflater, node, parent)) {
return;
}
if (inflater.inflateChildren(this, node, parent)) {
return;
}
inflateChildren(node, parent);
mLayoutInflaterDelegate.afterInflateChildren(inflater, node, parent);
}
public void inflateChildren(Node node, ViewGroup parent) {
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node currentNode = nodeList.item(i);
if (currentNode.getNodeType() != Node.ELEMENT_NODE) continue;
inflate(currentNode, parent); // this recursively can call inflateChildren
inflate(currentNode, parent, true);
}
}
private View createViewForName(String name, HashMap<String, String> attrs) {
protected View doCreateView(Node node, String viewName, HashMap<String, String> attrs) {
View view = mLayoutInflaterDelegate.beforeCreateView(node, viewName, attrs);
if (view != null)
return view;
return mLayoutInflaterDelegate.afterCreateView(createViewForName(viewName, attrs), node, viewName, attrs);
}
public View createViewForName(String name, HashMap<String, String> attrs) {
try {
if (name.equals("View")) {
return new View(mContext);
@@ -191,7 +261,7 @@ public class DynamicLayoutInflater {
}
private HashMap<String, String> getAttributesMap(Node currentNode) {
public HashMap<String, String> getAttributesMap(Node currentNode) {
NamedNodeMap attributeMap = currentNode.getAttributes();
int attributeCount = attributeMap.getLength();
HashMap<String, String> attributes = new HashMap<>(attributeCount);
@@ -204,14 +274,14 @@ public class DynamicLayoutInflater {
}
@SuppressWarnings("unchecked")
private void applyAttributes(View view, ViewAttrSetter<View> setter, Map<String, String> attrs, ViewGroup parent) {
protected void applyAttributes(View view, ViewInflater<View> setter, Map<String, String> attrs, @Nullable ViewGroup parent) {
if (setter != null) {
for (Map.Entry<String, String> entry : attrs.entrySet()) {
String[] attr = entry.getKey().split(":");
if (attr.length == 1) {
setter.setAttr(view, attr[0], entry.getValue(), parent, attrs);
applyAttribute(setter, view, null, attr[0], entry.getValue(), parent, attrs);
} else if (attr.length == 2) {
setter.setAttr(view, attr[0], attr[1], entry.getValue(), parent, attrs);
applyAttribute(setter, view, attr[0], attr[1], entry.getValue(), parent, attrs);
} else {
throw new InflateException("illegal attr name: " + entry.getKey());
}
@@ -223,5 +293,14 @@ public class DynamicLayoutInflater {
}
protected void applyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
if (mLayoutInflaterDelegate.beforeApplyAttribute(inflater, view, ns, attrName, value, parent, attrs)) {
return;
}
inflater.setAttr(view, ns, attrName, value, parent, attrs);
mLayoutInflaterDelegate.afterApplyAttribute(inflater, view, ns, attrName, value, parent, attrs);
}
}

View File

@@ -0,0 +1,136 @@
package com.stardust.autojs.core.ui.inflater;
import android.view.View;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.inflaters.ViewGroupInflater;
import org.w3c.dom.Node;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Stardust on 2018/3/29.
*/
public interface LayoutInflaterDelegate {
LayoutInflaterDelegate NO_OP = new NoOp();
View beforeInflation(String xml, ViewGroup parent);
View afterInflation(View doInflation, String xml, ViewGroup parent);
String beforeConvertXml(String xml);
String afterConvertXml(String xml);
View beforeInflateView(Node node, ViewGroup parent, boolean attachToParent);
View afterInflateView(View view, Node node, ViewGroup parent, boolean attachToParent);
View beforeCreateView(Node node, String viewName, HashMap<String, String> attrs);
View afterCreateView(View view, Node node, String viewName, HashMap<String, String> attrs);
boolean beforeApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
void afterApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
boolean beforeInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent);
void afterInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent);
void afterApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view);
boolean beforeApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view);
boolean beforeApplyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs);
void afterApplyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs);
class NoOp implements LayoutInflaterDelegate {
@Override
public String beforeConvertXml(String xml) {
return null;
}
@Override
public String afterConvertXml(String xml) {
return xml;
}
@Override
public View afterInflation(View result, String xml, ViewGroup parent) {
return result;
}
@Override
public View beforeInflation(String xml, ViewGroup parent) {
return null;
}
@Override
public View beforeInflateView(Node node, ViewGroup parent, boolean attachToParent) {
return null;
}
@Override
public View afterInflateView(View view, Node node, ViewGroup parent, boolean attachToParent) {
return view;
}
@Override
public View beforeCreateView(Node node, String viewName, HashMap<String, String> attrs) {
return null;
}
@Override
public View afterCreateView(View view, Node node, String viewName, HashMap<String, String> attrs) {
return view;
}
@Override
public boolean beforeApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent) {
return false;
}
@Override
public void afterApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent) {
}
@Override
public boolean beforeInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
return false;
}
@Override
public void afterInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
}
@Override
public void afterApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
}
@Override
public boolean beforeApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
return false;
}
@Override
public boolean beforeApplyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
return false;
}
@Override
public void afterApplyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
}
}
}

View File

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

View File

@@ -5,6 +5,8 @@ import android.view.View;
import android.view.ViewGroup;
import org.w3c.dom.Node;
import java.util.Map;
/**
@@ -12,7 +14,7 @@ import java.util.Map;
*/
public interface ViewAttrSetter<V extends View> {
public interface ViewInflater<V extends View> {
boolean setAttr(V view, String attrName, String value, ViewGroup parent, Map<String, String> attrs);
@@ -20,6 +22,8 @@ public interface ViewAttrSetter<V extends View> {
void applyPendingAttributes(V view, ViewGroup parent);
boolean inflateChildren(DynamicLayoutInflater inflater, Node node, V parent);
@Nullable
ViewCreator<V> getCreator();
}

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
@@ -12,8 +12,9 @@ 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.DynamicLayoutInflater;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewInflater;
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;
@@ -23,6 +24,8 @@ import com.stardust.autojs.core.ui.inflater.util.Ids;
import com.stardust.autojs.core.ui.inflater.util.Strings;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
import org.w3c.dom.Node;
import java.lang.reflect.Method;
import java.util.Map;
@@ -30,7 +33,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/3.
*/
public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
public class BaseViewInflater<V extends View> implements ViewInflater<V> {
protected static final ValueMapper<PorterDuff.Mode> TINT_MODES = new ValueMapper<PorterDuff.Mode>("tintMode")
@@ -91,14 +94,14 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
.map("viewEnd", 6)
.map("viewStart", 5);
private final ValueParser mValueParser;
private final ResourceParser mResourceParser;
public BaseViewAttrSetter(ValueParser valueParser) {
mValueParser = valueParser;
public BaseViewInflater(ResourceParser resourceParser) {
mResourceParser = resourceParser;
}
public Drawables getDrawables(){
return mValueParser.getDrawables();
public Drawables getDrawables() {
return mResourceParser.getDrawables();
}
@@ -584,7 +587,7 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
@Override
public boolean setAttr(V view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
if (ns.equals("android")) {
if (ns == null || ns.equals("android")) {
return setAttr(view, attrName, value, parent, attrs);
}
return false;
@@ -606,6 +609,11 @@ public class BaseViewAttrSetter<V extends View> implements ViewAttrSetter<V> {
}
@Override
public boolean inflateChildren(DynamicLayoutInflater inflater, Node node, V parent) {
return false;
}
@Nullable
@Override
public ViewCreator<V> getCreator() {

View File

@@ -1,26 +1,22 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.Context;
import android.support.annotation.Nullable;
import com.stardust.autojs.core.eventloop.EventEmitter;
import com.stardust.autojs.core.graphics.ScriptCanvasView;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.runtime.ScriptRuntime;
import java.util.Map;
/**
* Created by Stardust on 2018/3/16.
*/
public class CanvasViewAttrSetter extends BaseViewAttrSetter<ScriptCanvasView> {
public class CanvasViewInflater extends BaseViewInflater<ScriptCanvasView> {
private ScriptRuntime mScriptRuntime;
public CanvasViewAttrSetter(ValueParser valueParser, ScriptRuntime runtime) {
super(valueParser);
public CanvasViewInflater(ResourceParser resourceParser, ScriptRuntime runtime) {
super(resourceParser);
mScriptRuntime = runtime;
}

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.os.Build;
import android.support.annotation.Nullable;
@@ -9,7 +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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import java.text.ParseException;
@@ -21,12 +21,12 @@ import java.util.Map;
* Created by Stardust on 2017/11/29.
*/
public class DatePickerAttrSetter extends BaseViewAttrSetter<DatePicker> {
public class DatePickerInflater extends BaseViewInflater<DatePicker> {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("mm/dd/yyyy", Locale.getDefault());
public DatePickerAttrSetter(ValueParser valueParser) {
super(valueParser);
public DatePickerInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.view.View;

View File

@@ -1,10 +1,10 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.util.Gravities;
import java.util.Map;
@@ -13,12 +13,12 @@ import java.util.Map;
* Created by Stardust on 2017/11/29.
*/
public class FrameLayoutAttrSetter<V extends FrameLayout> extends ViewGroupAttrSetter<V> {
public class FrameLayoutInflater<V extends FrameLayout> extends ViewGroupInflater<V> {
private Integer mGravity;
public FrameLayoutAttrSetter(ValueParser valueParser) {
super(valueParser);
public FrameLayoutInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override
@@ -31,7 +31,7 @@ public class FrameLayoutAttrSetter<V extends FrameLayout> extends ViewGroupAttrS
}
@Override
public void applyPendingAttributesAboutChildren(V view) {
public void applyPendingAttributesOfChildren(V view) {
if (mGravity == null)
return;
for (int i = 0; i < view.getChildCount(); i++) {

View File

@@ -1,14 +1,13 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.os.Build;
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.ResourceParser;
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;
import java.util.Map;
@@ -16,10 +15,10 @@ import java.util.Map;
* Created by Stardust on 2017/11/3.
*/
public class ImageViewAttrSetter<V extends ImageView> extends BaseViewAttrSetter<V> {
public class ImageViewInflater<V extends ImageView> extends BaseViewInflater<V> {
public ImageViewAttrSetter(ValueParser valueParser) {
super(valueParser);
public ImageViewInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,12 +1,11 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
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.ResourceParser;
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;
@@ -20,7 +19,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/30.
*/
public class JsImageViewAttrSetter extends ImageViewAttrSetter<JsImageView> {
public class JsImageViewInflater extends ImageViewInflater<JsImageView> {
protected static final ValueMapper<ScaleType> SCALE_TYPES = new ValueMapper<ScaleType>("scaleType")
@@ -33,8 +32,8 @@ public class JsImageViewAttrSetter extends ImageViewAttrSetter<JsImageView> {
.map("fitXY", ScaleType.FIT_XY)
.map("matrix", ScaleType.MATRIX);
public JsImageViewAttrSetter(ValueParser valueParser) {
super(valueParser);
public JsImageViewInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -0,0 +1,57 @@
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.support.annotation.Nullable;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.runtime.ScriptRuntime;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.Map;
/**
* Created by Stardust on 2018/3/28.
*/
public class JsListViewInflater extends BaseViewInflater<JsListView> {
private ScriptRuntime mRuntime;
public JsListViewInflater(ResourceParser resourceParser, ScriptRuntime runtime) {
super(resourceParser);
mRuntime = runtime;
}
@Override
public boolean setAttr(JsListView view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
return super.setAttr(view, attr, value, parent, attrs);
}
@Override
public boolean setAttr(JsListView view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
return super.setAttr(view, ns, attrName, value, parent, attrs);
}
@Override
public boolean inflateChildren(DynamicLayoutInflater inflater, Node node, JsListView parent) {
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node child = nodeList.item(i);
if (child.getNodeType() != Node.ELEMENT_NODE) continue;
parent.setItemTemplate(inflater, child);
return true;
}
return false;
}
@Nullable
@Override
public ViewCreator<JsListView> getCreator() {
return (context, attrs) -> new JsListView(context, mRuntime);
}
}

View File

@@ -1,10 +1,9 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.util.Gravities;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
@@ -14,14 +13,14 @@ import java.util.Map;
* Created by Stardust on 2017/11/4.
*/
public class LinearLayoutAttrSetter<V extends LinearLayout> extends ViewGroupAttrSetter<V> {
public class LinearLayoutInflater<V extends LinearLayout> extends ViewGroupInflater<V> {
private static final ValueMapper<Integer> ORIENTATIONS = new ValueMapper<Integer>("orientation")
.map("vertical", LinearLayout.VERTICAL)
.map("horizontal", LinearLayout.HORIZONTAL);
public LinearLayoutAttrSetter(ValueParser valueParser) {
super(valueParser);
public LinearLayoutInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.util.AttributeSet;

View File

@@ -1,14 +1,13 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.res.ColorStateList;
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.ResourceParser;
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;
import java.util.Map;
@@ -16,10 +15,10 @@ import java.util.Map;
* Created by Stardust on 2017/11/29.
*/
public class ProgressBarAttrSetter<V extends ProgressBar> extends BaseViewAttrSetter<V> {
public class ProgressBarInflater<V extends ProgressBar> extends BaseViewInflater<V> {
public ProgressBarAttrSetter(ValueParser valueParser) {
super(valueParser);
public ProgressBarInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,9 +1,9 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import com.stardust.autojs.core.ui.inflater.ValueParser;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.util.Ids;
import java.util.Map;
@@ -12,12 +12,12 @@ import java.util.Map;
* Created by Stardust on 2017/11/29.
*/
public class RadioGroupAttrSetter<V extends RadioGroup> extends LinearLayoutAttrSetter<V> {
public class RadioGroupInflater<V extends RadioGroup> extends LinearLayoutInflater<V> {
private Integer mCheckedButton;
public RadioGroupAttrSetter(ValueParser valueParser) {
super(valueParser);
public RadioGroupInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override
@@ -31,7 +31,7 @@ public class RadioGroupAttrSetter<V extends RadioGroup> extends LinearLayoutAttr
}
@Override
public void applyPendingAttributesAboutChildren(V view) {
public void applyPendingAttributesOfChildren(V view) {
if (mCheckedButton != null) {
view.check(mCheckedButton);
mCheckedButton = null;

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.Context;
import android.os.Build;
@@ -8,10 +8,9 @@ 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.ResourceParser;
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;
import com.stardust.autojs.core.ui.inflater.util.Strings;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
@@ -22,14 +21,14 @@ import java.util.Map;
* Created by Stardust on 2017/11/29.
*/
public class SpinnerAttrSetter extends BaseViewAttrSetter<Spinner> {
public class SpinnerInflater extends BaseViewInflater<Spinner> {
protected static final ValueMapper<Integer> SPINNER_MODES = new ValueMapper<Integer>("spinnerMode")
.map("dialog", Spinner.MODE_DIALOG)
.map("dropdown", Spinner.MODE_DROPDOWN);
public SpinnerAttrSetter(ValueParser valueParser) {
super(valueParser);
public SpinnerInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,4 +1,4 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@@ -14,10 +14,9 @@ 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.ResourceParser;
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;
import com.stardust.autojs.core.ui.inflater.util.Gravities;
import com.stardust.autojs.core.ui.inflater.util.Res;
import com.stardust.autojs.core.ui.inflater.util.Strings;
@@ -29,7 +28,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/3.
*/
public class TextViewAttrSetter<V extends TextView> extends BaseViewAttrSetter<V> {
public class TextViewInflater<V extends TextView> extends BaseViewInflater<V> {
private static final ValueMapper<Integer> AUTO_LINK_MASKS = new ValueMapper<Integer>("autoLink")
.map("all", Linkify.ALL)
@@ -123,8 +122,8 @@ public class TextViewAttrSetter<V extends TextView> extends BaseViewAttrSetter<V
private Integer mTextStyle;
private String mTypeface;
public TextViewAttrSetter(ValueParser valueParser) {
super(valueParser);
public TextViewInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,21 +1,21 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.support.annotation.Nullable;
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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
/**
* Created by Stardust on 2017/11/29.
*/
public class TimePickerAttrSetter extends BaseViewAttrSetter<TimePicker> {
public class TimePickerInflater extends BaseViewInflater<TimePicker> {
public TimePickerAttrSetter(ValueParser valueParser) {
super(valueParser);
public TimePickerInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Nullable

View File

@@ -1,9 +1,9 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.util.Strings;
import java.util.Map;
@@ -12,11 +12,11 @@ import java.util.Map;
* Created by Stardust on 2017/11/5.
*/
public class ToolbarAttrSetter<V extends Toolbar> extends BaseViewAttrSetter<V> {
public class ToolbarInflater<V extends Toolbar> extends BaseViewInflater<V> {
public ToolbarAttrSetter(ValueParser valueParser) {
super(valueParser);
public ToolbarInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@Override

View File

@@ -1,10 +1,10 @@
package com.stardust.autojs.core.ui.inflater.attrsetter;
package com.stardust.autojs.core.ui.inflater.inflaters;
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.ResourceParser;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
import java.util.Map;
@@ -13,7 +13,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/4.
*/
public class ViewGroupAttrSetter<V extends ViewGroup> extends BaseViewAttrSetter<V> {
public class ViewGroupInflater<V extends ViewGroup> extends BaseViewInflater<V> {
private static final ValueMapper<Integer> PERSISTENT_DRAWING_CACHE = new ValueMapper<Integer>("persistentDrawingCache")
.map("all", ViewGroup.PERSISTENT_ALL_CACHES)
@@ -30,8 +30,8 @@ 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);
public ViewGroupInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@@ -79,7 +79,7 @@ public class ViewGroupAttrSetter<V extends ViewGroup> extends BaseViewAttrSetter
return true;
}
public void applyPendingAttributesAboutChildren(V view) {
public void applyPendingAttributesOfChildren(V view) {
}
}

View File

@@ -0,0 +1,117 @@
package com.stardust.autojs.core.ui.widget;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
import com.stardust.autojs.core.ui.inflater.ViewInflater;
import com.stardust.autojs.runtime.ScriptRuntime;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.Map;
/**
* Created by Stardust on 2018/3/28.
*/
public class JsListView extends RecyclerView {
public interface DataSourceAdapter {
int getItemCount(Object dataSource);
Object getItem(Object dataSource, int i);
void setDataSource(Object dataSource);
}
private Node mItemTemplate;
private DynamicLayoutInflater mDynamicLayoutInflater;
private ScriptRuntime mScriptRuntime;
private Object mDataSource;
private DataSourceAdapter mDataSourceAdapter;
public JsListView(Context context, ScriptRuntime scriptRuntime) {
super(context);
mScriptRuntime = scriptRuntime;
init();
}
private void init() {
setAdapter(new Adapter());
setLayoutManager(new LinearLayoutManager(getContext()));
}
public void setDataSourceAdapter(DataSourceAdapter dataSourceAdapter) {
mDataSourceAdapter = dataSourceAdapter;
getAdapter().notifyDataSetChanged();
}
public Object getDataSource() {
return mDataSource;
}
public void setDataSource(Object dataSource) {
mDataSource = dataSource;
if (mDataSourceAdapter != null)
mDataSourceAdapter.setDataSource(dataSource);
getAdapter().notifyDataSetChanged();
}
public void setItemTemplate(DynamicLayoutInflater inflater, Node itemTemplate) {
mDynamicLayoutInflater = inflater;
mItemTemplate = itemTemplate;
}
private class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(mDynamicLayoutInflater.inflate(mItemTemplate, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Object oldCtx = mScriptRuntime.ui.getBindingContext();
mScriptRuntime.ui.setBindingContext(mDataSourceAdapter.getItem(mDataSource, position));
applyDynamicAttrs(mItemTemplate, holder.itemView, (ViewGroup) holder.itemView.getParent());
mScriptRuntime.ui.setBindingContext(oldCtx);
}
private void applyDynamicAttrs(Node node, View itemView, ViewGroup parent) {
mDynamicLayoutInflater.applyAttributes(itemView, mDynamicLayoutInflater.getAttributesMap(node), parent);
if (!(itemView instanceof ViewGroup))
return;
ViewGroup viewGroup = (ViewGroup) itemView;
NodeList nodeList = node.getChildNodes();
int j = 0;
for (int i = 0; i < nodeList.getLength(); i++) {
Node child = nodeList.item(i);
if (child.getNodeType() != Node.ELEMENT_NODE) continue;
applyDynamicAttrs(child, viewGroup.getChildAt(j), viewGroup);
j++;
}
}
@Override
public int getItemCount() {
return mDataSource == null ? 0
: mDataSourceAdapter == null ? 0
: mDataSourceAdapter.getItemCount(mDataSource);
}
}
}

View File

@@ -1,5 +1,6 @@
package com.stardust.autojs.core.ui.xml;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.webkit.WebView;
import android.widget.CheckBox;
@@ -18,6 +19,7 @@ import com.stardust.autojs.core.ui.widget.JsEditText;
import com.stardust.autojs.core.ui.widget.JsFrameLayout;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.widget.JsLinearLayout;
import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.core.ui.widget.JsRelativeLayout;
import com.stardust.autojs.core.ui.widget.JsTextView;
import com.stardust.autojs.core.ui.widget.JsWebView;
@@ -66,6 +68,7 @@ public class XmlConverter {
.map("scroll", ScrollView.class.getName())
.map("toolbar", Toolbar.class.getName())
.map("canvas", ScriptCanvasView.class.getName())
.map("list", JsListView.class.getName())
);
private static final AttributeHandler ATTRIBUTE_HANDLER = new AttributeHandler.AttrNameRouter()

View File

@@ -18,6 +18,8 @@ public class ScriptBridges {
Object toArray(Object o);
Object toString(Object obj);
Object eval(Object context, String expr);
}
private Bridges mBridges;
@@ -47,4 +49,10 @@ public class ScriptBridges {
checkBridges();
return mBridges.toString(obj);
}
public Object eval(Object context, String expr) {
checkBridges();
return mBridges.eval(context, expr);
}
}

View File

@@ -212,7 +212,7 @@ public class ScriptRuntime {
device = new Device(context);
floaty = new Floaty(uiHandler, ui, this);
files = new Files(this);
media = new Media(context);
media = new Media(context, this);
}
public void init() {

View File

@@ -8,8 +8,8 @@ import android.view.View;
import com.stardust.autojs.R;
import com.stardust.autojs.core.floaty.FloatyWindow;
import com.stardust.autojs.core.ui.JsLayoutInflater;
import com.stardust.autojs.core.ui.JsViewHelper;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.util.FloatingPermission;
@@ -26,7 +26,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
public class Floaty {
private JsLayoutInflater mJsLayoutInflater;
private DynamicLayoutInflater mLayoutInflater;
private Context mContext;
private UiHandler mUiHandler;
private CopyOnWriteArraySet<JsFloatyWindow> mWindows = new CopyOnWriteArraySet<>();
@@ -36,7 +36,7 @@ public class Floaty {
mUiHandler = uiHandler;
mRuntime = runtime;
mContext = new ContextThemeWrapper(mUiHandler.getContext(), R.style.AppTheme);
mJsLayoutInflater = ui.getJsLayoutInflater();
mLayoutInflater = ui.getLayoutInflater();
}
public JsFloatyWindow window(String xml) {
@@ -64,10 +64,10 @@ public class Floaty {
private View inflate(String xml) {
if (Looper.getMainLooper() == Looper.myLooper()) {
return mJsLayoutInflater.inflate(mContext, xml);
return mLayoutInflater.inflate(xml);
} else {
VolatileDispose<View> dispose = new VolatileDispose<>();
mUiHandler.post(() -> dispose.setAndNotify(mJsLayoutInflater.inflate(mContext, xml)));
mUiHandler.post(() -> dispose.setAndNotify(mLayoutInflater.inflate(xml)));
return dispose.blockedGetOrThrow(ScriptInterruptedException.class);
}
}

View File

@@ -5,6 +5,7 @@ import android.media.MediaPlayer;
import android.media.MediaScannerConnection;
import android.net.Uri;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.MimeTypes;
@@ -18,15 +19,17 @@ public class Media implements MediaScannerConnection.MediaScannerConnectionClien
private MediaScannerConnection mScannerConnection;
private MediaPlayerWrapper mMediaPlayer;
private ScriptRuntime mRuntime;
public Media(Context context) {
public Media(Context context, ScriptRuntime runtime) {
mScannerConnection = new MediaScannerConnection(context, this);
mRuntime = runtime;
mScannerConnection.connect();
}
public void scanFile(String path) {
String mimeType = MimeTypes.fromFileOr(path, null);
mScannerConnection.scanFile(path, mimeType);
mScannerConnection.scanFile(mRuntime.files.path(path), mimeType);
}
@Override
@@ -43,6 +46,7 @@ public class Media implements MediaScannerConnection.MediaScannerConnectionClien
}
public void playMusic(String path, float volume, boolean looping) {
path = mRuntime.files.path(path);
if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayerWrapper();
}

View File

@@ -4,13 +4,13 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import com.stardust.autojs.core.graphics.ScriptCanvasView;
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.CanvasViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.attrsetter.JsImageViewAttrSetter;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.inflaters.CanvasViewInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.JsImageViewInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.JsListViewInflater;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.rhino.ProxyObject;
import com.stardust.autojs.runtime.ScriptRuntime;
@@ -29,26 +29,36 @@ public class UI extends ProxyObject {
private Context mContext;
private Map<String, Object> mProperties = new ConcurrentHashMap<>();
private JsLayoutInflater mJsLayoutInflater;
private DynamicLayoutInflater mDynamicLayoutInflater;
private ScriptRuntime mRuntime;
private ValueParser mValueParser;
private ResourceParser mResourceParser;
public UI(Context context, ScriptRuntime runtime) {
mContext = context;
mRuntime = runtime;
mValueParser = new ValueParser(new Drawables());
DynamicLayoutInflater inflater = new DynamicLayoutInflater(mValueParser);
inflater.registerViewAttrSetter(JsImageView.class.getName(),
new JsImageViewAttrSetter(mValueParser));
inflater.registerViewAttrSetter(ScriptCanvasView.class.getName(),
new CanvasViewAttrSetter(mValueParser, runtime));
mJsLayoutInflater = new ConvertLayoutInflater(inflater);
mProperties.put("layoutInflater", mJsLayoutInflater);
mResourceParser = new ResourceParser(new Drawables());
mDynamicLayoutInflater = new DynamicLayoutInflater(mResourceParser);
mDynamicLayoutInflater.setContext(context);
mDynamicLayoutInflater.registerViewAttrSetter(JsImageView.class.getName(),
new JsImageViewInflater(mResourceParser));
mDynamicLayoutInflater.registerViewAttrSetter(JsListView.class.getName(),
new JsListViewInflater(mResourceParser, runtime));
mDynamicLayoutInflater.registerViewAttrSetter(ScriptCanvasView.class.getName(),
new CanvasViewInflater(mResourceParser, runtime));
mProperties.put("layoutInflater", this.mDynamicLayoutInflater);
}
public Object getBindingContext() {
return mProperties.get("bindingContext");
}
public void setBindingContext(Object context) {
mProperties.put("bindingContext", context);
}
public JsLayoutInflater getJsLayoutInflater() {
return mJsLayoutInflater;
public DynamicLayoutInflater getLayoutInflater() {
return mDynamicLayoutInflater;
}
@Override
@@ -59,16 +69,24 @@ public class UI extends ProxyObject {
@Override
public Object get(String name, Scriptable start) {
Object value = super.get(name, start);
if (value != null && value != UniqueTag.NOT_FOUND && !value.equals(org.mozilla.javascript.Context.getUndefinedValue())) {
return value;
}
value = mProperties.get(name);
Object value = mProperties.get(name);
if (value != null)
return value;
return UniqueTag.NOT_FOUND;
return super.get(name, start);
}
@Override
public void put(String name, Scriptable start, Object value) {
if (mProperties.containsKey(name)) {
if (value == null) {
mProperties.remove(name);
} else {
mProperties.put(name, value);
}
} else {
super.put(name, start, value);
}
}
private class Drawables extends com.stardust.autojs.core.ui.inflater.util.Drawables {