angular ionic3 中的动画在收到自定义 cordova 插件后停止工作 android 对按钮按下的响应
angular animation in ionic3 stop working after receiving custom cordova plugin for android response to button press
我正在开发与 Ionic 一起使用的自定义 cordova 插件(Android 目前)。该插件使用以下代码向 WebView 添加侦听器:
this.callbackContext = callbackContext;//store this for later
this.webView.getView().setOnKeyListener(this);//add listener
PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); // send no result cause the result will be sent by the listener
pluginResult.setKeepCallback(true);
this.callbackContext.sendPluginResult(pluginResult);
然后我用这种方式覆盖监听器:
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
JSONObject result = new JSONObject();
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
{
try {
result.put("button", "button pressed");
} catch (JSONException err) {
}
}
PluginResult pr = new PluginResult(PluginResult.Status.OK, result);
pr.setKeepCallback(keepCallback);
this.callbackContext.sendPluginResult(pr);
return false;
}
return true;
}
在 Ionic 方面,我可以看到插件正在正确发回结果,但它似乎添加了一些奇怪的行为:当从 ionic 接收到事件时,我的代码需要启动动画(angular 动画),动画开始但没有完成。好像卡住了。如果我在收到事件后以任何方式与 ui 交互(例如,如果我只是点击屏幕,一切都会重新开始,)应用程序会再次开始响应
如果我以其他方式触发动画,动画效果会很好。
动画是这样制作的:
@Component({
...
animations: [
trigger('buttonAnimation', [
state('normal', style({
'transform': 'scale(1.0)'
})),
state('big', style({
'transform': 'scale(1.2)',
})),
transition('* => *', animate('.1s ease'))
]),
]
})
更新:
我是这样在模板文件中应用动画的
<button>
<i (click)="onButtonPressed()" [@buttonAnimation]="buttonState" (@buttonAnimation.done)="onAnimationEnd()"></i>
</button>
来自cordova插件的回调通过设置变量触发动画
enter code here
this.buttonState = 'big';
然后动画重新初始化
onAnimationEnd() {
this.buttonState = 'normal'
}
cordova插件是这样使用的,启动动画:
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
}, err => {
});
解决方案更新
我使用 yazantahhan 提出的解决方案解决了这个问题。我只需要在回调内部调用 ngZone,因为我需要在事件到达后触发更改。
cordova.plugins.buttonListener.listenButtonClick(data => {
this.ngZone.run(() => {
do stuff;
});
});
很可能您需要在 ngZone 中强制执行 detectChanges,或者 运行 它。
constructor(private ref: ChangeDetectorRef){}
ngOnInit() {
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
this.ref.detectChanges();
}, err => { });
}
或者使用 ngZone:
constructor(private ngZone: NgZone){}
ngOnInit() {
this.ngZone.run(() => {
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
}, err => { });
});
}
我正在开发与 Ionic 一起使用的自定义 cordova 插件(Android 目前)。该插件使用以下代码向 WebView 添加侦听器:
this.callbackContext = callbackContext;//store this for later
this.webView.getView().setOnKeyListener(this);//add listener
PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); // send no result cause the result will be sent by the listener
pluginResult.setKeepCallback(true);
this.callbackContext.sendPluginResult(pluginResult);
然后我用这种方式覆盖监听器:
@Override
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
JSONObject result = new JSONObject();
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
{
try {
result.put("button", "button pressed");
} catch (JSONException err) {
}
}
PluginResult pr = new PluginResult(PluginResult.Status.OK, result);
pr.setKeepCallback(keepCallback);
this.callbackContext.sendPluginResult(pr);
return false;
}
return true;
}
在 Ionic 方面,我可以看到插件正在正确发回结果,但它似乎添加了一些奇怪的行为:当从 ionic 接收到事件时,我的代码需要启动动画(angular 动画),动画开始但没有完成。好像卡住了。如果我在收到事件后以任何方式与 ui 交互(例如,如果我只是点击屏幕,一切都会重新开始,)应用程序会再次开始响应 如果我以其他方式触发动画,动画效果会很好。
动画是这样制作的:
@Component({
...
animations: [
trigger('buttonAnimation', [
state('normal', style({
'transform': 'scale(1.0)'
})),
state('big', style({
'transform': 'scale(1.2)',
})),
transition('* => *', animate('.1s ease'))
]),
]
})
更新:
我是这样在模板文件中应用动画的
<button>
<i (click)="onButtonPressed()" [@buttonAnimation]="buttonState" (@buttonAnimation.done)="onAnimationEnd()"></i>
</button>
来自cordova插件的回调通过设置变量触发动画
enter code here
this.buttonState = 'big';
然后动画重新初始化
onAnimationEnd() {
this.buttonState = 'normal'
}
cordova插件是这样使用的,启动动画:
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
}, err => {
});
解决方案更新
我使用 yazantahhan 提出的解决方案解决了这个问题。我只需要在回调内部调用 ngZone,因为我需要在事件到达后触发更改。
cordova.plugins.buttonListener.listenButtonClick(data => {
this.ngZone.run(() => {
do stuff;
});
});
很可能您需要在 ngZone 中强制执行 detectChanges,或者 运行 它。
constructor(private ref: ChangeDetectorRef){}
ngOnInit() {
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
this.ref.detectChanges();
}, err => { });
}
或者使用 ngZone:
constructor(private ngZone: NgZone){}
ngOnInit() {
this.ngZone.run(() => {
cordova.plugins.buttonListener.listenButtonClick(data => {
this.buttonState = 'big';
}, err => { });
});
}