sample: 自定义控件; fix: ActivityNotFoundException
This commit is contained in:
50
app/src/main/assets/sample/界面控件/自定义控件-带颜色按钮.js
Normal file
50
app/src/main/assets/sample/界面控件/自定义控件-带颜色按钮.js
Normal file
@@ -0,0 +1,50 @@
|
||||
"ui";
|
||||
|
||||
var ColoredButton = (function() {
|
||||
//继承至ui.Widget
|
||||
util.extends(ColoredButton, ui.Widget);
|
||||
|
||||
function ColoredButton() {
|
||||
//调用父类构造函数
|
||||
ui.Widget.call(this);
|
||||
//自定义属性color,定义按钮颜色
|
||||
this.defineAttr("color", (view, name, defaultGetter) => {
|
||||
return this._color;
|
||||
}, (view, name, value, defaultSetter) => {
|
||||
this._color = value;
|
||||
view.attr("backgroundTint", value);
|
||||
});
|
||||
//自定义属性onClick,定义被点击时执行的代码
|
||||
this.defineAttr("onClick", (view, name, defaultGetter) => {
|
||||
return this._onClick;
|
||||
}, (view, name, value, defaultSetter) => {
|
||||
this._onClick = value;
|
||||
});
|
||||
}
|
||||
ColoredButton.prototype.render = function() {
|
||||
return (
|
||||
<button textSize="16sp" style="Widget.AppCompat.Button.Colored" w="auto"/>
|
||||
);
|
||||
}
|
||||
ColoredButton.prototype.onViewCreated = function(view) {
|
||||
view.on("click", () => {
|
||||
if (this._onClick) {
|
||||
eval(this._onClick);
|
||||
}
|
||||
});
|
||||
}
|
||||
ui.registerWidget("colored-button", ColoredButton);
|
||||
return ColoredButton;
|
||||
})();
|
||||
|
||||
ui.layout(
|
||||
<vertical>
|
||||
<colored-button text="第一个按钮" color="#ff5722"/>
|
||||
<colored-button text="第二个按钮" onClick="hello()"/>
|
||||
</vertical>
|
||||
);
|
||||
|
||||
function hello() {
|
||||
alert("Hello ~");
|
||||
|
||||
}
|
||||
54
app/src/main/assets/sample/界面控件/自定义控件-配置勾选框.js
Normal file
54
app/src/main/assets/sample/界面控件/自定义控件-配置勾选框.js
Normal file
@@ -0,0 +1,54 @@
|
||||
"ui";
|
||||
|
||||
//这个自定义控件是一个勾选框checkbox,能够保存自己的勾选状态,在脚本重新启动时能恢复状态
|
||||
var PrefCheckBox = (function() {
|
||||
//继承至ui.Widget
|
||||
util.extends(PrefCheckBox, ui.Widget);
|
||||
|
||||
function PrefCheckBox() {
|
||||
//调用父类构造函数
|
||||
ui.Widget.call(this);
|
||||
//自定义属性key,定义在配置中保存时的key
|
||||
this.defineAttr("key");
|
||||
}
|
||||
PrefCheckBox.prototype.render = function() {
|
||||
return (
|
||||
<checkbox />
|
||||
);
|
||||
}
|
||||
PrefCheckBox.prototype.onViewCreated = function(view) {
|
||||
view.setChecked(PrefCheckBox.getPref().get(this.getKey(), false));
|
||||
view.on("check", (checked) => {
|
||||
PrefCheckBox.getPref().put(this.getKey(), checked);
|
||||
});
|
||||
}
|
||||
PrefCheckBox.prototype.getKey = function() {
|
||||
return this.key || view.attr("id").replace("@+id/", "");
|
||||
}
|
||||
PrefCheckBox.setPref = function(pref) {
|
||||
PrefCheckBox._pref = pref;
|
||||
}
|
||||
PrefCheckBox.getPref = function(){
|
||||
if(!PrefCheckBox._pref){
|
||||
PrefCheckBox._pref = storages.create("pref_pref");
|
||||
}
|
||||
return PrefCheckBox._pref;
|
||||
}
|
||||
ui.registerWidget("pref-checkbox", PrefCheckBox);
|
||||
return PrefCheckBox;
|
||||
})();
|
||||
|
||||
ui.layout(
|
||||
<vertical>
|
||||
<pref-checkbox id="perf1" text="配置1"/>
|
||||
<pref-checkbox id="perf2" text="配置2"/>
|
||||
<button id="btn" text="获取配置"/>
|
||||
</vertical>
|
||||
);
|
||||
|
||||
ui.btn.on("click", function(){
|
||||
toast("配置1为" + PrefCheckBox.getPref().get("perf1"));
|
||||
toast("配置2为" + PrefCheckBox.getPref().get("perf2"));
|
||||
});
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class TaskerScriptEditActivity extends BaseActivity {
|
||||
.putExtra(EXTRA_RUN_ENABLED, false)
|
||||
.putExtra(EXTRA_SAVE_ENABLED, false))
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Observers.consumer(),
|
||||
.subscribe(Observers.emptyConsumer(),
|
||||
ex -> {
|
||||
Toast.makeText(TaskerScriptEditActivity.this, ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
|
||||
@@ -101,7 +101,7 @@ public class AndroidClassIndices {
|
||||
.doOnNext(this::load)
|
||||
.subscribeOn(Schedulers.from(mSingleThreadExecutor))
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Observers.consumer(), t -> {
|
||||
.subscribe(Observers.emptyConsumer(), t -> {
|
||||
mLoadThrowable = t;
|
||||
t.printStackTrace();
|
||||
});
|
||||
|
||||
@@ -58,11 +58,11 @@ public class TimedTaskManager {
|
||||
return;
|
||||
if (task.isDisposable()) {
|
||||
mTimedTaskDatabase.delete(task)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);
|
||||
} else {
|
||||
task.setScheduled(false);
|
||||
mTimedTaskDatabase.update(task)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,13 +70,13 @@ public class TimedTaskManager {
|
||||
public void removeTask(TimedTask timedTask) {
|
||||
TimedTaskScheduler.cancel(mContext, timedTask);
|
||||
mTimedTaskDatabase.delete(timedTask)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public void addTask(TimedTask timedTask) {
|
||||
mTimedTaskDatabase.insert(timedTask)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);;
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);;
|
||||
TimedTaskScheduler.scheduleTaskIfNeeded(mContext, timedTask);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public class TimedTaskManager {
|
||||
public void notifyTaskScheduled(TimedTask timedTask) {
|
||||
timedTask.setScheduled(true);
|
||||
mTimedTaskDatabase.update(timedTask)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);
|
||||
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class TimedTaskManager {
|
||||
@SuppressLint("CheckResult")
|
||||
public void updateTask(TimedTask task) {
|
||||
mTimedTaskDatabase.update(task)
|
||||
.subscribe(Observers.consumer(), Throwable::printStackTrace);
|
||||
.subscribe(Observers.emptyConsumer(), Throwable::printStackTrace);
|
||||
TimedTaskScheduler.cancel(mContext, task);
|
||||
TimedTaskScheduler.scheduleTaskIfNeeded(mContext, task);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package org.autojs.autojs.tool;
|
||||
|
||||
import com.stardust.app.GlobalAppContext;
|
||||
|
||||
import org.autojs.autojs.model.explorer.ExplorerFileItem;
|
||||
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.functions.Consumer;
|
||||
|
||||
public class Observers {
|
||||
@@ -17,11 +21,36 @@ public class Observers {
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Consumer<T> consumer() {
|
||||
public static <T> Consumer<T> emptyConsumer() {
|
||||
return CONSUMER;
|
||||
}
|
||||
|
||||
public static Consumer<Throwable> toastMessage() {
|
||||
return TOAST_MESSAGE;
|
||||
}
|
||||
|
||||
public static <T> Observer<T> emptyObserver() {
|
||||
return new Observer<T>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(T t) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.io.InputStream;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.internal.functions.ObjectHelper;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
|
||||
@@ -267,17 +268,19 @@ public class ScriptOperations {
|
||||
}
|
||||
}
|
||||
|
||||
public Observable<Boolean> rename(final ExplorerFileItem item) {
|
||||
public Observable<ExplorerFileItem> rename(final ExplorerFileItem item) {
|
||||
final ScriptFile oldFile = new ScriptFile(item.getPath());
|
||||
String originalName = item.getName();
|
||||
return showNameInputDialog(originalName, new InputCallback(oldFile.isDirectory() ? null : PFiles.getExtension(item.getName()),
|
||||
originalName))
|
||||
.map(newName -> {
|
||||
ExplorerFileItem newItem = item.rename(newName);
|
||||
if (newItem != null) {
|
||||
notifyFileChanged(mCurrentDirectory, item, newItem);
|
||||
if (ObjectHelper.equals(newItem.toScriptFile(), item.toScriptFile())) {
|
||||
showMessage(R.string.error_cannot_rename);
|
||||
throw new IOException();
|
||||
}
|
||||
return newItem != null;
|
||||
notifyFileChanged(mCurrentDirectory, item, newItem);
|
||||
return newItem;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHo
|
||||
void setUpViews() {
|
||||
mEditorView.handleIntent(getIntent())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Observers.consumer(),
|
||||
.subscribe(Observers.emptyConsumer(),
|
||||
ex -> onLoadFileError(ex.getMessage()));
|
||||
mEditorMenu = new EditorMenu(mEditorView);
|
||||
setUpToolbar();
|
||||
|
||||
@@ -440,7 +440,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
public void saveFile() {
|
||||
save()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Observers.consumer(), e -> {
|
||||
.subscribe(Observers.emptyConsumer(), e -> {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
@@ -119,7 +119,6 @@ public class CodeEditText extends AppCompatEditText {
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
Log.v(LOG_TAG, "onDraw");
|
||||
mLogger.reset();
|
||||
if (mParentScrollView == null) {
|
||||
mParentScrollView = (HVScrollView) getParent();
|
||||
|
||||
@@ -31,8 +31,6 @@ import org.autojs.autojs.model.explorer.ExplorerProjectPage;
|
||||
import org.autojs.autojs.model.explorer.ExplorerSampleItem;
|
||||
import org.autojs.autojs.model.explorer.ExplorerSamplePage;
|
||||
import org.autojs.autojs.model.explorer.Explorers;
|
||||
import org.autojs.autojs.model.explorer.WorkspaceFileProvider;
|
||||
import org.autojs.autojs.model.sample.SampleFile;
|
||||
import org.autojs.autojs.model.script.ScriptFile;
|
||||
import org.autojs.autojs.model.script.Scripts;
|
||||
import org.autojs.autojs.tool.Observers;
|
||||
@@ -268,7 +266,7 @@ public class ExplorerView extends ThemeColorSwipeRefreshLayout implements SwipeR
|
||||
case R.id.rename:
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
.rename((ExplorerFileItem) mSelectedItem)
|
||||
.subscribe();
|
||||
.subscribe(Observers.emptyObserver());
|
||||
break;
|
||||
case R.id.delete:
|
||||
new ScriptOperations(getContext(), this, getCurrentPage())
|
||||
|
||||
@@ -279,7 +279,7 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
|
||||
.input("", host, (dialog, input) -> {
|
||||
Pref.saveServerAddress(input.toString());
|
||||
DevPluginService.getInstance().connectToServer(input.toString())
|
||||
.subscribe(Observers.consumer(), this::onConnectException);
|
||||
.subscribe(Observers.emptyConsumer(), this::onConnectException);
|
||||
})
|
||||
.neutralText(R.string.text_help)
|
||||
.onNeutral((dialog, which) -> {
|
||||
|
||||
@@ -317,7 +317,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
|
||||
.positiveText(R.string.text_install)
|
||||
.negativeText(R.string.cancel)
|
||||
.onPositive((dialog, which) ->
|
||||
IntentUtil.installApk(BuildActivity.this, outApk.getPath(), AppFileProvider.AUTHORITY)
|
||||
IntentUtil.installApkOrToast(BuildActivity.this, outApk.getPath(), AppFileProvider.AUTHORITY)
|
||||
)
|
||||
.show();
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public class UpdateInfoDialogBuilder extends MaterialDialog.Builder {
|
||||
final String path = new File(Pref.getScriptDirPath(), "AutoJs.apk").getPath();
|
||||
DownloadManager.getInstance().downloadWithProgress(getContext(), downloadUrl, path)
|
||||
.subscribeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(file -> IntentUtil.installApk(getContext(), file.getPath(), AppFileProvider.AUTHORITY),
|
||||
.subscribe(file -> IntentUtil.installApkOrToast(getContext(), file.getPath(), AppFileProvider.AUTHORITY),
|
||||
error -> {
|
||||
error.printStackTrace();
|
||||
Toast.makeText(getContext(), R.string.text_download_failed, Toast.LENGTH_SHORT).show();
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:hint="@string/text_class_or_package_name"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/keywords"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/text_class_or_package_name"/>
|
||||
android:layout_height="wrap_content"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
||||
@@ -423,4 +423,5 @@
|
||||
<string name="text_run_on_config_change">某些设置(屏幕方向,地区等)更改时</string>
|
||||
<string name="error_pattern_syntax">正则表达式错误</string>
|
||||
<string name="text_invalid_package_name">非法包名</string>
|
||||
<string name="error_cannot_rename">重命名失败</string>
|
||||
</resources>
|
||||
|
||||
@@ -3,17 +3,23 @@ module.exports = function(runtime, global){
|
||||
var floaty = {};
|
||||
|
||||
floaty.window = function(layout){
|
||||
if(typeof(layout) == 'xml'){
|
||||
layout = layout.toXMLString();
|
||||
if(typeof(xml) == 'xml'){
|
||||
xml = xml.toXMLString();
|
||||
}
|
||||
return wrap(runtime.floaty.window(layout));
|
||||
return wrap(runtime.floaty.window(function(context, parent){
|
||||
runtime.ui.layoutInflater.setContext(context);
|
||||
return ui.__inflate__(runtime.ui.layoutInflater.inflate(xml.toString(), parent, true));
|
||||
}));
|
||||
}
|
||||
|
||||
floaty.rawWindow = function(layout){
|
||||
if(typeof(layout) == 'xml'){
|
||||
layout = layout.toXMLString();
|
||||
if(typeof(xml) == 'xml'){
|
||||
xml = xml.toXMLString();
|
||||
}
|
||||
return wrap(runtime.floaty.rawWindow(layout));
|
||||
return wrap(runtime.floaty.rawWindow(function(context, parent){
|
||||
runtime.ui.layoutInflater.setContext(context);
|
||||
return ui.__inflate__(runtime.ui.layoutInflater.inflate(xml.toString(), parent, true));
|
||||
}));
|
||||
}
|
||||
|
||||
function wrap(window){
|
||||
|
||||
@@ -46,4 +46,30 @@ J.toJsArray = function(list, nullListToEmptyArray){
|
||||
return arr;
|
||||
}
|
||||
|
||||
J.objectToMap = function(obj){
|
||||
if(obj == null || obj === undefined){
|
||||
return null;
|
||||
}
|
||||
let map = new java.util.HashMap();
|
||||
for(let key in obj){
|
||||
if(obj.hasOwnProperty(key)){
|
||||
map.put(key, obj[key]);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
J.mapToObject = function(map){
|
||||
if(map == null || map === undefined){
|
||||
return null;
|
||||
}
|
||||
let iter = map.entrySet().iterator();
|
||||
let obj = {};
|
||||
while(iter.hasNext()){
|
||||
let entry = iter.next();
|
||||
obj[entry.key] = entry.value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
module.exports = J;
|
||||
@@ -6,27 +6,46 @@ module.exports = function (runtime, global) {
|
||||
var J = util.java;
|
||||
var ui = {};
|
||||
|
||||
ui.__widgets__ = {};
|
||||
|
||||
ui.__defineGetter__("emitter", ()=> activity ? activity.getEventEmitter() : null);
|
||||
|
||||
ui.layout = function (xml) {
|
||||
if(!activity){
|
||||
throw new Error("需要在ui模式下运行才能使用该函数");
|
||||
}
|
||||
if(typeof(xml) == 'xml'){
|
||||
xml = xml.toXMLString();
|
||||
}
|
||||
runtime.ui.layoutInflater.setContext(activity);
|
||||
var view = runtime.ui.layoutInflater.inflate(xml, activity.window.decorView, false);
|
||||
ui.setContentView(view);
|
||||
}
|
||||
|
||||
ui.inflate = function(xml, parent){
|
||||
ui.inflate = function(xml, parent, attachToParent){
|
||||
if(!activity){
|
||||
throw new Error("需要在ui模式下运行才能使用该函数");
|
||||
}
|
||||
if(typeof(xml) == 'xml'){
|
||||
xml = xml.toXMLString();
|
||||
}
|
||||
parent = parent || null;
|
||||
attachToParent = !!attachToParent;
|
||||
runtime.ui.layoutInflater.setContext(activity);
|
||||
return decorate(runtime.ui.layoutInflater.inflate(xml.toString(), parent));
|
||||
return runtime.ui.layoutInflater.inflate(xml.toString(), parent, attachToParent);
|
||||
}
|
||||
|
||||
ui.__inflate__ = function(ctx, xml, parent, attachToParent){
|
||||
if(typeof(xml) == 'xml'){
|
||||
xml = xml.toXMLString();
|
||||
}
|
||||
parent = parent || null;
|
||||
attachToParent = !!attachToParent;
|
||||
return runtime.ui.layoutInflater.inflate(ctx, xml.toString(), parent, attachToParent);
|
||||
}
|
||||
|
||||
ui.registerWidget = function(name, widget){
|
||||
if(typeof(widget) !== 'function'){
|
||||
throw new TypeError('widget should be a class-like function');
|
||||
}
|
||||
ui.__widgets__[name] = widget;
|
||||
}
|
||||
|
||||
ui.setContentView = function (view) {
|
||||
@@ -103,64 +122,96 @@ module.exports = function (runtime, global) {
|
||||
runtime.ui.bindingContext = global;
|
||||
var layoutInflater = runtime.ui.layoutInflater;
|
||||
layoutInflater.setLayoutInflaterDelegate({
|
||||
beforeConvertXml: function (xml) {
|
||||
beforeConvertXml: function (context, xml) {
|
||||
return null;
|
||||
},
|
||||
afterConvertXml: function (xml) {
|
||||
afterConvertXml: function (context, xml) {
|
||||
return xml;
|
||||
},
|
||||
afterInflation: function (result, xml, parent) {
|
||||
afterInflation: function (context, result, xml, parent) {
|
||||
return result;
|
||||
},
|
||||
beforeInflation: function (xml, parent) {
|
||||
beforeInflation: function (context, xml, parent) {
|
||||
return null;
|
||||
},
|
||||
beforeInflateView: function (node, parent, attachToParent) {
|
||||
beforeInflateView: function (context, node, parent, attachToParent) {
|
||||
return null;
|
||||
},
|
||||
afterInflateView: function (view, node, parent, attachToParent) {
|
||||
afterInflateView: function (context, view, node, parent, attachToParent) {
|
||||
return view;
|
||||
},
|
||||
beforeCreateView: function (node, viewName, attrs) {
|
||||
beforeCreateView: function (context, node, viewName, parent, attrs) {
|
||||
if(ui.__widgets__.hasOwnProperty(viewName)){
|
||||
let Widget = ui.__widgets__[viewName];
|
||||
let widget = new Widget();
|
||||
let ctx = layoutInflater.newInflateContext();
|
||||
ctx.put("widget", widget);
|
||||
let view = ui.__inflate__(ctx, widget.renderInternal(), parent, false);
|
||||
return view;
|
||||
};
|
||||
return null;
|
||||
},
|
||||
afterCreateView: function (view, node, viewName, attrs) {
|
||||
afterCreateView: function (context, view, node, viewName, parent, attrs) {
|
||||
if (view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsListView" ||
|
||||
view.getClass().getName() == "com.stardust.autojs.core.ui.widget.JsGridView") {
|
||||
initListView(view);
|
||||
}
|
||||
var widget = context.get("widget");
|
||||
if(widget != null){
|
||||
widget.view = view;
|
||||
let viewAttrs = com.stardust.autojs.core.ui.ViewExtras.getViewAttributes(view, layoutInflater.resourceParser);
|
||||
viewAttrs.setViewAttributeDelegate({
|
||||
has: function(name) {
|
||||
return widget.hasAttr(name);
|
||||
},
|
||||
get: function(view, name, getter){
|
||||
return widget.getAttr(view, name, getter);
|
||||
},
|
||||
set: function(view, name, value, setter) {
|
||||
widget.setAttr(view, name, value, setter);
|
||||
}
|
||||
});
|
||||
widget.notifyViewCreated(view);
|
||||
}
|
||||
return view;
|
||||
},
|
||||
beforeApplyAttributes: function (view, inflater, attrs, parent) {
|
||||
beforeApplyAttributes: function (context, view, inflater, attrs, parent) {
|
||||
return false;
|
||||
},
|
||||
afterApplyAttributes: function (view, inflater, attrs, parent) {
|
||||
|
||||
afterApplyAttributes: function (context, view, inflater, attrs, parent) {
|
||||
context.remove("widget");
|
||||
},
|
||||
beforeInflateChildren: function (inflater, node, parent) {
|
||||
beforeInflateChildren: function (context, inflater, node, parent) {
|
||||
return false;
|
||||
},
|
||||
afterInflateChildren: function (inflater, node, parent) {
|
||||
afterInflateChildren: function (context, inflater, node, parent) {
|
||||
|
||||
},
|
||||
afterApplyPendingAttributesOfChildren: function (inflater, view) {
|
||||
afterApplyPendingAttributesOfChildren: function (context, inflater, view) {
|
||||
|
||||
},
|
||||
beforeApplyPendingAttributesOfChildren: function (inflater, view) {
|
||||
beforeApplyPendingAttributesOfChildren: function (context, inflater, view) {
|
||||
return false;
|
||||
},
|
||||
beforeApplyAttribute: function (inflater, view, ns, attrName, value, parent, attrs) {
|
||||
beforeApplyAttribute: function (context, 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);
|
||||
let widget = context.get("widget");
|
||||
if(widget != null && widget.hasAttr(attrName)){
|
||||
widget.setAttr(view, attrName, value, (view, attrName, value)=>{
|
||||
inflater.setAttr(view, ns, attrName, value, parent, attrs);
|
||||
});
|
||||
} else {
|
||||
inflater.setAttr(view, ns, attrName, value, parent, attrs);
|
||||
}
|
||||
this.afterApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs);
|
||||
return true;
|
||||
},
|
||||
afterApplyAttribute: function (inflater, view, ns, attrName, value, parent, attrs) {
|
||||
afterApplyAttribute: function (context, inflater, view, ns, attrName, value, parent, attrs) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -229,6 +280,39 @@ module.exports = function (runtime, global) {
|
||||
}
|
||||
}
|
||||
|
||||
ui.Widget = (function(){
|
||||
function Widget(){
|
||||
this.__attrs__ = {};
|
||||
}
|
||||
Widget.prototype.renderInternal = function(){
|
||||
if(typeof(this.render) === 'function'){
|
||||
return this.render();
|
||||
}
|
||||
return (< />)
|
||||
};
|
||||
Widget.prototype.defineAttr = function(attrName, getter, setter){
|
||||
this.__attrs__[attrName] = {
|
||||
getter: getter,
|
||||
setter: setter
|
||||
};
|
||||
};
|
||||
Widget.prototype.hasAttr = function(attrName){
|
||||
return this.__attrs__.hasOwnProperty(attrName);
|
||||
};
|
||||
Widget.prototype.setAttr = function(view, attrName, value, setter){
|
||||
this.__attrs__[attrName].setter(view, attrName, value, setter);
|
||||
};
|
||||
Widget.prototype.getAttr = function(view, attrName, getter){
|
||||
return this.__attrs__[attrName].getter(view, attrName, getter);
|
||||
};
|
||||
Widget.prototype.notifyViewCreated = function(view){
|
||||
if(typeof(this.onViewCreated) == 'function'){
|
||||
this.onViewCreated(view);
|
||||
}
|
||||
};
|
||||
return Widget;
|
||||
})();
|
||||
|
||||
var proxy = runtime.ui;
|
||||
proxy.__proxy__ = {
|
||||
set: function (name, value) {
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var formatRegExp = /%[sdj%]/g;
|
||||
exports.extends = (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.java = require("__java_util__");
|
||||
exports.format = function(f) {
|
||||
if (!isString(f)) {
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.stardust.autojs.core.http;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -67,7 +69,6 @@ public class MutableOkHttp extends OkHttpClient {
|
||||
|
||||
|
||||
public void setTimeout(long timeout) {
|
||||
mTimeout = timeout;
|
||||
muteClient();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.stardust.autojs.core.ui.attribute;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface ViewAttributeDelegate {
|
||||
|
||||
interface ViewAttributeGetter {
|
||||
String get(String name);
|
||||
}
|
||||
|
||||
interface ViewAttributeSetter {
|
||||
void set(String name, String value);
|
||||
}
|
||||
|
||||
boolean has(String name);
|
||||
|
||||
String get(View view, String name, ViewAttributeGetter defaultGetter);
|
||||
|
||||
void set(View view, String name, String value, ViewAttributeSetter defaultSetter);
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import android.widget.CompoundButton;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.stardust.autojs.core.internal.Functions;
|
||||
import com.stardust.autojs.core.ui.inflater.ResourceParser;
|
||||
@@ -113,6 +114,7 @@ public class ViewAttributes {
|
||||
private Map<String, Attribute> mAttributes = new HashMap<>();
|
||||
private final Drawables mDrawables;
|
||||
private final View mView;
|
||||
private ViewAttributeDelegate mViewAttributeDelegate;
|
||||
|
||||
public ViewAttributes(ResourceParser resourceParser, View view) {
|
||||
mDrawables = resourceParser.getDrawables();
|
||||
@@ -120,6 +122,9 @@ public class ViewAttributes {
|
||||
init();
|
||||
}
|
||||
|
||||
public void setViewAttributeDelegate(ViewAttributeDelegate viewAttributeDelegate) {
|
||||
mViewAttributeDelegate = viewAttributeDelegate;
|
||||
}
|
||||
|
||||
public Drawables getDrawables() {
|
||||
return mDrawables;
|
||||
@@ -130,13 +135,41 @@ public class ViewAttributes {
|
||||
}
|
||||
|
||||
public boolean contains(String name) {
|
||||
return mAttributes.containsKey(name);
|
||||
return mAttributes.containsKey(name) ||
|
||||
(mViewAttributeDelegate != null && mViewAttributeDelegate.has(name));
|
||||
}
|
||||
|
||||
public Attribute get(String name) {
|
||||
if (mViewAttributeDelegate != null && mViewAttributeDelegate.has(name)) {
|
||||
return new Attribute() {
|
||||
@Override
|
||||
public String get() {
|
||||
return mViewAttributeDelegate.get(getView(), name, ViewAttributes.this::getAttrValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String value) {
|
||||
mViewAttributeDelegate.set(getView(), name, value, ViewAttributes.this::setAttrValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
return mAttributes.get(name);
|
||||
}
|
||||
|
||||
public String getAttrValue(String name) {
|
||||
Attribute attribute = mAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
return attribute.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAttrValue(String name, String value) {
|
||||
Attribute attribute = mAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
attribute.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void init() {
|
||||
@@ -248,9 +281,7 @@ public class ViewAttributes {
|
||||
}
|
||||
|
||||
protected void setElevation(int e) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mView.setElevation(e);
|
||||
}
|
||||
ViewCompat.setElevation(mView, e);
|
||||
}
|
||||
|
||||
protected void setScrollbars(String scrollbars) {
|
||||
@@ -472,15 +503,14 @@ public class ViewAttributes {
|
||||
}
|
||||
|
||||
protected void setBackgroundTint(int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mView.setBackgroundTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
ViewCompat.setBackgroundTintList(mView, ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
protected void setContextClickable(boolean clickable) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mView.setContextClickable(clickable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void setChecked(boolean checked) {
|
||||
|
||||
@@ -5,8 +5,6 @@ import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.InflateException;
|
||||
@@ -19,7 +17,6 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
@@ -150,86 +147,96 @@ public class DynamicLayoutInflater {
|
||||
}
|
||||
|
||||
public View inflate(String xml, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = mLayoutInflaterDelegate.beforeInflation(xml, parent);
|
||||
if (view != null)
|
||||
return view;
|
||||
xml = convertXml(xml);
|
||||
return mLayoutInflaterDelegate.afterInflation(doInflation(xml, parent, attachToParent), xml, parent);
|
||||
InflateContext context = newInflateContext();
|
||||
return inflate(context, xml, parent, attachToParent);
|
||||
}
|
||||
|
||||
protected View doInflation(String xml, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
public View inflate(InflateContext context, String xml, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = mLayoutInflaterDelegate.beforeInflation(context, xml, parent);
|
||||
if (view != null)
|
||||
return view;
|
||||
xml = convertXml(context, xml);
|
||||
return mLayoutInflaterDelegate.afterInflation(context, doInflation(context, xml, parent, attachToParent), xml, parent);
|
||||
}
|
||||
|
||||
public InflateContext newInflateContext(){
|
||||
return new InflateContext();
|
||||
}
|
||||
|
||||
|
||||
protected View doInflation(InflateContext context, String xml, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
try {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document document = db.parse(new ByteArrayInputStream(xml.getBytes()));
|
||||
return inflate(document.getDocumentElement(), parent, attachToParent);
|
||||
return inflate(context, document.getDocumentElement(), parent, attachToParent);
|
||||
} catch (Exception e) {
|
||||
throw new InflateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected String convertXml(String xml) {
|
||||
String str = mLayoutInflaterDelegate.beforeConvertXml(xml);
|
||||
protected String convertXml(InflateContext context, String xml) {
|
||||
String str = mLayoutInflaterDelegate.beforeConvertXml(context, xml);
|
||||
if (str != null)
|
||||
return str;
|
||||
try {
|
||||
return mLayoutInflaterDelegate.afterConvertXml(XmlConverter.convertToAndroidLayout(xml));
|
||||
return mLayoutInflaterDelegate.afterConvertXml(context, XmlConverter.convertToAndroidLayout(xml));
|
||||
} catch (Exception e) {
|
||||
throw new InflateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public View inflate(Node node, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = doInflation(node, parent, attachToParent);
|
||||
if (view != null && view instanceof ShouldCallOnFinishInflate) {
|
||||
public View inflate(InflateContext context, Node node, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = doInflation(context, node, parent, attachToParent);
|
||||
if (view instanceof ShouldCallOnFinishInflate) {
|
||||
((ShouldCallOnFinishInflate) view).onFinishDynamicInflate();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
protected View doInflation(Node node, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = mLayoutInflaterDelegate.beforeInflateView(node, parent, attachToParent);
|
||||
protected View doInflation(InflateContext context, Node node, @Nullable ViewGroup parent, boolean attachToParent) {
|
||||
View view = mLayoutInflaterDelegate.beforeInflateView(context, node, parent, attachToParent);
|
||||
if (view != null)
|
||||
return view;
|
||||
HashMap<String, String> attrs = getAttributesMap(node);
|
||||
view = doCreateView(node, node.getNodeName(), attrs);
|
||||
view = doCreateView(context, node, node.getNodeName(), parent, 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);
|
||||
ViewInflater<View> inflater = applyAttributes(context, view, attrs, parent);
|
||||
if (!(view instanceof ViewGroup) || !node.hasChildNodes()) {
|
||||
return view;
|
||||
}
|
||||
inflateChildren(inflater, node, (ViewGroup) view);
|
||||
inflateChildren(context, inflater, node, (ViewGroup) view);
|
||||
if (inflater instanceof ViewGroupInflater) {
|
||||
applyPendingAttributesOfChildren((ViewGroupInflater) inflater, (ViewGroup) view);
|
||||
applyPendingAttributesOfChildren(context, (ViewGroupInflater) inflater, (ViewGroup) view);
|
||||
}
|
||||
return mLayoutInflaterDelegate.afterInflateView(view, node, parent, attachToParent);
|
||||
return mLayoutInflaterDelegate.afterInflateView(context, view, node, parent, attachToParent);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void applyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
|
||||
if (mLayoutInflaterDelegate.beforeApplyPendingAttributesOfChildren(inflater, view)) {
|
||||
protected void applyPendingAttributesOfChildren(InflateContext context, ViewGroupInflater inflater, ViewGroup view) {
|
||||
if (mLayoutInflaterDelegate.beforeApplyPendingAttributesOfChildren(context, inflater, view)) {
|
||||
return;
|
||||
}
|
||||
inflater.applyPendingAttributesOfChildren(view);
|
||||
mLayoutInflaterDelegate.afterApplyPendingAttributesOfChildren(inflater, view);
|
||||
mLayoutInflaterDelegate.afterApplyPendingAttributesOfChildren(context, inflater, view);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ViewInflater<View> applyAttributes(View view, HashMap<String, String> attrs, @Nullable ViewGroup parent) {
|
||||
public ViewInflater<View> applyAttributes(InflateContext context, View view, HashMap<String, String> attrs, @Nullable ViewGroup parent) {
|
||||
ViewInflater<View> inflater = (ViewInflater<View>) getViewInflater(view);
|
||||
if (mLayoutInflaterDelegate.beforeApplyAttributes(view, inflater, attrs, parent)) {
|
||||
if (mLayoutInflaterDelegate.beforeApplyAttributes(context, view, inflater, attrs, parent)) {
|
||||
return inflater;
|
||||
}
|
||||
applyAttributes(view, inflater, attrs, parent);
|
||||
mLayoutInflaterDelegate.afterApplyAttributes(view, inflater, attrs, parent);
|
||||
applyAttributes(context, view, inflater, attrs, parent);
|
||||
mLayoutInflaterDelegate.afterApplyAttributes(context, view, inflater, attrs, parent);
|
||||
return inflater;
|
||||
}
|
||||
|
||||
@@ -244,31 +251,31 @@ public class DynamicLayoutInflater {
|
||||
return setter;
|
||||
}
|
||||
|
||||
protected void inflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
if (mLayoutInflaterDelegate.beforeInflateChildren(inflater, node, parent)) {
|
||||
protected void inflateChildren(InflateContext context, ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
if (mLayoutInflaterDelegate.beforeInflateChildren(context, inflater, node, parent)) {
|
||||
return;
|
||||
}
|
||||
if (inflater.inflateChildren(this, node, parent)) {
|
||||
return;
|
||||
}
|
||||
inflateChildren(node, parent);
|
||||
mLayoutInflaterDelegate.afterInflateChildren(inflater, node, parent);
|
||||
inflateChildren(context, node, parent);
|
||||
mLayoutInflaterDelegate.afterInflateChildren(context, inflater, node, parent);
|
||||
}
|
||||
|
||||
public void inflateChildren(Node node, ViewGroup parent) {
|
||||
public void inflateChildren(InflateContext context, 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, true);
|
||||
inflate(context, currentNode, parent, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected View doCreateView(Node node, String viewName, HashMap<String, String> attrs) {
|
||||
View view = mLayoutInflaterDelegate.beforeCreateView(node, viewName, attrs);
|
||||
protected View doCreateView(InflateContext context, Node node, String viewName, ViewGroup parent, HashMap<String, String> attrs) {
|
||||
View view = mLayoutInflaterDelegate.beforeCreateView(context, node, viewName, parent, attrs);
|
||||
if (view != null)
|
||||
return view;
|
||||
return mLayoutInflaterDelegate.afterCreateView(createViewForName(viewName, attrs), node, viewName, attrs);
|
||||
return mLayoutInflaterDelegate.afterCreateView(context, createViewForName(viewName, attrs), node, viewName, parent, attrs);
|
||||
}
|
||||
|
||||
public View createViewForName(String name, HashMap<String, String> attrs) {
|
||||
@@ -311,14 +318,14 @@ public class DynamicLayoutInflater {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void applyAttributes(View view, ViewInflater<View> setter, Map<String, String> attrs, @Nullable ViewGroup parent) {
|
||||
protected void applyAttributes(InflateContext context, 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) {
|
||||
applyAttribute(setter, view, null, attr[0], entry.getValue(), parent, attrs);
|
||||
applyAttribute(context, setter, view, null, attr[0], entry.getValue(), parent, attrs);
|
||||
} else if (attr.length == 2) {
|
||||
applyAttribute(setter, view, attr[0], attr[1], entry.getValue(), parent, attrs);
|
||||
applyAttribute(context, setter, view, attr[0], attr[1], entry.getValue(), parent, attrs);
|
||||
} else {
|
||||
throw new InflateException("illegal attr name: " + entry.getKey());
|
||||
}
|
||||
@@ -330,8 +337,8 @@ 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)) {
|
||||
protected void applyAttribute(InflateContext context, ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
|
||||
if (mLayoutInflaterDelegate.beforeApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs)) {
|
||||
return;
|
||||
}
|
||||
boolean isDynamic = isDynamicValue(value);
|
||||
@@ -340,7 +347,7 @@ public class DynamicLayoutInflater {
|
||||
return;
|
||||
}
|
||||
inflater.setAttr(view, ns, attrName, value, parent, attrs);
|
||||
mLayoutInflaterDelegate.afterApplyAttribute(inflater, view, ns, attrName, value, parent, attrs);
|
||||
mLayoutInflaterDelegate.afterApplyAttribute(context, inflater, view, ns, attrName, value, parent, attrs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.stardust.autojs.core.ui.inflater;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class InflateContext {
|
||||
|
||||
private HashMap<String, Object> mProperties;
|
||||
|
||||
public void put(String key, Object value) {
|
||||
if (mProperties == null) {
|
||||
mProperties = new HashMap<>();
|
||||
}
|
||||
mProperties.put(key, value);
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
if(mProperties == null)
|
||||
return null;
|
||||
return mProperties.get(key);
|
||||
}
|
||||
|
||||
|
||||
public Object remove(String key){
|
||||
if(mProperties == null)
|
||||
return null;
|
||||
return mProperties.remove(key);
|
||||
}
|
||||
|
||||
public boolean has(String key) {
|
||||
return mProperties.containsKey(key);
|
||||
}
|
||||
}
|
||||
@@ -18,118 +18,118 @@ public interface LayoutInflaterDelegate {
|
||||
|
||||
LayoutInflaterDelegate NO_OP = new NoOp();
|
||||
|
||||
View beforeInflation(String xml, ViewGroup parent);
|
||||
View beforeInflation(InflateContext inflateContext, String xml, ViewGroup parent);
|
||||
|
||||
View afterInflation(View doInflation, String xml, ViewGroup parent);
|
||||
View afterInflation(InflateContext inflateContext, View doInflation, String xml, ViewGroup parent);
|
||||
|
||||
String beforeConvertXml(String xml);
|
||||
String beforeConvertXml(InflateContext inflateContext, String xml);
|
||||
|
||||
String afterConvertXml(String xml);
|
||||
String afterConvertXml(InflateContext inflateContext, String xml);
|
||||
|
||||
View beforeInflateView(Node node, ViewGroup parent, boolean attachToParent);
|
||||
View beforeInflateView(InflateContext inflateContext, Node node, ViewGroup parent, boolean attachToParent);
|
||||
|
||||
View afterInflateView(View view, Node node, ViewGroup parent, boolean attachToParent);
|
||||
View afterInflateView(InflateContext inflateContext, View view, Node node, ViewGroup parent, boolean attachToParent);
|
||||
|
||||
View beforeCreateView(Node node, String viewName, HashMap<String, String> attrs);
|
||||
View beforeCreateView(InflateContext inflateContext, Node node, String viewName, ViewGroup parent, HashMap<String, String> attrs);
|
||||
|
||||
View afterCreateView(View view, Node node, String viewName, HashMap<String, String> attrs);
|
||||
View afterCreateView(InflateContext inflateContext, View view, Node node, String viewName, ViewGroup parent, HashMap<String, String> attrs);
|
||||
|
||||
boolean beforeApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
|
||||
boolean beforeApplyAttributes(InflateContext inflateContext, View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
|
||||
|
||||
void afterApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
|
||||
void afterApplyAttributes(InflateContext inflateContext, View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent);
|
||||
|
||||
boolean beforeInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent);
|
||||
boolean beforeInflateChildren(InflateContext inflateContext, ViewInflater<View> inflater, Node node, ViewGroup parent);
|
||||
|
||||
void afterInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent);
|
||||
void afterInflateChildren(InflateContext inflateContext, ViewInflater<View> inflater, Node node, ViewGroup parent);
|
||||
|
||||
void afterApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view);
|
||||
void afterApplyPendingAttributesOfChildren(InflateContext inflateContext, ViewGroupInflater inflater, ViewGroup view);
|
||||
|
||||
boolean beforeApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view);
|
||||
boolean beforeApplyPendingAttributesOfChildren(InflateContext inflateContext, ViewGroupInflater inflater, ViewGroup view);
|
||||
|
||||
boolean beforeApplyAttribute(ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs);
|
||||
boolean beforeApplyAttribute(InflateContext inflateContext, 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);
|
||||
void afterApplyAttribute(InflateContext inflateContext, 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) {
|
||||
public String beforeConvertXml(InflateContext inflateContext, String xml) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String afterConvertXml(String xml) {
|
||||
public String afterConvertXml(InflateContext inflateContext, String xml) {
|
||||
return xml;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View afterInflation(View result, String xml, ViewGroup parent) {
|
||||
public View afterInflation(InflateContext inflateContext, View result, String xml, ViewGroup parent) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View beforeInflation(String xml, ViewGroup parent) {
|
||||
public View beforeInflation(InflateContext inflateContext, String xml, ViewGroup parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View beforeInflateView(Node node, ViewGroup parent, boolean attachToParent) {
|
||||
public View beforeInflateView(InflateContext inflateContext, Node node, ViewGroup parent, boolean attachToParent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View afterInflateView(View view, Node node, ViewGroup parent, boolean attachToParent) {
|
||||
public View afterInflateView(InflateContext inflateContext, View view, Node node, ViewGroup parent, boolean attachToParent) {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View beforeCreateView(Node node, String viewName, HashMap<String, String> attrs) {
|
||||
public View beforeCreateView(InflateContext inflateContext, Node node, String viewName, ViewGroup parent, HashMap<String, String> attrs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View afterCreateView(View view, Node node, String viewName, HashMap<String, String> attrs) {
|
||||
public View afterCreateView(InflateContext inflateContext, View view, Node node, String viewName, ViewGroup parent, HashMap<String, String> attrs) {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeApplyAttributes(View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent) {
|
||||
public boolean beforeApplyAttributes(InflateContext inflateContext, 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) {
|
||||
public void afterApplyAttributes(InflateContext inflateContext, View view, ViewInflater<View> inflater, HashMap<String, String> attrs, ViewGroup parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
public boolean beforeInflateChildren(InflateContext inflateContext, ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterInflateChildren(ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
public void afterInflateChildren(InflateContext inflateContext, ViewInflater<View> inflater, Node node, ViewGroup parent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
|
||||
public void afterApplyPendingAttributesOfChildren(InflateContext inflateContext, ViewGroupInflater inflater, ViewGroup view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeApplyPendingAttributesOfChildren(ViewGroupInflater inflater, ViewGroup view) {
|
||||
public boolean beforeApplyPendingAttributesOfChildren(InflateContext inflateContext, 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) {
|
||||
public boolean beforeApplyAttribute(InflateContext inflateContext, 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) {
|
||||
public void afterApplyAttribute(InflateContext inflateContext, ViewInflater<View> inflater, View view, String ns, String attrName, String value, ViewGroup parent, Map<String, String> attrs) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
|
||||
ViewAttributes viewAttributes = ViewExtras.getViewAttributes(view, getResourceParser());
|
||||
ViewAttributes.Attribute attribute = viewAttributes.get(attr);
|
||||
if (attribute != null) {
|
||||
Log.d(LOG_TAG, "setAttr use ViewAttributes: attr = " + attr);
|
||||
attribute.set(value);
|
||||
return true;
|
||||
}
|
||||
@@ -284,6 +285,7 @@ public class BaseViewInflater<V extends View> implements ViewInflater<V> {
|
||||
case "paddingBottom":
|
||||
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), Dimensions.parseToIntPixel(value, view));
|
||||
break;
|
||||
case "bg":
|
||||
case "background":
|
||||
getDrawables().setupWithViewBackground(view, value);
|
||||
break;
|
||||
|
||||
@@ -346,6 +346,7 @@ public class TextViewInflater<V extends TextView> extends BaseViewInflater<V> {
|
||||
case "text":
|
||||
view.setText(Strings.parse(view, value));
|
||||
break;
|
||||
case "color":
|
||||
case "textColor":
|
||||
view.setTextColor(Colors.parse(view.getContext(), value));
|
||||
break;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.stardust.autojs.core.ui.nativeview;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.stardust.autojs.R;
|
||||
import com.stardust.autojs.core.ui.JsViewHelper;
|
||||
import com.stardust.autojs.core.ui.ViewExtras;
|
||||
import com.stardust.autojs.core.ui.attribute.ViewAttributes;
|
||||
@@ -47,7 +48,7 @@ public class NativeView extends NativeJavaObjectWithPrototype {
|
||||
super(scope, view, staticType);
|
||||
mViewAttributes = ViewExtras.getViewAttributes(view, runtime.ui.getResourceParser());
|
||||
mView = view;
|
||||
mViewPrototype = new ViewPrototype(mView, scope, runtime);
|
||||
mViewPrototype = new ViewPrototype(mView, mViewAttributes, scope, runtime);
|
||||
prototype = new NativeJavaObject(scope, mViewPrototype, mViewPrototype.getClass());
|
||||
}
|
||||
|
||||
@@ -59,25 +60,8 @@ public class NativeView extends NativeJavaObjectWithPrototype {
|
||||
return super.has(name, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String name, Scriptable start, Object value) {
|
||||
if (value != null && (value instanceof CharSequence ||
|
||||
value.getClass().getName().equals("org.mozilla.javascript.NativeString"))) {
|
||||
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
attribute.set(ScriptRuntime.toString(value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.put(name, start, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String name, Scriptable start) {
|
||||
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
return attribute.get();
|
||||
}
|
||||
if (super.has(name, start)) {
|
||||
return super.get(name, start);
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.widget.CompoundButton;
|
||||
|
||||
import com.stardust.autojs.core.eventloop.EventEmitter;
|
||||
import com.stardust.autojs.core.ui.BaseEvent;
|
||||
import com.stardust.autojs.core.ui.attribute.ViewAttributes;
|
||||
import com.stardust.autojs.core.ui.widget.JsListView;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
|
||||
@@ -20,13 +21,34 @@ public class ViewPrototype {
|
||||
private final View mView;
|
||||
private final HashSet<String> mRegisteredEvents = new HashSet<>();
|
||||
private final Scriptable mScope;
|
||||
private final ViewAttributes mViewAttributes;
|
||||
|
||||
public ViewPrototype(View view, Scriptable scope, ScriptRuntime runtime) {
|
||||
public ViewPrototype(View view, ViewAttributes viewAttributes, Scriptable scope, ScriptRuntime runtime) {
|
||||
mView = view;
|
||||
mViewAttributes = viewAttributes;
|
||||
mEventEmitter = runtime.events.emitter();
|
||||
mScope = scope;
|
||||
}
|
||||
|
||||
public ViewAttributes getViewAttributes() {
|
||||
return mViewAttributes;
|
||||
}
|
||||
|
||||
public Object attr(String name) {
|
||||
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
return attribute.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void attr(String name, Object value) {
|
||||
ViewAttributes.Attribute attribute = mViewAttributes.get(name);
|
||||
if (attribute != null) {
|
||||
attribute.set(org.mozilla.javascript.ScriptRuntime.toString(value));
|
||||
}
|
||||
}
|
||||
|
||||
public void click() {
|
||||
mView.performClick();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Button;
|
||||
|
||||
@@ -23,6 +25,7 @@ public class JsButton extends Button {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public JsButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.stardust.autojs.R;
|
||||
import com.stardust.autojs.core.ui.ViewExtras;
|
||||
import com.stardust.autojs.core.ui.inflater.DynamicLayoutInflater;
|
||||
import com.stardust.autojs.core.ui.nativeview.NativeView;
|
||||
import com.stardust.autojs.core.ui.nativeview.ViewPrototype;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
|
||||
import org.mozilla.javascript.NativeJavaObject;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
@@ -143,7 +135,7 @@ public class JsListView extends RecyclerView {
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
try {
|
||||
mDynamicLayoutInflater.setInflateFlags(DynamicLayoutInflater.FLAG_IGNORES_DYNAMIC_ATTRS);
|
||||
return new ViewHolder(mDynamicLayoutInflater.inflate(mItemTemplate, parent, false));
|
||||
return new ViewHolder(mDynamicLayoutInflater.inflate(mDynamicLayoutInflater.newInflateContext(), mItemTemplate, parent, false));
|
||||
} catch (Exception e) {
|
||||
mScriptRuntime.exit(e);
|
||||
return new ViewHolder(new View(parent.getContext()));
|
||||
@@ -170,7 +162,7 @@ public class JsListView extends RecyclerView {
|
||||
}
|
||||
|
||||
private void applyDynamicAttrs(Node node, View itemView, ViewGroup parent) {
|
||||
mDynamicLayoutInflater.applyAttributes(itemView, mDynamicLayoutInflater.getAttributesMap(node), parent);
|
||||
mDynamicLayoutInflater.applyAttributes(mDynamicLayoutInflater.newInflateContext(), itemView, mDynamicLayoutInflater.getAttributesMap(node), parent);
|
||||
if (!(itemView instanceof ViewGroup))
|
||||
return;
|
||||
ViewGroup viewGroup = (ViewGroup) itemView;
|
||||
|
||||
@@ -100,11 +100,7 @@ public class XmlConverter {
|
||||
.handler("paddingRight", new AttributeHandler.DimenHandler("paddingRight"))
|
||||
.handler("paddingTop", new AttributeHandler.DimenHandler("paddingTop"))
|
||||
.handler("paddingBottom", new AttributeHandler.DimenHandler("paddingBottom"))
|
||||
.defaultHandler(new AttributeHandler.MappedAttributeHandler()
|
||||
.mapName("align", "layout_gravity")
|
||||
.mapName("bg", "background")
|
||||
.mapName("color", "textColor")
|
||||
);
|
||||
.defaultHandler(new AttributeHandler.MappedAttributeHandler());
|
||||
|
||||
public static String convertToAndroidLayout(String xml) throws IOException, SAXException, ParserConfigurationException {
|
||||
return convertToAndroidLayout(new InputSource(new StringReader(xml)));
|
||||
|
||||
@@ -454,7 +454,7 @@ public class ScriptRuntime {
|
||||
PrintWriter writer = new PrintWriter(stringWriter);
|
||||
e.printStackTrace(writer);
|
||||
writer.close();
|
||||
BufferedReader bufferedReader = new BufferedReader(new StringReader(writer.toString()));
|
||||
BufferedReader bufferedReader = new BufferedReader(new StringReader(stringWriter.toString()));
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
scriptTrace.append("\n").append(line);
|
||||
|
||||
@@ -40,13 +40,13 @@ public class Floaty {
|
||||
mLayoutInflater = ui.getLayoutInflater();
|
||||
}
|
||||
|
||||
public JsResizableWindow window(String xml) {
|
||||
public JsResizableWindow window(BaseResizableFloatyWindow.ViewSupplier supplier) {
|
||||
try {
|
||||
FloatingPermission.waitForPermissionGranted(mContext);
|
||||
} catch (InterruptedException e) {
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
JsResizableWindow window = new JsResizableWindow((context, parent) -> mLayoutInflater.inflate(xml, parent));
|
||||
JsResizableWindow window = new JsResizableWindow(supplier);
|
||||
addWindow(window);
|
||||
return window;
|
||||
}
|
||||
@@ -63,13 +63,13 @@ public class Floaty {
|
||||
return window;
|
||||
}
|
||||
|
||||
public JsRawWindow rawWindow(String xml) {
|
||||
public JsRawWindow rawWindow(RawWindow.RawFloaty floaty) {
|
||||
try {
|
||||
FloatingPermission.waitForPermissionGranted(mContext);
|
||||
} catch (InterruptedException e) {
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
JsRawWindow window = new JsRawWindow((context, parent) -> mLayoutInflater.inflate(xml, parent));
|
||||
JsRawWindow window = new JsRawWindow(floaty);
|
||||
addWindow(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@ package com.stardust.autojs.script;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.autojs.rhino.TokenStream;
|
||||
import com.stardust.util.MapBuilder;
|
||||
|
||||
import org.mozilla.javascript.Token;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
@@ -63,13 +66,17 @@ public abstract class JavaScriptSource extends ScriptSource {
|
||||
}
|
||||
|
||||
private int parseExecutionMode(String script) {
|
||||
if (script == null || script.length() == 0 || script.charAt(0) != '"')
|
||||
if (script == null || script.length() == 0)
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2);
|
||||
if (i == -1)
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
String modeString = script.substring(1, i);
|
||||
return parseExecutionMode(modeString.split(" "));
|
||||
if(script.charAt(0) == '"'){
|
||||
int i = script.lastIndexOf("\";", EXECUTION_MODE_STRING_MAX_LENGTH + 2);
|
||||
if (i >= 0){
|
||||
String modeString = script.substring(1, i);
|
||||
return parseExecutionMode(modeString.split(" "));
|
||||
}
|
||||
}
|
||||
return EXECUTION_MODE_NORMAL;
|
||||
|
||||
}
|
||||
|
||||
private int parseExecutionMode(String[] modeStrings) {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PFile extends File {
|
||||
if (renameTo(newFile)) {
|
||||
return newFile;
|
||||
} else {
|
||||
return null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@ import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.R;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -35,20 +38,26 @@ public class IntentUtil {
|
||||
}
|
||||
|
||||
|
||||
public static void sendMailTo(Context context, String sendTo, @Nullable String title, @Nullable String content) {
|
||||
Uri uri = Uri.parse("mailto:" + sendTo);
|
||||
String[] email = {sendTo};
|
||||
Intent intent = new Intent(Intent.ACTION_SENDTO, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(Intent.EXTRA_CC, email);
|
||||
if (title != null)
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, title);
|
||||
if (content != null)
|
||||
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||
context.startActivity(Intent.createChooser(intent, ""));
|
||||
public static boolean sendMailTo(Context context, String sendTo, @Nullable String title, @Nullable String content) {
|
||||
try {
|
||||
Uri uri = Uri.parse("mailto:" + sendTo);
|
||||
String[] email = {sendTo};
|
||||
Intent intent = new Intent(Intent.ACTION_SENDTO, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(Intent.EXTRA_CC, email);
|
||||
if (title != null)
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, title);
|
||||
if (content != null)
|
||||
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||
context.startActivity(Intent.createChooser(intent, ""));
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendMailTo(Context context, String sendTo) {
|
||||
sendMailTo(context, sendTo, null, null);
|
||||
public static boolean sendMailTo(Context context, String sendTo) {
|
||||
return sendMailTo(context, sendTo, null, null);
|
||||
}
|
||||
|
||||
public static boolean browse(Context context, String link) {
|
||||
@@ -62,10 +71,16 @@ public class IntentUtil {
|
||||
|
||||
}
|
||||
|
||||
public static void shareText(Context context, String text) {
|
||||
context.startActivity(new Intent(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_TEXT, text)
|
||||
.setType("text/plain"));
|
||||
public static boolean shareText(Context context, String text) {
|
||||
try {
|
||||
context.startActivity(new Intent(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_TEXT, text)
|
||||
.setType("text/plain"));
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean goToAppDetailSettings(Context context, String packageName) {
|
||||
@@ -85,7 +100,7 @@ public class IntentUtil {
|
||||
return goToAppDetailSettings(context, context.getPackageName());
|
||||
}
|
||||
|
||||
public static void installApk(Context context, String path, String fileProviderAuthority) {
|
||||
public static void installApk(Context context, String path, String fileProviderAuthority) throws ActivityNotFoundException {
|
||||
Uri uri = getUriOfFile(context, path, fileProviderAuthority);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(uri, "application/vnd.android.package-archive");
|
||||
@@ -95,9 +110,18 @@ public class IntentUtil {
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void viewFile(Context context, String path, String fileProviderAuthority) {
|
||||
public static void installApkOrToast(Context context, String path, String fileProviderAuthority) {
|
||||
try {
|
||||
installApk(context, path, fileProviderAuthority);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(context, R.string.error_activity_not_found_for_apk_installing, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean viewFile(Context context, String path, String fileProviderAuthority) {
|
||||
String mimeType = MimeTypes.fromFileOr(path, "*/*");
|
||||
viewFile(context, path, mimeType, fileProviderAuthority);
|
||||
return viewFile(context, path, mimeType, fileProviderAuthority);
|
||||
}
|
||||
|
||||
public static Uri getUriOfFile(Context context, String path, String fileProviderAuthority) {
|
||||
@@ -110,22 +134,34 @@ public class IntentUtil {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static void viewFile(Context context, String path, String mimeType, String fileProviderAuthority) {
|
||||
Uri uri = getUriOfFile(context, path, fileProviderAuthority);
|
||||
context.startActivity(new Intent(Intent.ACTION_VIEW)
|
||||
.setDataAndType(uri, mimeType)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
|
||||
public static boolean viewFile(Context context, String path, String mimeType, String fileProviderAuthority) {
|
||||
try {
|
||||
Uri uri = getUriOfFile(context, path, fileProviderAuthority);
|
||||
context.startActivity(new Intent(Intent.ACTION_VIEW)
|
||||
.setDataAndType(uri, mimeType)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void editFile(Context context, String path, String fileProviderAuthority) {
|
||||
String mimeType = MimeTypes.fromFileOr(path, "*/*");
|
||||
Uri uri = getUriOfFile(context, path, fileProviderAuthority);
|
||||
context.startActivity(new Intent(Intent.ACTION_EDIT)
|
||||
.setDataAndType(uri, mimeType)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
|
||||
public static boolean editFile(Context context, String path, String fileProviderAuthority) {
|
||||
try {
|
||||
String mimeType = MimeTypes.fromFileOr(path, "*/*");
|
||||
Uri uri = getUriOfFile(context, path, fileProviderAuthority);
|
||||
context.startActivity(new Intent(Intent.ACTION_EDIT)
|
||||
.setDataAndType(uri, mimeType)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">common</string>
|
||||
<string name="text_no_floating_window_permission">没有悬浮窗权限</string>
|
||||
<string name="error_activity_not_found_for_apk_installing">找不到安装apk的应用</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user