feat(ui): supports label grid

This commit is contained in:
hyb1996
2018-03-30 17:37:31 +08:00
parent 47faa1f69e
commit af5bf8ecf2
13 changed files with 176 additions and 17 deletions

View File

@@ -8,11 +8,23 @@ module.exports = function (runtime, global) {
ui.__view_cache__ = {};
ui.layout = function (xml) {
if(!activity){
throw new Error("需要在ui模式下运行才能使用该函数");
}
runtime.ui.layoutInflater.setContext(activity);
var view = runtime.ui.layoutInflater.inflate(xml.toString());
ui.setContentView(view);
}
ui.inflate = function(xml, parent){
if(!activity){
throw new Error("需要在ui模式下运行才能使用该函数");
}
parent = parent || null;
runtime.ui.layoutInflater.setContext(activity);
return decorate(runtime.ui.layoutInflater.inflate(xml.toString(), parent));
}
ui.setContentView = function (view) {
ui.view = view;
ui.__view_cache__ = {};
@@ -86,7 +98,8 @@ module.exports = function (runtime, global) {
}
runtime.ui.bindingContext = global;
runtime.ui.layoutInflater.setLayoutInflaterDelegate({
var layoutInflater = runtime.ui.layoutInflater;
layoutInflater.setLayoutInflaterDelegate({
beforeConvertXml: function (xml) {
return null;
},
@@ -109,7 +122,8 @@ module.exports = function (runtime, global) {
return null;
},
afterCreateView: function (view, node, viewName, attrs) {
if (view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsListView") {
if (view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsListView" ||
view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsGridView") {
initListView(view);
}
return view;
@@ -133,6 +147,11 @@ module.exports = function (runtime, global) {
return false;
},
beforeApplyAttribute: function (inflater, view, ns, attrName, value, parent, attrs) {
var isDynamic = layoutInflater.isDynamicValue(value);
if ((isDynamic && layoutInflater.getInflateFlags() == layoutInflater.FLAG_IGNORES_DYNAMIC_ATTRS)
|| (!isDynamic && layoutInflater.getInflateFlags() == layoutInflater.FLAG_JUST_DYNAMIC_ATTRS)) {
return true;
}
value = bind(value);
inflater.setAttr(view, ns, attrName, value, parent, attrs);
this.afterApplyAttribute(inflater, view, ns, attrName, value, parent, attrs);
@@ -171,7 +190,8 @@ module.exports = function (runtime, global) {
function decorate(view) {
var view = global.events.__asEmitter__(Object.create(view));
if (view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsListView") {
if (view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsListView"
|| view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsGridView") {
view = decorateList(view);
}
var gestureDetector = new android.view.GestureDetector(context, {

View File

@@ -50,6 +50,11 @@ import javax.xml.parsers.DocumentBuilderFactory;
public class DynamicLayoutInflater {
public static final int FLAG_DEFAULT = 0;
public static final int FLAG_IGNORES_DYNAMIC_ATTRS = 1;
public static final int FLAG_JUST_DYNAMIC_ATTRS = 2;
private static final String LOG_TAG = "DynamicLayoutInflater";
private Map<String, ViewInflater<?>> mViewAttrSetters = new HashMap<>();
@@ -58,6 +63,7 @@ public class DynamicLayoutInflater {
private ResourceParser mResourceParser;
@NonNull
private LayoutInflaterDelegate mLayoutInflaterDelegate = LayoutInflaterDelegate.NO_OP;
private int mInflateFlags;
public DynamicLayoutInflater(ResourceParser resourceParser) {
mResourceParser = resourceParser;
@@ -72,6 +78,14 @@ public class DynamicLayoutInflater {
this.mViewCreators = new HashMap<>(inflater.mViewCreators);
}
public int getInflateFlags() {
return mInflateFlags;
}
public void setInflateFlags(int inflateFlags) {
mInflateFlags = inflateFlags;
}
public ResourceParser getResourceParser() {
return mResourceParser;
}
@@ -160,8 +174,11 @@ public class DynamicLayoutInflater {
return view;
HashMap<String, String> attrs = getAttributesMap(node);
view = doCreateView(node, node.getNodeName(), attrs);
if (parent != null && attachToParent) {
parent.addView(view); // have to add to parent to enable certain layout attrs
if (parent != null) {
parent.addView(view); // have to add to parent to generate layout params
if (!attachToParent) {
parent.removeView(view);
}
}
ViewInflater<View> inflater = applyAttributes(view, attrs, parent);
if (!(view instanceof ViewGroup) || !node.hasChildNodes()) {
@@ -297,10 +314,22 @@ public class DynamicLayoutInflater {
if (mLayoutInflaterDelegate.beforeApplyAttribute(inflater, view, ns, attrName, value, parent, attrs)) {
return;
}
boolean isDynamic = isDynamicValue(value);
if ((isDynamic && mInflateFlags == FLAG_IGNORES_DYNAMIC_ATTRS)
|| (!isDynamic && mInflateFlags == FLAG_JUST_DYNAMIC_ATTRS)) {
return;
}
inflater.setAttr(view, ns, attrName, value, parent, attrs);
mLayoutInflaterDelegate.afterApplyAttribute(inflater, view, ns, attrName, value, parent, attrs);
}
public boolean isDynamicValue(String value) {
int i = value.indexOf("{{");
if (i < 0)
return false;
return value.indexOf("}}", i + 1) >= 0;
}
}

View File

@@ -25,5 +25,5 @@ public interface ViewInflater<V extends View> {
boolean inflateChildren(DynamicLayoutInflater inflater, Node node, V parent);
@Nullable
ViewCreator<V> getCreator();
ViewCreator<? super V> getCreator();
}

View File

@@ -616,7 +616,7 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
@Nullable
@Override
public ViewCreator<V> getCreator() {
public ViewCreator<? super V> getCreator() {
return null;
}
}

View File

@@ -0,0 +1,45 @@
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.view.ViewGroup;
import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.widget.JsGridView;
import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.runtime.ScriptRuntime;
import java.util.Map;
/**
* Created by Stardust on 2018/3/30.
*/
public class JsGridViewInflater<V extends JsGridView> extends JsListViewInflater<V> {
public JsGridViewInflater(ResourceParser resourceParser, ScriptRuntime runtime) {
super(resourceParser, runtime);
}
@Override
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
case "orientation":
((GridLayoutManager) view.getLayoutManager()).setOrientation(LinearLayoutInflater.ORIENTATIONS.get(value));
return true;
case "spanCount":
((GridLayoutManager) view.getLayoutManager()).setSpanCount(Integer.parseInt(value));
return true;
default:
return super.setAttr(view, attr, value, parent, attrs);
}
}
@Nullable
@Override
public ViewCreator<? super JsListView> getCreator() {
return (context, attrs) -> new JsGridView(context, getRuntime());
}
}

View File

@@ -21,17 +21,21 @@ import java.util.Map;
* Created by Stardust on 2018/3/28.
*/
public class JsListViewInflater extends BaseViewInflater<JsListView> {
public class JsListViewInflater<V extends JsListView> extends BaseViewInflater<V> {
private ScriptRuntime mRuntime;
private final ScriptRuntime mRuntime;
public JsListViewInflater(ResourceParser resourceParser, ScriptRuntime runtime) {
super(resourceParser);
mRuntime = runtime;
}
public ScriptRuntime getRuntime() {
return mRuntime;
}
@Override
public boolean setAttr(JsListView view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
public boolean setAttr(V view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) {
case "orientation":
view.setLayoutManager(new WrapContentLinearLayoutManager(view.getContext(), LinearLayoutInflater.ORIENTATIONS.get(value), false));
@@ -42,7 +46,7 @@ public class JsListViewInflater extends BaseViewInflater<JsListView> {
}
@Override
public boolean setAttr(JsListView view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
public boolean setAttr(V view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
return super.setAttr(view, ns, attrName, value, parent, attrs);
}
@@ -60,7 +64,7 @@ public class JsListViewInflater extends BaseViewInflater<JsListView> {
@Nullable
@Override
public ViewCreator<JsListView> getCreator() {
public ViewCreator<? super JsListView> getCreator() {
return (context, attrs) -> new JsListView(context, mRuntime);
}
}

View File

@@ -55,8 +55,11 @@ public class Drawables {
}
public Drawable loadDrawableResources(Context context, String value) {
return context.getResources().getDrawable(context.getResources().getIdentifier(value, "drawable",
context.getPackageName()));
int resId = context.getResources().getIdentifier(value, "drawable",
context.getPackageName());
if (resId == 0)
throw new Resources.NotFoundException("drawable not found: " + value);
return context.getResources().getDrawable(resId);
}
public Drawable loadAttrResources(Context context, String value) {

View File

@@ -0,0 +1,23 @@
package com.stardust.autojs.core.ui.widget;
import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import com.stardust.autojs.runtime.ScriptRuntime;
/**
* Created by Stardust on 2018/3/30.
*/
public class JsGridView extends JsListView {
public JsGridView(Context context, ScriptRuntime scriptRuntime) {
super(context, scriptRuntime);
}
@Override
protected void init() {
super.init();
setLayoutManager(new GridLayoutManager(getContext(), 1));
}
}

View File

@@ -1,6 +1,7 @@
package com.stardust.autojs.core.ui.widget;
import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
@@ -47,11 +48,12 @@ public class JsListView extends RecyclerView {
init();
}
private void init() {
protected void init() {
setAdapter(new Adapter());
setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
}
public void setOnItemTouchListener(OnItemTouchListener onItemTouchListener) {
mOnItemTouchListener = onItemTouchListener;
}
@@ -101,10 +103,13 @@ public class JsListView extends RecyclerView {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
try {
mDynamicLayoutInflater.setInflateFlags(DynamicLayoutInflater.FLAG_IGNORES_DYNAMIC_ATTRS);
return new ViewHolder(mDynamicLayoutInflater.inflate(mItemTemplate, parent, false));
} catch (Exception e) {
mScriptRuntime.exit(e);
return new ViewHolder(new View(parent.getContext()));
} finally {
mDynamicLayoutInflater.setInflateFlags(DynamicLayoutInflater.FLAG_DEFAULT);
}
}
@@ -113,10 +118,13 @@ public class JsListView extends RecyclerView {
try {
Object oldCtx = mScriptRuntime.ui.getBindingContext();
mScriptRuntime.ui.setBindingContext(mDataSourceAdapter.getItem(mDataSource, position));
applyDynamicAttrs(mItemTemplate, holder.itemView, (ViewGroup) holder.itemView.getParent());
mDynamicLayoutInflater.setInflateFlags(DynamicLayoutInflater.FLAG_JUST_DYNAMIC_ATTRS);
applyDynamicAttrs(mItemTemplate, holder.itemView, JsListView.this);
mScriptRuntime.ui.setBindingContext(oldCtx);
} catch (Exception e) {
mScriptRuntime.exit(e);
} finally {
mDynamicLayoutInflater.setInflateFlags(DynamicLayoutInflater.FLAG_DEFAULT);
}
}

View File

@@ -17,6 +17,7 @@ import com.stardust.autojs.core.graphics.ScriptCanvasView;
import com.stardust.autojs.core.ui.widget.JsButton;
import com.stardust.autojs.core.ui.widget.JsEditText;
import com.stardust.autojs.core.ui.widget.JsFrameLayout;
import com.stardust.autojs.core.ui.widget.JsGridView;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.widget.JsLinearLayout;
import com.stardust.autojs.core.ui.widget.JsListView;
@@ -69,6 +70,7 @@ public class XmlConverter {
.map("toolbar", Toolbar.class.getName())
.map("canvas", ScriptCanvasView.class.getName())
.map("list", JsListView.class.getName())
.map("grid", JsGridView.class.getName())
);
private static final AttributeHandler ATTRIBUTE_HANDLER = new AttributeHandler.AttrNameRouter()

View File

@@ -65,8 +65,9 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
public void forceStop() {
LooperHelper.quitForThread(getThread());
Activity activity = (Activity) getTag("activity");
if (activity != null)
if (activity != null) {
activity.finish();
}
super.forceStop();
}

View File

@@ -7,8 +7,10 @@ import com.stardust.autojs.core.graphics.ScriptCanvasView;
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
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.JsGridViewInflater;
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.JsGridView;
import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.rhino.ProxyObject;
@@ -43,6 +45,8 @@ public class UI extends ProxyObject {
new JsImageViewInflater(mResourceParser));
mDynamicLayoutInflater.registerViewAttrSetter(JsListView.class.getName(),
new JsListViewInflater(mResourceParser, runtime));
mDynamicLayoutInflater.registerViewAttrSetter(JsGridView.class.getName(),
new JsGridViewInflater(mResourceParser, runtime));
mDynamicLayoutInflater.registerViewAttrSetter(ScriptCanvasView.class.getName(),
new CanvasViewInflater(mResourceParser, runtime));
mProperties.put("layoutInflater", this.mDynamicLayoutInflater);