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;