I am building a nativescript carousel using the nativescript-carousel pluging but when I do tns build android I am getting this error:
node_modules/nativescript-carousel/index.d.ts(1,22): error TS6053: File 'D:/Documents/coursera_examples/nativescript/VilcabambaHotel/node_modules/nativescript-carousel/node_modules/tns-platform-declarations/android.d.ts' not found.
My home.component.html carousel is this:
<GridLayout horizontalAlignment="center" verticalAlignment="top" rows="*" columns="*" height="95%">
<Carousel #carousel ios:indicatorOffset="0,-10" ios:finite="true" ios:bounce="false" showIndicator="true" height="100%" indicatorAnimation="SWAP"
indicatorColor="#66ccff" indicatorColorUnselected="#cceeff" height="250" width="80%">
<CarouselItem backgroundColor="white" height="100%">
<GridLayout *ngIf="cabin">
<Image [src]="BaseURL + cabin.image" ></Image>
</GridLayout>
</CarouselItem>
<CarouselItem backgroundColor="white">
<GridLayout *ngIf="house">
<Image [src]="BaseURL + house.image" ></Image>
</GridLayout>
</CarouselItem>
<CarouselItem backgroundColor="white">
<GridLayout *ngIf="ecoactivity">
<Image [src]="BaseURL + ecoactivity.image" ></Image>
</GridLayout>
</CarouselItem>
</Carousel>
</GridLayout>
this is my home.component.ts
import { Component, OnInit, Inject, ChangeDetectorRef } from '#angular/core';
//import { TNSFontIconService } from 'nativescript-ngx-fonticon';
import { Page } from "ui/page";
import { View } from "ui/core/view";
import { SwipeGestureEventData, SwipeDirection } from "ui/gestures";
import * as enums from "ui/enums";
import { Cabin } from '../shared/cabin';
import { CabinService } from '../services/cabin.service';
import { House } from '../shared/house';
import { HouseService } from '../services/house.service';
import { Ecoactivity } from '../shared/ecoactivity';
import { EcoactivityService } from '../services/ecoactivity.service';
import { DrawerPage } from '../shared/drawer/drawer.page';
import { registerElement } from 'nativescript-angular/element-registry';
import { Carousel, CarouselItem } from 'nativescript-carousel';
registerElement('Carousel', () => Carousel);
registerElement('CarouselItem', () => CarouselItem);
#Component({
selector: 'app-home',
moduleId: module.id,
templateUrl: './home.component.html',
// styleUrls: ['./home.component.css']
})
export class HomeComponent extends DrawerPage implements OnInit {
cabin: Cabin;
house: House;
ecoactivity: Ecoactivity;
cabinErrMess: string;
houseErrMess: string;
ecoactivityErrMess: string;
constructor(private cabinservice: CabinService,
private houseservice: HouseService,
private ecoactivityservice: EcoactivityService,
private changeDetectorRef: ChangeDetectorRef,
private page: Page,
// private fonticon: TNSFontIconService,
#Inject('BaseURL') private BaseURL) {
super(changeDetectorRef);
}
ngOnInit() {
this.cabinservice.getFeaturedCabin()
.subscribe(cabin => this.cabin = cabin,
errmess => this.cabinErrMess = <any>errmess);
this.houseservice.getFeaturedHouse()
.subscribe(house => this.house = house,
errmess => this.houseErrMess = <any>errmess);
this.ecoactivityservice.getFeaturedEcoactivity()
.subscribe(ecoactivity => this.ecoactivity = ecoactivity,
errmess => this.ecoactivityErrMess = <any>errmess);
}
The error disapears if I remove the next lines of code but my carousel stops working
import { registerElement } from 'nativescript-angular/element-registry';
import { Carousel, CarouselItem } from 'nativescript-carousel';
registerElement('Carousel', () => Carousel);
registerElement('CarouselItem', () => CarouselItem
I created a document called reference.d.ts with the next lines of code but the error is still there.
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
Looks like a improper usage of declaration within plugin, you could manually adjust it by updating the path to
/// <reference path="../tns-platform-declarations/android.d.ts" />
from
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
in index.d.ts
Edit:
If you still find any other TS errors, you may simply add "skipLibCheck": true inside compilerOptions in your tsconfig.json.
Related
I am trying to create a dropdown in my nativescript angular app by using nativescript dropdown plugin. I am seeing an error "Dropdown(1) is not a valid view instance" when I run the app
import { DropDownModule } from "nativescript-drop-down/angular";
.html file
<GridLayout rows="auto, auto, auto, *"
columns="auto, *" (tap)="openVersionDropdown()" >
<DropDown #dd backgroundColor="red" [items]="itemsVersion"
[selectedIndex]="selectedVersionIndex" (opened)="onopen()"
(closed)="onclose()" (selectedIndexChange)="onVersionChange($event)" row="0" colSpan="2"></DropDown>
<Label text="Selected Index:"
row="1"
col="0"
fontSize="18"
verticalAlignment="bottom"></Label>
<Label [text]="selectedVersionIndex"
row="1"
col="1"></Label>
ts file
import {DropDown, SelectedIndexChangedEventData, ValueList} from "nativescript-drop-down";
....
public itemsVersion: ValueList<string>;
selectedVersionIndex : number;
public onopen() {
console.log("Drop Down opened.");
}
public onclose() {
console.log("Drop Down closed.");
}
public changeStyles() {
this.cssClass = "changed-styles";
}
openVersionDropdown(){
let dropdown = <DropDown>this.page.getViewById('ddVersion');
dropdown.open();
}
onVersionChange(args: SelectedIndexChangedEventData){
console.log(`Drop Down selected index changed from ${args.oldIndex} to ${args.newIndex}. `);
}
ngOnInit(): void {
this.itemsVersion = new ValueList<string>();
for (let loop = 0; loop < 5; loop++) {
this.itemsVersion.push({
value: `${loop}` ,
display: "Item "+ loop,
});
}
}
Try to this for add dropdown in application:
1.demo.module.ts:-
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { DemoComponent } from "./demo.component";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { DropDownModule } from "nativescript-drop-down/angular";
#NgModule({
imports: [
NativeScriptCommonModule,
NativeScriptFormsModule,
DropDownModule,
],
declarations: [
DemoComponent
],
providers: [
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class DemoModule { }
2.demo.component.html:-
<GridLayout row="0" rows="auto" col="0" columns="*,auto"
class="demo-container" ios:style="padding:8">
<DropDown row="0" col="0" #ddlInitial [items]="initialList"
[selectedIndex]="initialSelectedIndex" ios:style="padding:8"
(selectedIndexChanged)="onInitialChange($event)"
hint="Initial"
class="eloha-font-semibold demo-drop-input">
</DropDown>
<Label row="0" col="1" text="" class="fa set-icon-color"
[ngClass]="{'font-size-lg': !isTablet, 'font-size-lg-tablet': isTablet}"
verticalAlignment="middle" android:style="padding-right: 10"></Label>
</GridLayout>
3.demo.component.ts:-
import { Component, OnInit, NgZone, ChangeDetectorRef, ChangeDetectionStrategy, ViewChild, AfterViewInit, ElementRef } from "#angular/core";
import * as frameModule from "tns-core-modules/ui/frame";
import { isIOS, device } from "tns-core-modules/platform";
import * as orientation from 'nativescript-orientation';
import { RouterExtensions } from "nativescript-angular/router";
import * as dialogs from "tns-core-modules/ui/dialogs";
import { DeviceType } from "tns-core-modules/ui/enums";
import { ActivatedRoute } from "#angular/router";
import { SelectedIndexChangedEventData, ValueList } from "nativescript-drop-down";
import { DatePipe } from "#angular/common";
#Component({
selector: "Demo",
moduleId: module.id,
templateUrl: "./demo.component.html",
styleUrls: ['./demo.component.css'],
providers: [DatePipe]
})
export class AddFamilyComponent implements OnInit {
public isTablet: boolean = false;
//Value
public initialList: ValueList<string>;
//Get dropDown selected index
public initialSelectedIndex = 0;
constructor(private zone: NgZone,
private _ref: ChangeDetectorRef,
private route: ActivatedRoute,
private datePipe: DatePipe,
private routerExtensions: RouterExtensions) {
this.isIos = isIOS;
this.pageIndex = "2";
}
ngOnInit(): void {
orientation.setOrientation("portrait");
orientation.disableRotation();
}
ngAfterViewInit(): void {
if (isIOS) {
const controller = frameModule.topmost().ios.controller;
// get the view controller navigation item
const navigationItem = controller.visibleViewController.navigationItem;
// hide back button
navigationItem.setHidesBackButtonAnimated(true, false);
}
}
//Add initial value
getInitialValueList() {
let initialSource = new ValueList<string>([
{ value: "Mr", display: "Mr" },
{ value: "Mrs", display: "Mrs" },
{ value: "Miss", display: "Miss" }
]);
this.initialList = initialSource;
}
//Change initial selection value
onInitialChange(args: SelectedIndexChangedEventData) {
let initialValue = this.initialList.getValue(args.newIndex);
}
}
4. demo.component.css:-
.demo-drop-input {
font-size: 17;
padding-top: 5;
padding-left: 5;
padding-right: 0;
padding-bottom: 5;
border-radius: 30;
background: #fffff;
}
I want to import this in my react native project's Appjs view.
I tried many ways but its not working. I mean i want to render it inside My view. How can I import and show this file in my Appjs?
Here is my code:
import ForwardRef from '../../constants/UI_login/Home_Landing_Page/BackgroundComponent'
import React from "react";
import Svg, { Defs, LinearGradient, Stop, Rect } from "react-native-svg";
/* Adobe XD React Exporter has dropped some elements not supported by react-native-svg: style */
const BackgroundComponent = ({ svgRef }) => (
<Svg width={375} height={247} viewBox="0 0 375 247" ref={svgRef}>
<Defs>
<LinearGradient
id="a"
x1={0.5}
y1={0.807}
x2={0.5}
y2={1}
gradientUnits="objectBoundingBox"
>
<Stop offset={0} stopColor="#fff" />
<Stop offset={1} stopColor="#fff" stopOpacity={0} />
</LinearGradient>
</Defs>
<Rect className="a" width={375} height={247} />
</Svg>
);
const ForwardRef = React.forwardRef((props, ref) => (
<BackgroundComponent svgRef={ref} {...props} />
));
export default ForwardRef;
App.js
import React from 'react';
import { StyleSheet} from 'react-native';
//import {Actions} from 'react-native-router-flux';
import Routes from './components/Routes';
import {firebaseConfig} from "./constants/ApiKeys";
import {AppContainer} from './components/Navigation'
import * as firebase from 'firebase';
if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); }
console.ignoredYellowBox = ['Setting a timer'];
export default class App extends React.Component {
render() {
return (
<AppContainer/>
);
}
}
I'm using the NativeBase (and especially the NativeBaseSink template). All my routes are defined in the App.js like this :
App.js
import { Platform } from "react-native";
import { Root } from "native-base";
import { StackNavigator, TabNavigator } from "react-navigation";
import Drawer from "./Drawer";
import Homepage from "./main_scenes/main";
import Splashscreen from "./main_scenes/home/";
import LoginScene from "./main_scenes/home/login/";
import RegisterScene from "./main_scenes/home/register/";
import InsertPhoneCode from "./main_scenes/home/pin/";
import MyResults from "./main_scenes/results/";
import MyMap from "./main_scenes/results/map/";
import UserDetails from "./main_scenes/profile/";
import MyResultsByDistance from "./main_scenes/results/Distance"
import MyResultsByAvis from "./main_scenes/results/Avis"
import Test from "./main_scenes/tab"
const AppNavigator = StackNavigator(
{
Drawer: { screen: Drawer },
RegisterScene: {screen : RegisterScene},
Splashscreen:{ screen : Splashscreen},
Homepage:{ screen : Homepage},
InsertPhoneCode:{screen:InsertPhoneCode},
LoginScene: {screen : LoginScene},
MyResults: {screen:MyResults},
MyMap:{screen:MyMap},
UserDetails:{screen:UserDetails},
MyResultsByDistance:{screen:MyResultsByDistance},
MyResultsByAvis:{screen:MyResultsByAvis},
},
{
initialRouteName: "Splashscreen",
headerMode: "none",
}
);
export default () =>
<Root>
<AppNavigator />
</Root>;
I'm using the Tabs functionality of Nativebase framework. Then, I have create an index.js where i've define all my tabs like this :
index.js
import React, { Component } from "react";
import {Dimensions, AppRegistry, StyleSheet,
ListView, ScrollView,View,Image,TouchableOpacity,AsyncStorage, Alert} from 'react-native';
import {
Container,
Header,
Title,
Button,
Icon,
Tabs,
Tab,
Text,
Right,
Left,
Body,
TabHeading,
Footer,
FooterTab,
} from "native-base";
import DisplayByDistance from "./Distance/";
import DisplayByAvis from "./Avis/";
import styles from "./styles";
import { StackNavigator } from 'react-navigation';
export default class ConfigTab extends Component {
constructor(props) {
super(props);
this.state = {
tab1: false,
mapRegion: null,
lastLat: null,
lastLong: null,
};
}
toggleTab1() {
this.setState({
tab1: true,
});
}
render() {
return (
<Container>
<Header hasTabs>
<Left>
<Button transparent onPress={() => this.props.navigation.goBack()}>
<Icon name="arrow-back" />
</Button>
</Left>
<Body style={{ flex: 3 }}>
<Title> Résultats</Title>
</Body>
<Right />
</Header>
<Tabs style={{ elevation: 3 }}>
<Tab
heading={
<TabHeading><Icon name="navigate" /><Text
style={styles.TabTitle}>Le plus prés</Text></TabHeading>
}
>
<DisplayByDistance />
</Tab>
<Tab heading={<TabHeading><Icon name="star-half" /><Text
style={styles.TabTitle}>Le mieux noté</Text></TabHeading>}>
<DisplayByAvis />
</Tab>
</Tabs>
<Footer>
<FooterTab>
<Button active={this.state.tab1} onPress={() => this.props.navigation.navigate("MyMap")}>
<Icon active={this.state.tab1} name="paper-plane" />
<Text>Afficher la carte</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
AppRegistry.registerComponent('ConfigTab', () => ConfigTab);
According to the files i've edited, when i press on the TabOne, it opens the right tab where the content is located in the file called Distance.js
So right now, everything works well except that the "props.navigation.navigate"is not recognized in my Distance.js file.
Here is my file
Distance.js
import React, { Component, PropTypes } from "react";
import {...} from 'react-native';
import {...} from "native-base";
import styles from "./../styles";
import { StackNavigator } from 'react-navigation';
import App from "./../../../App"
var productArray = [];
class TabOne extends Component {
constructor(props){
super(props)
var dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1.guid != r2.guid});
this.state={
data:[],
dataSource: dataSource.cloneWithRows(productArray),
isLoading:true,
}
this.donePressed=this.donePressed.bind(this);
};
componentDidMount()
{
this.getTheData(function(json){
productArray = json;
this.setState({
dataSource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
}.bind(this));
}
donePressed() {
const { navigate } = this.props.navigation;
navigate('UserDetails');
}
getTheData(callback) {
var url = "http://paradox.ma/workshop/webservices/getPOI_info.php";
fetch(url)
.then(response => response.json())
.then(json => callback(json))
.catch(error => alert("Erreur de connexion Internet") );
}
list(rowData) {
if (rowData === null) { return <View></View>; };
let VerifiedUser;
const VerifiedTest=rowData.Verified;
if (VerifiedTest==='1')
{
VerifiedUser=(
<Right>
<View style={styles.avatarBox}>
<Text numberOfLines={2}><Icon name="verified" size={30} color="green" /></Text>
<Text>Profil vérifié</Text>
</View>
</Right>
)}
return (
<ListItem thumbnail
onPress={() => this.donePressed().bind(this)}
>
<Left>
<View style={styles.avatarBox}>
<Thumbnail size={55} source={{uri:rowData.Avatar}} />
<Text style={styles.avatarTitle}>{rowData.Title}</Text>
</View>
</Left>
<Body>
<Text>{rowData.Title}</Text>
<Text numberOfLines={2}><Icon name="map-marker" size={15} color="grey" /> {rowData.Address}, {rowData.City} ({rowData.Distance} km)</Text>
<Text numberOfLines={3}>{rowData.Description}</Text>
</Body>
{VerifiedUser}
</ListItem>
);
}
render(){
return(
<Container>
<View>
<TouchableOpacity onPress={() => this.donePressed().bind(this)}>
<Text>Test</Text>
</TouchableOpacity>
</View>
</Container>
);
}
}
export default TabOne;
My function called donePressed() works very well when i replace the this.props.navigation.navigate by alert("Hello") But once I try to navigate between screens, I have an error : Undefined is not an object...this_2.props.navigation.navigate().
I really don't know where is the problem coming from. I have tried to define the function in the constructor, no way.
Hope to find a solution.
if you want to react navigation to inject navigation prop you'll need to declare that specific Component as a Navigator scene
but I would totally suggest using React navigation's TabNavigator,
you can find here how to nest Navigators: https://reactnavigation.org/docs/intro/nesting
I'm trying to get this to work, but it only gives me following error. I did almost the same thing for the nativescript-groceries app, but angular2-seed-advanced has a somewhat different architecture, seems to be a dependency injection problem somewhere between nativescript and the seed project and the telerik-ui.
Any help is appreciated:
EXCEPTION: Error in
/data/data/com.yourdomain.appname/files/app/app/components/app.component.tns.html:0:0
ORIGINAL EXCEPTION: TypeError: Cannot read property 'android' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'android' of undefined
at RadSideDrawer.initOldDrawer (/data/data/com.yourdomain.appname/files/app/tns_modules/nativescript-telerik-ui/sidedrawer/sidedrawer.js:91:40)
at RadSideDrawer._createUI (/data/data/com.yourdomain.appname/files/app/tns_modules/nativescript-telerik-ui/sidedrawer/sidedrawer.js:147:18)
at RadSideDrawer.View._onContextChanged (/data/data/com.yourdomain.appname/files/app/tns_modules/ui/core/view.js:197:14)
at RadSideDrawer.View._onAttached (/data/data/com.yourdomain.appname/files/app/tns_modules/ui/core/view.js:149:14)
at Page.View._addViewCore (/data/data/com.yourdomain.appname/files/app/tns_modules/ui/core/view.js:125:18)
at Page.View._addView (/data/data/com.yourdomain.appname/files/app/tns_modules/ui/core/view-common.js:952:14)
at Page.Object.defineProperty.set [as content] (/data/data/com.yourdomain.appname/files/app/tns_modules/ui/content-view/content-view.js:19:22)
at ViewUtil.insertChild (/data/data/com.yourdomain.appname/files/app/tns_modules/nativescript-angular/view-util.js:56:28)
at ViewUtil.createAndAttach (/data/data/com.yourdomain.appname/files/app/tns_modules/nativescript-angular/view-util.js:103:18)
at ViewUtil.createView (/data/data/com.yourdomain.appname/files/app/tns_modules/nativescript-angular/view-util.js:110:25)
ERROR CONTEXT:
[object Object]
Here are my changes
nativescript/package.json
### Added dependency
"nativescript-telerik-ui": "^1.3.1",
nativescript/app/native.module.ts
...
import {SIDEDRAWER_PROVIDERS} from 'nativescript-telerik-ui/sidedrawer/angular';
...
#NgModule({
...
providers: [
NS_ANALYTICS_PROVIDERS,
### Added sidedrawer providers
SIDEDRAWER_PROVIDERS,
{ provide: RouterExtensions, useClass: TNSRouterExtensions }
],
...
})
export class NativeModule { }
nativescript/app/pages/app/app.component.ts:
...
import {Inject, ChangeDetectorRef} from '#angular/core';
...
import {Page} from 'ui/page';
...
export class NSAppComponent extends AppComponent {
constructor(
#Inject(Page) private _page: Page,
private _changeDetectionRef: ChangeDetectorRef,
#Inject(AnalyticsService) public analytics: AnalyticsService,
#Inject(LogService) private log: LogService,
#Inject(Store) private store: Store<any>,
#Inject(Router) private router: Router)
{
// ### ADDED Page and ChangeDetectionRef
super(_page, _changeDetectionRef, analytics, log);
...
nativescript/app/app/components/app.component.ts
...
import {ViewChild, ChangeDetectorRef, ChangeDetectionStrategy, AfterViewInit} from '#angular/core';
...
import {
SIDEDRAWER_DIRECTIVES,
RadSideDrawerComponent,
SideDrawerType
} from 'nativescript-telerik-ui/sidedrawer/angular';
import {DrawerTransitionBase, PushTransition} from 'nativescript-telerik-ui/sidedrawer';
import {Page} from 'ui/page';
...
#BaseComponent(
{
moduleId : module.id,
selector : 'sd-app',
templateUrl : 'app.component.html',
directives : [SIDEDRAWER_DIRECTIVES],
changeDetection: ChangeDetectionStrategy.Default // Everything else uses OnPush
}
)
export class AppComponent implements AfterViewInit {
private _currentNotification: string;
private _sideDrawerTransition: DrawerTransitionBase;
#ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
private drawer: SideDrawerType;
constructor(
private page: Page,
private changeDetectionRef: ChangeDetectorRef,
public analytics: AnalyticsService,
public logger: LogService)
{
logger.debug(`Config env: ${Config.ENVIRONMENT().ENV}`);
this.page.on("loaded", this.onLoaded, this);
}
ngAfterViewInit() {
this.drawer = this.drawerComponent.sideDrawer;
this.changeDetectionRef.detectChanges();
}
public onLoaded(args) {
this._sideDrawerTransition = new PushTransition();
}
public get sideDrawerTransition(): DrawerTransitionBase {
return this._sideDrawerTransition;
}
public get currentNotification(): string {
return this._currentNotification;
}
public openDrawer() {
this.drawer.showDrawer();
}
public onDrawerOpening() {
console.log("Drawer opening");
this._currentNotification = "Drawer opening";
}
public onDrawerOpened() {
console.log("Drawer opened");
this._currentNotification = "Drawer opened";
}
public onDrawerClosing() {
console.log("Drawer closing");
this._currentNotification = "Drawer closing";
}
public onDrawerClosed() {
console.log("Drawer closed");
this._currentNotification = "Drawer closed";
}
}
nativescript/app/app/components/app.component.tns.html
<RadSideDrawer #drawer>
<StackLayout tkDrawerContent class="sideStackLayout">
<StackLayout class="sideTitleStackLayout">
<Label text="Navigation Menu"></Label>
</StackLayout>
<StackLayout class="sideStackLayout">
<Label text="MenuItemA" ></Label>
<Label text="MenuItemB" ></Label>
<Label text="MenuItemC" ></Label>
</StackLayout>
</StackLayout>
<StackLayout tkMainContent>
<!-- nested original content in Drawer -->
<ActionBar title="Test" class="action-bar">
<ActionItem ios.position="right" android.position="popup">
<Button [text]="'MENU' | translate" (tap)=openDrawer() class="action-btn"></Button>
</ActionItem>
<ActionItem nsRouterLink="/about" ios.position="right" android.position="popup">
<Button [text]="'ABOUT' | translate" class="action-btn"></Button>
</ActionItem>
</ActionBar>
<StackLayout class="container">
<lang-switcher></lang-switcher>
<ScrollView>
<page-router-outlet></page-router-outlet>
</ScrollView>
</StackLayout>
</StackLayout>
nativescript/app/app/components/app.component.tns.css
.sideStackLayout {
background-color: white;
}
Ok, got it to work and wanted to share this, as it is not exactly straightforward or especially well documented...
With the release of nativescript-telerik-ui 1.4.1 and the final 2.0.0 release of Angular this is pretty easy actually.
nativescript/package.json
### Added dependency
"nativescript-telerik-ui": "^1.4.1",
nativescript/app/native.module.ts
...
import { SIDEDRAWER_DIRECTIVES } from 'nativescript-telerik-ui/sidedrawer/angular';
...
#NgModule({
...
declarations: [
SIDEDRAWER_DIRECTIVES, ### allows usage of <RadSideDrawer> in pages
HomeComponent,
AboutComponent
],
...
})
export class NativeModule { }
nativescript/app/pages/app/app.component.ts:
no changes - drawer is supposed to be used per page
nativescript/app/app/components/app.component.ts
no changes - drawer is supposed to be used per page
nativescript/app/app/components/about/about.component.ts
import {ViewChild, ChangeDetectorRef, Inject} from '#angular/core';
...
import {RadSideDrawerComponent, SideDrawerType } from 'nativescript-telerik-ui/sidedrawer/angular';
import {DrawerTransitionBase, PushTransition} from 'nativescript-telerik-ui/sidedrawer';
import {Page} from 'ui/page';
...
export class AboutComponent {
private _currentNotification: string;
private _sideDrawerTransition: DrawerTransitionBase;
#ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
private drawer: SideDrawerType;
constructor(
private page: Page,
private changeDetectionRef: ChangeDetectorRef )
{
this.page.on("loaded", this.onLoaded, this);
}
ngAfterViewInit() {
this.drawer = this.drawerComponent.sideDrawer;
this.changeDetectionRef.detectChanges();
}
public onLoaded(args) {
this._sideDrawerTransition = new PushTransition();
}
public get sideDrawerTransition(): DrawerTransitionBase {
return this._sideDrawerTransition;
}
public get currentNotification(): string {
return this._currentNotification;
}
public openDrawer() {
this.drawer.showDrawer();
}
public onDrawerOpening() {
console.log("Drawer opening");
this._currentNotification = "Drawer opening";
}
public onDrawerOpened() {
console.log("Drawer opened");
this._currentNotification = "Drawer opened";
}
public onDrawerClosing() {
console.log("Drawer closing");
this._currentNotification = "Drawer closing";
}
public onDrawerClosed() {
console.log("Drawer closed");
this._currentNotification = "Drawer closed";
}
}
nativescript/app/app/components/app.component.tns.html
<RadSideDrawer #drawer
(drawerOpening)="onDrawerOpening()"
(drawerOpened)="onDrawerOpened()"
(drawerClosing)="onDrawerClosing()"
(drawerClosed)="onDrawerClosed()"
[transition]="sideDrawerTransition">
<StackLayout tkDrawerContent class="sideStackLayout">
<Label text="MenuItemA" ></Label>
<Label text="MenuItemB" ></Label>
<Label text="MenuItemC" ></Label>
</StackLayout>
<StackLayout tkMainContent>
<!-- nested original content in Drawer -->
<ActionBar title="Test" class="action-bar">
<ActionItem ios.position="right" (tap)=openDrawer() android.position="popup">
<Button [text]="'MENU' | translate" class="action-btn"></Button>
</ActionItem>
<ActionItem nsRouterLink="/about" ios.position="right" android.position="popup">
<Button [text]="'ABOUT' | translate" class="action-btn"></Button>
</ActionItem>
</ActionBar>
<StackLayout>
<Label text="Angular 2 Seed Advanced is ...
...
</StackLayout>
</StackLayout>
nativescript/app/app/components/app.component.tns.css
.sideStackLayout {
background-color: white;
}
I am a newbie in react-native, Dont mind if i ask a basic question, i wanted to know,
what is the step by step procedure to implement navigation drawer.
Referred Links this Link
I am not able to integrate it.
Any Demo project implementing drawer will also work.
Any help regarding this will be great.
Thankyou
Implementation of navigation drawer in react native as follows:
index.ios.js
'use strict';
import React, { AppRegistry } from 'react-native';
import App from './components/App';
AppRegistry.registerComponent('ReactNativeProject', () => App);
App.js:
'use strict'
import React, { Component } from 'react';
import { DeviceEventEmitter, Navigator, Text, TouchableOpacity, View } from 'react-native';
import Drawer from 'react-native-drawer';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { EventEmitter } from 'fbemitter';
import Menu from './Menu';
import HomePage from './HomePage'
import ProfilePage from './ProfilePage'
import navigationHelper from '../helpers/navigation';
import styles from '../styles/root';
let _emitter = new EventEmitter();
class App extends Component {
componentDidMount() {
var self = this;
_emitter.addListener('openMenu', () => {
self._drawer.open();
});
_emitter.addListener('back', () => {
self._navigator.pop();
});
}
render() {
return (
<Drawer
ref={(ref) => this._drawer = ref}
type="overlay"
content={<Menu navigate={(route) => {
this._navigator.push(navigationHelper(route));
this._drawer.close()
}}/>}
tapToClose={true}
openDrawerOffset={0.2}
panCloseMask={0.2}
closedDrawerOffset={-3}
styles={{
drawer: {shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3},
main: {paddingLeft: 3}
}}
tweenHandler={(ratio) => ({
main: { opacity:(2-ratio)/2 }
})}>
<Navigator
ref={(ref) => this._navigator = ref}
configureScene={(route) => Navigator.SceneConfigs.FloatFromLeft}
initialRoute={{
id: 'HomePage',
title: 'HomePage',
index: 0
}}
renderScene={(route, navigator) => this._renderScene(route, navigator)}
navigationBar={
<Navigator.NavigationBar
style={styles.navBar}
routeMapper={NavigationBarRouteMapper} />
}
/>
</Drawer>
);
}
_renderScene(route, navigator) {
switch (route.id) {
case 'HomePage':
return ( <HomePage navigator={navigator}/> );
case 'ProfilePage':
return ( <ProfilePage navigator={navigator}/> );
}
}
}
const NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
switch (route.id) {
case 'HomePage':
return (
<TouchableOpacity
style={styles.navBarLeftButton}
onPress={() => {_emitter.emit('openMenu')}}>
<Icon name='menu' size={25} color={'white'} />
</TouchableOpacity>
)
default:
return (
<TouchableOpacity
style={styles.navBarLeftButton}
onPress={() => {_emitter.emit('back')}}>
<Icon name='chevron-left' size={25} color={'white'} />
</TouchableOpacity>
)
}
},
RightButton(route, navigator, index, navState) {
return (
<TouchableOpacity
style={styles.navBarRightButton}>
<Icon name='more-vert' size={25} color={'white'} />
</TouchableOpacity>
)
},
Title(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
{route.title}
</Text>
)
}
}
export default App;
Menu.js
import React, { Component } from 'react';
import { ListView } from 'react-native';
import Button from 'react-native-button';
import styles from '../styles/menu'
var _navigate;
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
};
_navigate = this.props.navigate;
}
componentDidMount() {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(['HomePage', 'ProfilePage'])
});
}
_renderMenuItem(item) {
return(
<Button style={styles.menuItem} onPress={()=> this._onItemSelect(item)}>{item}</Button>
);
}
_onItemSelect(item) {
_navigate(item);
}
render() {
return (
<ListView
style={styles.container}
dataSource={this.state.dataSource}
renderRow={(item) => this._renderMenuItem(item)}
/>
);
}
}
module.exports = Menu;
ProfilePage.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import styles from '../styles/home'
class ProfilePage extends Component {
render(){
return (
<View style={styles.container}>
<Text>Profile Page</Text>
</View>
);
}
}
module.exports = ProfilePage;
HomePage.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import styles from '../styles/home'
class HomePage extends Component {
render(){
return (
<View style={styles.container}>
<Text>Home Page</Text>
</View>
);
}
}
module.exports = HomePage;
navigation.js
import React, { Platform } from 'react-native';
import _ from 'underscore';
module.exports = function (scene) {
var componentMap = {
'HomePage': {
title: 'HomePage',
id: 'HomePage'
},
'ProfilePage': {
title: 'ProfilePage',
id: 'ProfilePage'
}
}
return componentMap[scene];
}
Firstly, you need to install the react-navigation package:
npm install --save react-navigation
To make it easier and more comfortable, I put every lines of codes and comments in my App.js file
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
import { DrawerNavigator } from 'react-navigation';
// Create HomeScreen class. When 'Home' item is clicked, it will navigate to this page
class HomeScreen extends Component {
render() {
return <Text> Home Page </Text>
}
}
// Create ProfileScreen class. When 'Profile' item is clicked, it will navigate to this page
class ProfileScreen extends Component {
render() {
return <Text> Profile Page </Text>
}
}
// Create SettingsScreen class. When 'Settings' item is clicked, it will navigate to this page
class SettingsScreen extends Component {
render() {
return <Text> Settings Page </Text>
}
}
const RootNavigation = DrawerNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen},
Settings: { screen: SettingsScreen}
});
export default class App extends Component {
render() {
return <RootNavigation />
}
}
Here is my demo
Download source code from here (Navigation Drawer In React Native)
Create a navigation drawer menu like following:
const MyDrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen,
},
Settings: {
screen: SettingScreen,
},
Profile:{
screen: ProfileScreen
}
});
const MyAppdrawer = createAppContainer(MyDrawerNavigator);
Thanks!