From a7ed49d8b133820bb6504285d8c23c26729c5138 Mon Sep 17 00:00:00 2001
From: hyb1996 <946994919@qq.com>
Date: Thu, 29 Mar 2018 21:17:49 +0800
Subject: [PATCH] sample(ui): music file browser
---
.../main/assets/sample/复杂界面/音乐浏览器.js | 59 +++++++++++++++++++
.../ui/edit/completion/CodeCompletionBar.java | 2 +-
.../ui/main/task/TaskListRecyclerView.java | 2 +-
autojs/src/main/assets/init.js | 5 --
autojs/src/main/assets/modules/__ui__.js | 39 +++++++++---
.../inflaters/JsListViewInflater.java | 11 +++-
.../inflaters/LinearLayoutInflater.java | 2 +-
.../autojs/core/ui/widget/JsListView.java | 49 +++++++++++----
.../autojs/runtime/ScriptBridges.java | 8 +--
.../com/stardust/autojs/runtime/api/UI.java | 5 +-
.../WrapContentLinearLayoutManager.java | 2 +-
11 files changed, 148 insertions(+), 36 deletions(-)
create mode 100644 app/src/main/assets/sample/复杂界面/音乐浏览器.js
rename {app/src/main/java/android => autojs/src/main/java/com/stardust/autojs}/workground/WrapContentLinearLayoutManager.java (96%)
diff --git a/app/src/main/assets/sample/复杂界面/音乐浏览器.js b/app/src/main/assets/sample/复杂界面/音乐浏览器.js
new file mode 100644
index 00000000..f3d6f949
--- /dev/null
+++ b/app/src/main/assets/sample/复杂界面/音乐浏览器.js
@@ -0,0 +1,59 @@
+"ui";
+
+//音乐文件的后缀名
+var musicExts = [".mp3", ".wma", ".rm", ".wav", ".mid", ".ape", ".flac"];
+//扫描路径
+var path = files.getSdcardPath();
+//保存音乐文件列表的数组
+var musicFiles = [];
+
+ui.layout(
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+ui.files.setDataSource(musicFiles);
+
+ui.files.on("item_click", function(item, pos){
+ media.playMusic(item.path, 1);
+});
+
+//启动线程来扫描音乐文件
+threads.start(function () {
+ listMuiscFiles(path, musicFiles);
+ ui.run(()=> {
+ ui.progressbar.setVisility(8);
+ });
+});
+
+function listMuiscFiles(dir, list) {
+ //遍历该文件夹的文件
+ files.listDir(dir).forEach(fileName => {
+ var path = files.join(dir, fileName);
+ //如果是子文件夹则继续扫描子文件夹的文件
+ if (files.isDir(path)) {
+ listMuiscFiles(path, list);
+ return;
+ }
+ for (var i = 0; i < musicExts.length; i++) {
+ //如果文件名的后缀是音乐格式
+ if (fileName.endsWith(musicExts[i])) {
+ //则把它添加到列表中
+ list.push({
+ name: fileName,
+ path: path
+ });
+ }
+ }
+ });
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletionBar.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletionBar.java
index 288c49dd..210b2564 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletionBar.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/completion/CodeCompletionBar.java
@@ -9,7 +9,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import android.workground.WrapContentLinearLayoutManager;
+import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.autocomplete.CodeCompletions;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
index 3a63d4fd..96152dac 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
@@ -12,7 +12,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import android.workground.WrapContentLinearLayoutManager;
+import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
diff --git a/autojs/src/main/assets/init.js b/autojs/src/main/assets/init.js
index 9bc42ce6..63ee9547 100644
--- a/autojs/src/main/assets/init.js
+++ b/autojs/src/main/assets/init.js
@@ -52,11 +52,6 @@ runtime.init();
},
toString: function(o){
return String(o);
- },
- eval: function(context, expr){
- with(context){
- return eval(expr);
- }
}
});
diff --git a/autojs/src/main/assets/modules/__ui__.js b/autojs/src/main/assets/modules/__ui__.js
index 9124709d..b3c75baa 100644
--- a/autojs/src/main/assets/modules/__ui__.js
+++ b/autojs/src/main/assets/modules/__ui__.js
@@ -24,7 +24,7 @@ module.exports = function (runtime, global) {
ui.findById = function (id) {
if (!ui.view)
return null;
- var v = ui.findByStringId(ui.view.getChildAt(0), id);
+ var v = ui.findByStringId(ui.view, id);
if (v) {
v = decorate(v);
}
@@ -159,13 +159,14 @@ module.exports = function (runtime, global) {
}
function evalInContext(expr, ctx) {
- return global.__exitIfError__(function () {
- log(ctx.toString());
- with(ctx){
- return eval(expr);
+ return global.__exitIfError__(function() {
+ with(ctx) {
+ return (function(){
+ return eval(expr);
+ }).call(ctx);
}
});
-
+
}
function decorate(view) {
@@ -283,7 +284,9 @@ module.exports = function (runtime, global) {
adapter.notifyItemRangeInserted(change.index, change.addedCount);
}
} else if (change.type == 'update') {
- adapter.notifyItemChanged(parseInt(change.name));
+ try{
+ adapter.notifyItemChanged(parseInt(change.name));
+ }catch(e){}
}
});
});
@@ -292,7 +295,25 @@ module.exports = function (runtime, global) {
}
function decorateList(list) {
-
+ list.setOnItemTouchListener({
+ onItemClick: function(listView, itemView, item, pos){
+ emit("item_click", item, pos, itemView, listView);
+ },
+ onItemLongClick: function(listView, itemView, item, pos){
+ var event = {};
+ event.consumed = false;
+ emit("item_long_click", event, item, pos, itemView, listView);
+ return event.consumed;
+ }
+ });
+ function emit() {
+ var args = arguments;
+ global.__exitIfError__(function () {
+ //不支持使用apply的原因是rhino会把参数中的primitive变成object
+ functionApply(list.emit, args);
+ //view.emit.apply(view, args);
+ });
+ }
return list;
}
@@ -345,7 +366,7 @@ module.exports = function (runtime, global) {
cache = ui.findById(name);
if (cache) {
ui.__view_cache__[name] = cache;
- return cache;
+ return cache;
}
}
return ui[name];
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/JsListViewInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/JsListViewInflater.java
index 2f40b566..4c79a141 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/JsListViewInflater.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/JsListViewInflater.java
@@ -1,13 +1,16 @@
package com.stardust.autojs.core.ui.inflater.inflaters;
import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
import android.view.ViewGroup;
+import android.widget.LinearLayout;
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 com.stardust.autojs.workground.WrapContentLinearLayoutManager;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -29,7 +32,13 @@ public class JsListViewInflater extends BaseViewInflater {
@Override
public boolean setAttr(JsListView view, String attr, String value, ViewGroup parent, Map attrs) {
- return super.setAttr(view, attr, value, parent, attrs);
+ switch (attr) {
+ case "orientation":
+ view.setLayoutManager(new WrapContentLinearLayoutManager(view.getContext(), LinearLayoutInflater.ORIENTATIONS.get(value), false));
+ return true;
+ default:
+ return super.setAttr(view, attr, value, parent, attrs);
+ }
}
@Override
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
index 5ee771ac..81cb5a91 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
@@ -15,7 +15,7 @@ import java.util.Map;
public class LinearLayoutInflater extends ViewGroupInflater {
- private static final ValueMapper ORIENTATIONS = new ValueMapper("orientation")
+ static final ValueMapper ORIENTATIONS = new ValueMapper("orientation")
.map("vertical", LinearLayout.VERTICAL)
.map("horizontal", LinearLayout.HORIZONTAL);
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
index 8d6b97b9..d06ed07e 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
@@ -1,20 +1,17 @@
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;
+import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
/**
* Created by Stardust on 2018/3/28.
@@ -31,11 +28,18 @@ public class JsListView extends RecyclerView {
void setDataSource(Object dataSource);
}
+ public interface OnItemTouchListener {
+ void onItemClick(JsListView listView, View itemView, Object item, int pos);
+
+ boolean onItemLongClick(JsListView listView, View itemView, Object item, int pos);
+ }
+
private Node mItemTemplate;
private DynamicLayoutInflater mDynamicLayoutInflater;
private ScriptRuntime mScriptRuntime;
private Object mDataSource;
private DataSourceAdapter mDataSourceAdapter;
+ private OnItemTouchListener mOnItemTouchListener;
public JsListView(Context context, ScriptRuntime scriptRuntime) {
super(context);
@@ -45,7 +49,11 @@ public class JsListView extends RecyclerView {
private void init() {
setAdapter(new Adapter());
- setLayoutManager(new LinearLayoutManager(getContext()));
+ setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
+ }
+
+ public void setOnItemTouchListener(OnItemTouchListener onItemTouchListener) {
+ mOnItemTouchListener = onItemTouchListener;
}
public void setDataSourceAdapter(DataSourceAdapter dataSourceAdapter) {
@@ -73,6 +81,18 @@ public class JsListView extends RecyclerView {
public ViewHolder(View itemView) {
super(itemView);
+ itemView.setOnClickListener(v -> {
+ if (mOnItemTouchListener != null) {
+ int pos = getAdapterPosition();
+ mOnItemTouchListener.onItemClick(JsListView.this, itemView, mDataSourceAdapter.getItem(mDataSource, pos), pos);
+ }
+ });
+ itemView.setOnLongClickListener(v -> {
+ if (mOnItemTouchListener == null)
+ return false;
+ int pos = getAdapterPosition();
+ return mOnItemTouchListener.onItemLongClick(JsListView.this, itemView, mDataSourceAdapter.getItem(mDataSource, pos), pos);
+ });
}
}
@@ -80,15 +100,24 @@ public class JsListView extends RecyclerView {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new ViewHolder(mDynamicLayoutInflater.inflate(mItemTemplate, parent, false));
+ try {
+ return new ViewHolder(mDynamicLayoutInflater.inflate(mItemTemplate, parent, false));
+ } catch (Exception e) {
+ mScriptRuntime.exit(e);
+ return new ViewHolder(new View(parent.getContext()));
+ }
}
@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);
+ try {
+ Object oldCtx = mScriptRuntime.ui.getBindingContext();
+ mScriptRuntime.ui.setBindingContext(mDataSourceAdapter.getItem(mDataSource, position));
+ applyDynamicAttrs(mItemTemplate, holder.itemView, (ViewGroup) holder.itemView.getParent());
+ mScriptRuntime.ui.setBindingContext(oldCtx);
+ } catch (Exception e) {
+ mScriptRuntime.exit(e);
+ }
}
private void applyDynamicAttrs(Node node, View itemView, ViewGroup parent) {
diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.java b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.java
index e1c77afa..86450f0a 100644
--- a/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.java
+++ b/autojs/src/main/java/com/stardust/autojs/runtime/ScriptBridges.java
@@ -1,5 +1,7 @@
package com.stardust.autojs.runtime;
+import android.view.View;
+
import com.stardust.autojs.core.accessibility.UiCollection;
/**
@@ -19,7 +21,6 @@ public class ScriptBridges {
Object toString(Object obj);
- Object eval(Object context, String expr);
}
private Bridges mBridges;
@@ -50,9 +51,4 @@ public class ScriptBridges {
return mBridges.toString(obj);
}
- public Object eval(Object context, String expr) {
- checkBridges();
- return mBridges.eval(context, expr);
-
- }
}
diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java
index dfdcb9bf..afc0742e 100644
--- a/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java
+++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java
@@ -53,7 +53,10 @@ public class UI extends ProxyObject {
}
public void setBindingContext(Object context) {
- mProperties.put("bindingContext", context);
+ if (context == null)
+ mProperties.remove("bindingContext");
+ else
+ mProperties.put("bindingContext", context);
}
diff --git a/app/src/main/java/android/workground/WrapContentLinearLayoutManager.java b/autojs/src/main/java/com/stardust/autojs/workground/WrapContentLinearLayoutManager.java
similarity index 96%
rename from app/src/main/java/android/workground/WrapContentLinearLayoutManager.java
rename to autojs/src/main/java/com/stardust/autojs/workground/WrapContentLinearLayoutManager.java
index 8c564b2b..ffd19b4c 100644
--- a/app/src/main/java/android/workground/WrapContentLinearLayoutManager.java
+++ b/autojs/src/main/java/com/stardust/autojs/workground/WrapContentLinearLayoutManager.java
@@ -1,4 +1,4 @@
-package android.workground;
+package com.stardust.autojs.workground;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;