How to translate Java's inner anonymous classes into Nativescript JS? - nativescript

How do I translate the following Java code into Nativescript JS?
Assuming the all the libraries/namespaces are already in place, only syntax needed
mMapView.addViewpointChangedListener(new ViewpointChangedListener() {
#Override public void viewpointChanged(ViewpointChangedEvent viewpointChangedEvent) {
// do thing
}
});

You have implement the ViewpointChangedListener interface and then pass the instance of same to addViewpointChangedListener method. Similar to how OnClickListener interface is implemented here.

The answer was here in the docs : https://docs.nativescript.org/core-concepts/android-runtime/binding-generator/extend-class-interface#interfaces
So, in the end it turns this way :
this.mapView.addViewpointChangedListener(new com.esri.arcgisruntime.mapping.view.ViewpointChangedListener({
viewpointChanged: (args) => {
//do thing
}
}));

Related

Xamarin Android: Calling Invalidate() inside overridden OnDraw method

I am creating a custom renderer, that needs to display whatever I have rendered in my Vulkan engine. For this I have a VulkanSurfaceView, which inherits from MetalKit.MTKView on iOS, and from Android.Views.SurfaceView and ISurfaceHolderCallback on Android.
For iOS I can simply do this, which will draw a new frame continually, as long as the view is in focus:
public class VulkanSurfaceView : MTKView, IVulkanAppHost
{
...
public override void Draw()
{
Renderer.Tick();
base.Draw();
}
}
However, on Android I have to do this, where I call Invalidate() from within the OnDraw method, else it is only called once. I think this code smells a bit, and I am not sure, if this is the "good" way of doing it. Is my solution okay? If not, does anyone have a better idea?
public class VulkanSurfaceView : SurfaceView, ISurfaceHolderCallback, IVulkanAppHost
{
...
protected override void OnDraw(Canvas? canvas)
{
Renderer.Tick();
base.OnDraw(canvas);
Invalidate();
}
}
Did you try calling setWillNotDraw(false) in your surfaceCreated method ?
Refer the link
Thank you to #ToolmakerSteve.
I created a Timer where I call Invalidate() if a new frame has been requested (by me via a simple bool). For anyone interested I do it like so:
protected override void OnDraw(Canvas? canvas) // Just to show the updated OnDraw-method
{
Renderer.Tick();
base.OnDraw(canvas);
}
public void SurfaceCreated(ISurfaceHolder holder)
{
TickTimer = new System.Threading.Timer(state =>
{
AndroidApplication.SynchronizationContext.Send(_ => { if (NewFrameRequested) Invalidate(); }, state);
try { TickTimer.Change(0, Timeout.Infinite); } catch (ObjectDisposedException) { }
}, null, 0, Timeout.Infinite);
}
For now it is very simple, but it works and will probably grow. The reason for my initial bad framerate with this method was a misunderstanding of the "dueTime" of the Timer (see Timer Class), which I though was the framerate sought. This is actually the time between frames, which seems obvious now.
As #Bhargavi also kindly mentioned you need to set "setWillNotDraw(false)" if OnDraw is not being called when invalidating the view.

How to handle tap events for an interactive watch faces with androidx.wear?

What is the correct way of handling tap events with the new androidx.wear.watchface libraries? I was doing this with the now deprecated android.support:wearable libraries without any problem with Java (using onTapCommand). Now, everything seems to be quite different, especially since the documentation and examples seem to be available only in Kotlin. Also, I can't find any example which properly shows how the functions are used.
The documentation mentions setTapListener, TapListener. And then there are the functions onTap, onTapEvent and onTapCommand. This seems very confusing.
Could somebody put here a small example? Or point me to a working example on the internet?
Any help much appreciated!
Implementing this seemed to work for me
https://developer.android.com/reference/androidx/wear/watchface/WatchFace.TapListener
My code:
class WatchFaceRenderer(...): Renderer.CanvasRenderer(...), WatchFace.TapListener {
override fun onTapEvent(tapType: Int, tapEvent: TapEvent, complicationSlot: ComplicationSlot?) {
if (tapType == TapType.UP)
// do something
invalidate()
}
}
class Service : WatchFaceService() {
override suspend fun createWatchFace(
surfaceHolder: SurfaceHolder,
watchState: WatchState,
complicationSlotsManager: ComplicationSlotsManager,
currentUserStyleRepository: CurrentUserStyleRepository
): WatchFace {
val renderer = WatchFaceRenderer(
context = applicationContext,
surfaceHolder = surfaceHolder,
watchState = watchState,
currentUserStyleRepository = currentUserStyleRepository,
canvasType = CanvasType.SOFTWARE,
)
return WatchFace(WatchFaceType.ANALOG, renderer).setTapListener(renderer)
}
}

Tapestry: Events from Palette component

