I am writing a react native app and need to implement keyboard events inside components.
I tried with following code and did not success.
import { DeviceEventEmitter } from 'react-native';
export default class KeyEvent {
static onKeyDownListener(cb) {
KeyEvent.removeKeyDownListener();
console.log('Key Down');
this.listenerKeyDown = DeviceEventEmitter.addListener('onKeyDown', cb);
}
static removeKeyDownListener() {
if (this.listenerKeyDown) {
this.listenerKeyDown.remove();
}
}
static onKeyUpListener(cb) {
console.log('Key up');
KeyEvent.removeKeyUpListener();
this.listenerKeyUp = DeviceEventEmitter.addListener('onKeyUp', cb);
}
static removeKeyUpListener() {
if (this.listenerKeyUp) {
this.listenerKeyUp.remove();
}
}
}
Call inside componentDidMount function relevant component as follows.
componentDidMount() {
console.log('componentDidMount');
// if you want to react to keyDown
KeyEvent.onKeyDownListener((keyCode) => {
console.log(`Key code pressed: ${keyCode}`);
});
// if you want to react to keyUp
KeyEvent.onKeyUpListener((keyCode) => {
console.log(`Key code pressed: ${keyCode}`);
});
}
componentWillUnmount() {
console.log('componentWillUnmount');
// if you are listening to keyDown
KeyEvent.removeKeyDownListener();
// if you are listening to keyUp
KeyEvent.removeKeyUpListener();
}
Can anyone help me to fix this or suggest any other way of doing this. I need to press a button on enter key down.
As per react native doc, you can attach below events to keyboard.
keyboardWillShow
keyboardDidShow
keyboardWillHide
keyboardDidHide
keyboardWillChangeFrame
keyboardDidChangeFrame
So if you want pressed key event then you need to attach event to input field like below.
<TextInput
onKeyPress={this.handleKeyDown}
placeholder="Enter text here..."
/>
handleKeyDown: function(e) {
if(e.nativeEvent.key == "Enter"){
dismissKeyboard();
}
},
Related
I want to perform some actions when my app goes to the background—e.g., when pressing the home button. (I am testing on an Android device.)
I tried the following in my app.component.ts:
this.platform.ready().then(() => {
this.platform.pause.subscribe(async () => {
alert("Pause event detected");
//Do stuff here
});
this.platform.resume.subscribe(async () => {
alert("Resume event detected");
//Do stuff here
});
…
I also tried:
App.getState().then((result) => {
alert("state active?" + result.isActive);
});
No listener is triggered when the app goes to background (e.g., by pressing the home button). But when I start the app again, all events are triggered (in this case, the alerts), including the platform.pause event.
I am using Ionic 9 and Capacitor.
Am I misunderstanding something? What could be the problem?
You can use the event listeners provided in Capacitor's App API.
// Import the relevant stuff from Capacitor
import { Plugins, AppState } from '#capacitor/core';
const { App } = Plugins;
Then in your AppComponent class
this.platform.ready().then(() => {
App.addListener('appStateChange', (state: AppState) => {
if (state.isActive) {
console.log('App has become active');
} else {
console.log('App has become inactive');
}
});
})
Note that you can test this in a desktop browser as well by switching to another tab.
Ok... things work. The problem was, that I had both variants in code active.
I am trying to disabling the physical device back in android only in some screens. Trying the below code is not working. Any idea?
import { RouterExtensions } from "nativescript-angular";
import * as application from "application";
import { AndroidApplication, AndroidActivityBackPressedEventData } from "application";
import { isAndroid } from "platform";
export class ItemComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit() {
if (!isAndroid) {
return;
}
application.android.on(AndroidApplication.activityBackPressedEvent, (data: AndroidActivityBackPressedEventData) => {
data.cancel = true; // prevents default back button behavior
});
}
}
#Override
public void onBackPressed() {
if (!shouldAllowBack()) {
doSomething();
} else {
super.onBackPressed();
}
}
Add this code in your activity-
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Your Code Here. Leave empty if you want nothing to happen on back press.
}
For more information visit this link.
Back button is controlled at Activity level, NativeScript uses one single Activity and all your pages / routes are fragments inside that.
So you don't have to call it on every page / component. Add the listener to your app component and check the router to know which page you are at and cancel the back event.
Use location and check if location consists the desired path(as mentioned in routing file) where you want to use your custom function.
import { Location } from '#angular/common';
constructor(private _location: Location
){}
if (application.android) {
application.android.on(AndroidApplication.activityBackPressedEvent, (data: AndroidActivityBackPressedEventData) => {
const path = this._location.path();
console.log(`path i s--> ${path}`);
switch (path) {
case '/Screen 1':
data.cancel = true;
break;
case '/Screen 2':
//do something else
break;
});
}
I have an ionic 3 app based on the super template. I have set the root page to the following:
<ion-tabs>
<ion-tab [root]="tab1Root" [tabTitle]="tab1Title" tabIcon="bonfire"></ion-tab>
<ion-tab [root]="tab2Root" [tabTitle]="tab2Title" tabIcon="search"></ion-tab>
<ion-tab [root]="tab3Root" [tabTitle]="tab3Title" tabIcon="cog"></ion-tab>
</ion-tabs>
When I press the hardware back button on this page, nothing happens at all. However, when I change the content to something else, like:
<p>Hello</p>
Then the hardware back button exits, as I would like.
How can I make the hardware back button work correctly on the tabbed page, while preserving the working default behaviour on other pages?
Inside your app.component.ts file
import { Nav, App } from 'ionic-angular';
export class MyApp {
#ViewChild(Nav) nav: Nav;
and then
platform.registerBackButtonAction(() => {
let nav = app.getActiveNav();
let activeView: ViewController = nav.getActive();
if(activeView != null){
if(nav.canGoBack()) {
nav.pop();
}else if (typeof activeView.instance.backButtonAction === 'function')
{
activeView.instance.backButtonAction();
}
else {
nav.parent.select(0); // goes to the first tab
}
}
});
Hope this helps you and also don't forget to place it inside the platform.
in your respcted ts file where you need to close the application write a funtion
backButtonAction(){
this.platfrom.exitApp();
}
I ended up needing to do this in app.container.ts to get the desired behaviour:
platform.registerBackButtonAction(() => {
let nav = app.getActiveNav();
let activeView = nav.getActive();
if (activeView != null){
if (nav.canGoBack()) {
nav.pop();
} else if (nav.parent.getSelected() != nav.parent.getByIndex(0)) {
// goes to the first tab
nav.parent.select(0);
} else {
platform.exitApp();
}
}
});
In your Tabs Page try to Add ionViewDidEnter and try to append the following class as follows:
ionViewDidEnter() {
this.platform.registerBackButtonAction(() => {
this.platform.exitApp();
});
}
Write your code inside the constructor() from which page you to leave.
Home.ts
constructor(
public navCtrl: NavController,
private platform: Platform) {
this.platform.registerBackButtonAction(()=>{
this.platform.exitApp();
});
}
I have an app (Webview exactly) and I'm trying to handle the Android hardware button to return from the second page for example to the first one. My problem now is the button won't close the app anymore, and I don't know what should I do. Here is my code:
export default class App extends Component {
constructor(props) {
super(props)
this.state={
};
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress',this.handleBackButtonClick);
}
componentWillUnmount() { BackHandler.removeEventListener('hardwareBackPress',this.handleBackButtonClick);
}
onNavigationStateChange(navState){
console.log(JSON.stringify(navState));
canGoBack = navState.url == initialUrl && !navState.loading
}
handleBackButtonClick() {
this.refs[WEBVIEW_REF].goBack();
return true;
}
The return value of handleBackButtonClick determines whether the app is to be kept running or not.
Currently, you are always returning true. Instead, you could check whether the current navigation state is such that you would like to close the app, and return false accordingly.
handleBackButtonClick() {
const canGoBack = someCalculation();
if(canGoBack)
this.refs[WEBVIEW_REF].goBack();
}
return canGoBack;
}
I have splash screen on my apps, so I want to exit the apps when we click android back button from the main page (not go back to splash screen). So I want to implement this method from react-native tutorial.
if (!this.onMainScreen()) {
this.goBack();
return true;
}
return false;
Is there anyone can help me how to implement onMainScreen(), and goBack() functions?
Thank you for the help.
you should be able to use this function
function getCurrentRouteFromState(navigationState): NavigationRouteConfigMap {
const route = navigationState.routes[navigationState.index];
// dive into nested navigators
if (route.routes) {
return getCurrentRouteFromState(route);
}
return route;
}
pass it your navigation state and access the routeName member on the resulting object:
let screenName = getCurrentRouteFromState(state).routeName then you can compare the screen name with your main screen name and decide what to do.
So, On your main page(I think which is your Main.js)
import { BackHandler } from 'react-native';
componentWillMount(){
BackHandler.addEventListener('hardwareBackPress', function() {
BackHandler.exitApp();
});
}