sample(ui): music file browser
This commit is contained in:
59
app/src/main/assets/sample/复杂界面/音乐浏览器.js
Normal file
59
app/src/main/assets/sample/复杂界面/音乐浏览器.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
"ui";
|
||||||
|
|
||||||
|
//音乐文件的后缀名
|
||||||
|
var musicExts = [".mp3", ".wma", ".rm", ".wav", ".mid", ".ape", ".flac"];
|
||||||
|
//扫描路径
|
||||||
|
var path = files.getSdcardPath();
|
||||||
|
//保存音乐文件列表的数组
|
||||||
|
var musicFiles = [];
|
||||||
|
|
||||||
|
ui.layout(
|
||||||
|
<vertical bg="#ffffff">
|
||||||
|
<list id="files" layout_weight="1">
|
||||||
|
<linear bg="?selectableItemBackground">
|
||||||
|
<img src="@drawable/ic_music_note_black_48dp" tint="white" bg="#ff5722" w="50" h="70" margin="16" />
|
||||||
|
<vertical>
|
||||||
|
<text id="name" textSize="16sp" textColor="#000000" text="{{this.name}}" marginTop="16" maxLines="1" ellipsize="end"/>
|
||||||
|
<text id="path" textSize="13sp" textColor="#929292" text="{{this.path}}" marginTop="8" maxLines="1" ellipsize="end"/>
|
||||||
|
</vertical>
|
||||||
|
</linear>
|
||||||
|
</list>
|
||||||
|
<progressbar id="progressbar" indeterminate="true" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"/>
|
||||||
|
</vertical>
|
||||||
|
);
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.workground.WrapContentLinearLayoutManager;
|
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
import com.stardust.scriptdroid.R;
|
import com.stardust.scriptdroid.R;
|
||||||
import com.stardust.scriptdroid.model.autocomplete.CodeCompletions;
|
import com.stardust.scriptdroid.model.autocomplete.CodeCompletions;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.workground.WrapContentLinearLayoutManager;
|
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
|
import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
|
||||||
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
|
import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
|
||||||
|
|||||||
@@ -52,11 +52,6 @@ runtime.init();
|
|||||||
},
|
},
|
||||||
toString: function(o){
|
toString: function(o){
|
||||||
return String(o);
|
return String(o);
|
||||||
},
|
|
||||||
eval: function(context, expr){
|
|
||||||
with(context){
|
|
||||||
return eval(expr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ module.exports = function (runtime, global) {
|
|||||||
ui.findById = function (id) {
|
ui.findById = function (id) {
|
||||||
if (!ui.view)
|
if (!ui.view)
|
||||||
return null;
|
return null;
|
||||||
var v = ui.findByStringId(ui.view.getChildAt(0), id);
|
var v = ui.findByStringId(ui.view, id);
|
||||||
if (v) {
|
if (v) {
|
||||||
v = decorate(v);
|
v = decorate(v);
|
||||||
}
|
}
|
||||||
@@ -159,10 +159,11 @@ module.exports = function (runtime, global) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function evalInContext(expr, ctx) {
|
function evalInContext(expr, ctx) {
|
||||||
return global.__exitIfError__(function () {
|
return global.__exitIfError__(function() {
|
||||||
log(ctx.toString());
|
with(ctx) {
|
||||||
with(ctx){
|
return (function(){
|
||||||
return eval(expr);
|
return eval(expr);
|
||||||
|
}).call(ctx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -283,7 +284,9 @@ module.exports = function (runtime, global) {
|
|||||||
adapter.notifyItemRangeInserted(change.index, change.addedCount);
|
adapter.notifyItemRangeInserted(change.index, change.addedCount);
|
||||||
}
|
}
|
||||||
} else if (change.type == 'update') {
|
} 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) {
|
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;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +366,7 @@ module.exports = function (runtime, global) {
|
|||||||
cache = ui.findById(name);
|
cache = ui.findById(name);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
ui.__view_cache__[name] = cache;
|
ui.__view_cache__[name] = cache;
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ui[name];
|
return ui[name];
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package com.stardust.autojs.core.ui.inflater.inflaters;
|
package com.stardust.autojs.core.ui.inflater.inflaters;
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
|
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
|
||||||
import com.stardust.autojs.core.ui.inflater.ResourceParser;
|
import com.stardust.autojs.core.ui.inflater.ResourceParser;
|
||||||
import com.stardust.autojs.core.ui.inflater.ViewCreator;
|
import com.stardust.autojs.core.ui.inflater.ViewCreator;
|
||||||
import com.stardust.autojs.core.ui.widget.JsListView;
|
import com.stardust.autojs.core.ui.widget.JsListView;
|
||||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
|
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
@@ -29,7 +32,13 @@ public class JsListViewInflater extends BaseViewInflater<JsListView> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setAttr(JsListView view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
|
public boolean setAttr(JsListView view, String attr, String value, ViewGroup parent, Map<String, String> 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
|
@Override
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class LinearLayoutInflater<V extends LinearLayout> extends ViewGroupInflater<V> {
|
public class LinearLayoutInflater<V extends LinearLayout> extends ViewGroupInflater<V> {
|
||||||
|
|
||||||
private static final ValueMapper<Integer> ORIENTATIONS = new ValueMapper<Integer>("orientation")
|
static final ValueMapper<Integer> ORIENTATIONS = new ValueMapper<Integer>("orientation")
|
||||||
.map("vertical", LinearLayout.VERTICAL)
|
.map("vertical", LinearLayout.VERTICAL)
|
||||||
.map("horizontal", LinearLayout.HORIZONTAL);
|
.map("horizontal", LinearLayout.HORIZONTAL);
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
package com.stardust.autojs.core.ui.widget;
|
package com.stardust.autojs.core.ui.widget;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
|
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
|
||||||
import com.stardust.autojs.core.ui.inflater.ViewInflater;
|
|
||||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
|
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
import java.util.Map;
|
import com.stardust.autojs.workground.WrapContentLinearLayoutManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2018/3/28.
|
* Created by Stardust on 2018/3/28.
|
||||||
@@ -31,11 +28,18 @@ public class JsListView extends RecyclerView {
|
|||||||
void setDataSource(Object dataSource);
|
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 Node mItemTemplate;
|
||||||
private DynamicLayoutInflater mDynamicLayoutInflater;
|
private DynamicLayoutInflater mDynamicLayoutInflater;
|
||||||
private ScriptRuntime mScriptRuntime;
|
private ScriptRuntime mScriptRuntime;
|
||||||
private Object mDataSource;
|
private Object mDataSource;
|
||||||
private DataSourceAdapter mDataSourceAdapter;
|
private DataSourceAdapter mDataSourceAdapter;
|
||||||
|
private OnItemTouchListener mOnItemTouchListener;
|
||||||
|
|
||||||
public JsListView(Context context, ScriptRuntime scriptRuntime) {
|
public JsListView(Context context, ScriptRuntime scriptRuntime) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -45,7 +49,11 @@ public class JsListView extends RecyclerView {
|
|||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
setAdapter(new Adapter());
|
setAdapter(new Adapter());
|
||||||
setLayoutManager(new LinearLayoutManager(getContext()));
|
setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemTouchListener(OnItemTouchListener onItemTouchListener) {
|
||||||
|
mOnItemTouchListener = onItemTouchListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDataSourceAdapter(DataSourceAdapter dataSourceAdapter) {
|
public void setDataSourceAdapter(DataSourceAdapter dataSourceAdapter) {
|
||||||
@@ -73,6 +81,18 @@ public class JsListView extends RecyclerView {
|
|||||||
|
|
||||||
public ViewHolder(View itemView) {
|
public ViewHolder(View itemView) {
|
||||||
super(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
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
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
|
@Override
|
||||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||||
Object oldCtx = mScriptRuntime.ui.getBindingContext();
|
try {
|
||||||
mScriptRuntime.ui.setBindingContext(mDataSourceAdapter.getItem(mDataSource, position));
|
Object oldCtx = mScriptRuntime.ui.getBindingContext();
|
||||||
applyDynamicAttrs(mItemTemplate, holder.itemView, (ViewGroup) holder.itemView.getParent());
|
mScriptRuntime.ui.setBindingContext(mDataSourceAdapter.getItem(mDataSource, position));
|
||||||
mScriptRuntime.ui.setBindingContext(oldCtx);
|
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) {
|
private void applyDynamicAttrs(Node node, View itemView, ViewGroup parent) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.stardust.autojs.runtime;
|
package com.stardust.autojs.runtime;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.stardust.autojs.core.accessibility.UiCollection;
|
import com.stardust.autojs.core.accessibility.UiCollection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +21,6 @@ public class ScriptBridges {
|
|||||||
|
|
||||||
Object toString(Object obj);
|
Object toString(Object obj);
|
||||||
|
|
||||||
Object eval(Object context, String expr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bridges mBridges;
|
private Bridges mBridges;
|
||||||
@@ -50,9 +51,4 @@ public class ScriptBridges {
|
|||||||
return mBridges.toString(obj);
|
return mBridges.toString(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(Object context, String expr) {
|
|
||||||
checkBridges();
|
|
||||||
return mBridges.eval(context, expr);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ public class UI extends ProxyObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBindingContext(Object context) {
|
public void setBindingContext(Object context) {
|
||||||
mProperties.put("bindingContext", context);
|
if (context == null)
|
||||||
|
mProperties.remove("bindingContext");
|
||||||
|
else
|
||||||
|
mProperties.put("bindingContext", context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package android.workground;
|
package com.stardust.autojs.workground;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
Reference in New Issue
Block a user