I am developing android and ios application using nativescript angular project.I want to access my android library(aar) created using android studio,I was created a plugin project in nativescript and put the aar file inside the plugin project.I was also installed the plugin project to my project and run it but it was not working.How can i solve the issue
My java code is:
package com.deemsysinc;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ScrollView;
public class ResponsiveScrollView extends ScrollView {
public interface OnEndScrollListener {
public void onEndScroll(int x,int y);
}
private boolean mIsFling;
private OnEndScrollListener mOnEndScrollListener;
public ResponsiveScrollView(Context context) {
this(context, null, 0);
}
public ResponsiveScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ResponsiveScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void fling(int velocityY) {
super.fling(velocityY);
mIsFling = true;
Log.d("FlingCalled","true");
}
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (mIsFling) {
if (Math.abs(y - oldY) < 2 || y >= getMeasuredHeight() || y == 0) {
if (mOnEndScrollListener != null) {
mOnEndScrollListener.onEndScroll(x,y);
}
mIsFling = false;
}
}
}
public OnEndScrollListener getOnEndScrollListener() {
return mOnEndScrollListener;
}
public void setOnEndScrollListener(OnEndScrollListener mOnEndScrollListener) {
this.mOnEndScrollListener = mOnEndScrollListener;
}
}
I was calling my android native class like:
declare var com: any
export class FoodCourtScroll extends ScrollView
{
protected attachNative() {
(<any>ScrollView.prototype).attachNative.call(this);
}
public createNativeView() {
return this.orientation === "horizontal" ? new org.nativescript.widgets.HorizontalScrollView(this._context) : new com.example.admin.scrollwork.ResponsiveScrollView(this._context);
}
}
Package.json in my plugin project is:
{
"name": "nativescript-fscroll",
"version": "0.0.1",
"main": "index.js",
"nativescript": {
}
}
Please help to solve the issue.
My app.module.ts file:
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import {ActiveComponents,AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { NativeScriptUIListViewModule } from "nativescript-ui-listview/angular";
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import {NativeScriptFormsModule } from "nativescript-angular/forms";
import { NativeScriptHttpModule } from "nativescript-angular/http";
import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
import { DataService } from "~/app/data_services/data_services"
import { RestaurantService } from "~/app/services/restaurant.service";
import { NetWorkMonitor } from "~/app/Utils/NetworkMonitor";
import { AccordionModule } from "nativescript-accordion/angular";
import { TNSCheckBoxModule } from "nativescript-checkbox/angular";
import { NgRippleModule } from 'nativescript-ng-ripple';
import { CartService } from "~/app/services/cart.service";
import { ScrollView } from "ui/scroll-view";
import { registerElement } from "nativescript-angular";
import { OrderService, OrderData } from "~/app/services/order.service";
//import { FoodCourtScroll } from "~/app/Utils/deemsys_scroll";
import { DropDownModule } from "nativescript-drop-down/angular";
registerElement("PreviousNextView", () => require("nativescript-iqkeyboardmanager").PreviousNextView);
declare var org, android;
let ResponsiveScrollView;
function init() {
class ResponsiveScrollViewImpl extends org.nativescript.widgets.VerticalScrollView {
public mIsFling: boolean = false;
public fling(velocityY: any) {
super.fling(velocityY);
this.mIsFling = true;
}
}
ResponsiveScrollView = ResponsiveScrollViewImpl;
}
class FoodCourtScroll extends ScrollView {
createNativeView() {
init();
return new ResponsiveScrollView(this._context);
}
protected attachNative() {
const that = new WeakRef(this);
(<any>this).handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
onScrollChanged: function (x: number, y: number, oldX: number, oldY: number) {
const owner: ScrollView = that.get();
if (owner) {
(<any>owner)._onScrollChanged();
console.log("mIsFling: " + owner.nativeViewProtected.mIsFling);
if (owner.nativeViewProtected.mIsFling) {
if (Math.abs(y - oldY) < 2 || y >= owner.nativeViewProtected.getMeasuredHeight() || y == 0) {
owner.nativeViewProtected.mIsFling = false;
owner.notify({
object: owner,
eventName: "dragEnd",
scrollX: x,
scrollY: y
});
}
}
}
}
});
this.nativeViewProtected.getViewTreeObserver().addOnScrollChangedListener((<any>this).handler);
}
}
registerElement("FoodCourtScroll", () => FoodCourtScroll);
@NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule,
NativeScriptUIListViewModule,
NativeScriptFormsModule,
FormsModule,
ReactiveFormsModule,
NativeScriptHttpModule,
NativeScriptHttpClientModule,
AccordionModule,
TNSCheckBoxModule,
NgRippleModule,
DropDownModule
],
declarations: [
AppComponent,
...ActiveComponents,
],
providers: [
NetWorkMonitor,
DataService,
RestaurantService,
CartService,
OrderService,
OrderData
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AppModule { }
My Html file:
<ActionBar title="Menu" class="action-bar">
<ActionItem icon="res://search_red" ios.position="right" android.position="right"></ActionItem>
<!-- <StackLayout orientation="horizontal" ios.position="right">
<Image src="res://search_red" class="action-image"></Image>
</StackLayout> -->
<NavigationButton text="" icon="res://ic_arrow_red" (tap)="onNavBtnTap()"></NavigationButton>
</ActionBar>
<GridLayout rows="55,*,50">
<ScrollView #categoryList (scroll)="onHorizontalScroll($event)" orientation="horizontal" row="0" (loaded)="onLoaded($event)">
<StackLayout class="m-t-10 m-l-5 m-r-5" orientation="horizontal" >
<StackLayout orientation="horizontal" *ngFor="let category of AllMenuList; let a=index;" >
<Label height="55" width="170" [id]="category.categoryname" [class.category-label-Selected]="a===selectedIndex" class="category-label" [text]="category.categoryname" (tap)="onCategoryClick(a)"></Label>
<Label width="10"></Label>
</StackLayout>
</StackLayout>
</ScrollView>
<FoodCourtScroll id="subMenuScroll" (dragEnd)="onDragEnd($event)" (scrollEnds)="onScrollEnds($event)" (onScrollEnd)="onScrollEndd($event)" (scroll)="onVerticalScroll($event)" #ScrollList class="m-t-10" orientation="vertical" row="1">
<StackLayout id="vscroll">
<StackLayout width="100%" class="m-t-20 m-l-10" orientation="vertical" *ngFor="let category of AllMenuList; let i=index;" (tap)="onCellClick($event)">
<StackLayout [id]="category.categoryname" width="100%" >
<Label class="category-name" [text]="category.categoryname"></Label>
<StackLayout class="m-t-30" orientation="vertical" *ngFor="let food of category.menus; let k=index;" >
<GridLayout rows="auto,auto,auto,auto">
<StackLayout row="0" orientation="horizontal">
<Image [src]="food.cuisineType==1? '~/app/images/veg.png':'~/app/images/nonveg.png'" height="15" width="15"></Image>
<Label class="food-name" [text]="food.menuname"></Label>
</StackLayout>
<Label [text]="'$'+food.price" row="1" class="food-price"></Label>
<Button [visibility]="!food.isCountEnabled? 'visible': 'collapse'" class="add-button" row="1" horizontalAlignment="right" text="ADD" (tap)="Add(i,k)"></Button>
<GridLayout [visibility]="food.isCountEnabled? 'visible':'collapse'" class="plusandminuscontainer" row="1" horizontalAlignment="right">
<Label horizontalAlignment="left" verticalAlignment="center" class="minus" text="" (tap)="decrement(i,k)"></Label>
<Label horizontalAlignment="center" verticalAlignment="center" class="count-label" [text]="food.itemCount"></Label>
<Label horizontalAlignment="right" verticalAlignment="center" class="plus" text="" (tap)="increment(i,k)"></Label>
</GridLayout>
<StackLayout class="prep-container" row="2" orientation="horizontal">
<Label class="time-icon" text=""></Label>
<Label class="prep-time" [text]="food.preptime + ' minutes' "></Label>
</StackLayout>
<StackLayout row="3" class="hr-light m-l-20 m-t-10" ></StackLayout>
</GridLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</FoodCourtScroll>
<GridLayout [visibility]="cartItem==0? 'collapse':'visible'" class="anim-itemInfo cart-container" row="2">
<StackLayout orientation="horizontal" horizontalAlignment="left">
<Label verticalAlignment="center" class="m-l-10 cart-label" [text]="cartItem + ' Items'"></Label>
<Label verticalAlignment="center" class="m-l-10 cart-label" text="|"></Label>
<Label verticalAlignment="center" class="m-l-10 cart-label" [text]="'$'+cartTotal"></Label>
</StackLayout>
<Label verticalAlignment="center" class="m-r-10 viewcart-label" text="VIEW CART " horizontalAlignment="right"></Label>
</GridLayout>
</GridLayout>
My Html related ts file:
import { Component, OnInit, AfterViewInit,ViewChild, ElementRef} from "@angular/core";
import {Page, borderTopRightRadiusProperty} from "ui/page";
import { isIOS, isAndroid } from 'tns-core-modules/platform';
import { RadListView, ListViewEventData } from "nativescript-ui-listview";
//import { RestaurentMenuModel,RestaurentSubMenuModel } from "~/app/models/restaurant";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { run } from "tns-core-modules/application/application";
import { ScrollEventData, ScrollView } from "tns-core-modules/ui/scroll-view/scroll-view";
import { RouterExtensions } from "nativescript-angular/router";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { Label } from "tns-core-modules/ui/label/label";
import { analyzeAndValidateNgModules } from "@angular/compiler";
import * as utils from "tns-core-modules/utils/utils";
import { setTimeout, setInterval} from "tns-core-modules/timer";
import { EventData } from "data/observable";
import { FoodScrollDelegate } from "~/app/Utils/scroll_delegate";
declare var UITableViewCellSelectionStyle;
declare var UIView, NSMutableArray, NSIndexPath;
//declare var setShowsHorizontalScrollIndicator;
@Component({
selector:"restaurant_menu",
moduleId:module.id,
templateUrl:"./restaurant_menu.component.html",
styleUrls:["./restaurant_menu.component.css"],
})
export class RestaurantMenu implements OnInit
{
//public cartCount:Number=1;
@ViewChild("ScrollList") scrollList:ElementRef;
@ViewChild("categoryList") categoryList:ElementRef;
public AllMenuList:any;
public cartTotal:any=0;
public cartItem:any=0;
public isCartVisible=false;
incrementItem:any=0;
decrementItem:any=0;
categoryContainer:Label;
subMenuContainers:StackLayout;
offsetValue:any=0;
dummyStatus:any=0;
iterate:any=0;
horizontalOffsetvalue:any=0;
calculationValue:any=0;
lengthHorizontaloffsetLength:any=0;
public selectedIndex:Number=0;
public scrollEnabled:Boolean=false;
lastItemY:Number=0;
subMenuScroll:ScrollView;
foodScrollDelegate:FoodScrollDelegate;
public id;
_delegate:any;
constructor(private page:Page,public routerExtension:RouterExtensions)
{
}
ngOnInit()
{
this.subMenuScroll=this.page.getViewById("subMenuScroll");
//this.subMenuScroll.ios.delegate=FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
//console.log("PrintDelegate"+this.foodScrollDelegate.scrollViewDidEndDraggingWillDecelerate);
// this.foodScrollDelegate=new FoodScrollDelegate();
// this.foodScrollDelegate.yvalue.subscribe(yvalue=>{
// console.log("TheYYValue"+yvalue);
// });
}
onLoaded(event)
{
const scrollview = event.object;
if (scrollview.ios) {
scrollview.ios.showsHorizontalScrollIndicator = false;
}
else
{
scrollview.android.setHorizontalScrollBarEnabled(false);
}
}
onNavBtnTap()
{
this.routerExtension.backToPreviousPage();
}
public onHorizontalScroll(args:ScrollEventData)
{
// console.log("scrollX: " + args.scrollX);
// console.log("scrollY: " + args.scrollY);
}
public onVerticalScroll(args: ScrollEventData) {
console.log("Scrolling")
}
onScrollEndd(event)
{
console.log("TheAndroidEvent"+event.y);
}
}
You don't need a AAR library for simple implementations like this one. You could handle everything with your project here
declare var org, android;
let ResponsiveScrollView;
function init() {
class ResponsiveScrollViewImpl extends org.nativescript.widgets.VerticalScrollView {
public mIsFling: boolean = false;
constructor(context) {
super(context);
return global.__native(this);
}
public fling(velocityY: any) {
super.fling(velocityY);
this.mIsFling = true;
}
}
ResponsiveScrollView = ResponsiveScrollViewImpl;
}
class FoodCourtScroll extends ScrollView {
createNativeView() {
init();
return new ResponsiveScrollView(this._context);
}
protected attachNative() {
const that = new WeakRef(this);
(<any>this).handler = new android.view.ViewTreeObserver.OnScrollChangedListener({
onScrollChanged: function () {
const owner: ScrollView = that.get();
if (owner) {
const nativeView = owner.nativeViewProtected;
if (nativeView) {
const x = nativeView.getScrollX();
const y = nativeView.getScrollY();
const oldX = (<any>owner)._lastScrollX;
const oldY = (<any>owner)._lastScrollY;
console.log("mIsFling: " + nativeView.mIsFling);
console.log("newX: " + x);
console.log("oldX: " + oldX);
console.log("newY: " + y);
console.log("oldY: " + oldY);
if (nativeView.mIsFling) {
if (Math.abs(y - oldY) < 2 || y >= owner.nativeViewProtected.getMeasuredHeight() || y == 0) {
owner.nativeViewProtected.mIsFling = false;
owner.notify({
object: owner,
eventName: "dragEnd",
scrollX: x,
scrollY: y
});
}
}
}
(<any>owner)._onScrollChanged();
}
}
});
this.nativeViewProtected.getViewTreeObserver().addOnScrollChangedListener((<any>this).handler);
}
}
registerElement("FoodCourtScroll", () => FoodCourtScroll);
Here is the Playground Sample, make sure you execute Android specific code conditionally to not break the iOS version. You may consider writing platform specific TS files that implements FoodCourtScroll
Or simply use a if condition based on platform.
Note: fling
method is never called, I haven't used it before. So you might want to check your implementation there.