I'm using palette components on a page and I want the available elements in two of them to change depending on what is selected in the first.
What is the best way to achieve this? Which events are thrown by the palette component, that I could listen to, adapt the palette's model and perform a zone update? I thought it would work the same way as for select components doing something like this:
void onValueChanged() {
// do something
}
Unfortunately that doesn't work for palettes.
I'm using Tapestry 5.4-beta-6, but I guess things haven't changed that much since earlier versions.
I'd probably do this with a mixin.
public class PaletteChange {
#Parameter
private String zone;
#InjectContainer
private Palette palette;
public void afterRender() {
Link eventLink = componentResources.createEventLink("change");
JSONObject args = new JSONOBject(
"id", pallete.getClientId(),
"url", eventLink,
"zone", zone
);
javascriptSupport.addScript("palleteChange(%s)", args);
}
Object onChange(#RequestParameter("value") String value) {
CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>();
resources.triggerEvent("change", new String[] { value }, callback);
return callback.getResult();
}
}
Javascript
function palleteChange(spec) {
var field = $('#' + spec.id + '/select[1]');
field.on('change', function() {
var zoneManager = Tapestry.findZoneManagerForZone(spec.zone);
var params = { value: field.val() };
zoneManager.updateFromURL(spec.url, params);
});
}
Then use the mixin in your code
<t:palette t:id="myPalette" t:mixins="paletteChange" zone="myZone" ... />
<t:zone t:id="myZone">
...
</t:zone>
Page
#Inject
private Zone myZone;
Block onChangeFromMyPalette(String value) {
doStuff(value);
return myZone.getBody();
}
See here for a similar mixin.
I finally used the didChange element together with a similar mixin like the Observe mixin. I put a demo on Github for anyone, who is interested.
Just a few notes:
I used 5.4 beta 6, it already has the necessary client side events.
I couldn't make it work using a Tapestry javascript module, so I still use javascriptSupport.addInitializerCall.
The remaining problem is, that updating the second palette with a zone update will reset any changes the user has made in this palette, since they are only kept on the client side (in a hidden field). I will still need to look into that, but it is not part of the original question.

Dynamically setting content in Geb

I want to define a method in a groovy class that I can pass an xpath to on the fly(in order for the same method to be reusable depending on the application). The code snippet below is just a proof of concept, however I would eventually like to build a library of re-usable commands/components, which is why I would like to learn how to dynamically define page content.
If I try this:
import geb.Page;
class oneStepDefMethodClass extends Page {
static url = 'http://www.google.com'
static content = {
queryInput { $("input", id: "gbqfq") }
queryButton { $("button",name: "btnG") }
//songLink { $("span._BZ")}
}
....
void assertSongInResults2(String xpathOfSongLink){
println "Waiting on video link "+ xpathOfSongLink
songLink { $(xpathOfSongLink)}
waitFor {
songLink.displayed
}
}
}
I get this error :groovy.lang.MissingMethodException: No signature of method: geb.navigator.NonEmptyNavigator.songLink() is applicable for argument types: (oneStepDefMethodClass$_assertSongInResults2_closure3) values: [oneStepDefMethodClass$_assertSongInResults2_closure3#7c455e96]
If I throw a
content={songLink {$(xpathOfSongLink)}
}
block in the assertSongInResults2 method, I get this error:
geb.error.UnresolvablePropertyException: Unable to resolve songLink as content for oneStepDefMethodClass, or as a property on its Navigator context. Is songLink a class you forgot to import?
So, yeah is there a way to dynamically define page content like that? The program executes fine if I define it statically up top with the rest of the content , but that is not the point, I want to create re-usable resources instead of redefining the wheel every time I want to use geb.
Solved as I was writing the question, but thought I would post in case anyone else has a similar problem
static String someXpath
static content = {
queryInput { $("input", id: "gbqfq") } //
queryButton { $("button",name: "btnG") } //
songLink { $(someXpath) } //syntax element.className
}
....
void assertSongInResults2(String xpathOfSongLink){
println "Waiting on video link "+ xpathOfSongLink
someXpath=xpathOfSongLink
waitFor {
songLink.displayed
}
}

Fetch windows setting value

How do I fetch the Measurement System setting value in javascript?
I'm guessing that it would be throw some WinJS call.
The logical place would be Windows.Globalization, but not seeing if offered there. One pretty simple workaround - faster to write than to research the setting :) is to create a Windows Runtime Component in C# that calls in to System.Globalization:
namespace WindowsRuntimeComponent
{
public sealed class RegionalSettings
{
public bool isMetric()
{
return System.Globalization.RegionInfo.CurrentRegion.IsMetric;
}
}
}
Then add as a reference to your JavaScript app and invoke there:
var r = new WindowsRuntimeComponent.RegionalSettings;
var isMetric = r.isMetric();

Resources