I would like to ask if there is a way to hide a nav bar of the ionic framework on a particular view upon changing in the screen orientation from portrait to landscape.
Yes you can, it's very easy.
This is a function you need to trigger to hide a navbar:
$ionicNavBarDelegate.showBar(false);
Of course, do it inside an appropriate Controller.
The second part of this formula is Cordova Orientation plugin, click here.
So when combined you would want something like this:
if(screen.orientation == 'landscape') {
$ionicNavBarDelegate.showBar(false);
}
There's also a JavaScript approach to detect an orientation, but it's a hit and miss solution on some devices. Cordova plugin i much safer solution.
This is not everything, what if user change orientation after view initialization:
window.addEventListener('orientationchange', doOnOrientationChange);
// Initial execution if needed
doOnOrientationChange();
function doOnOrientationChange()
{
if(screen.orientation == 'landscape') {
$ionicNavBarDelegate.showBar(false);
}
}
Related
how to reload a page (with a new template) when the orientation of the device changes?
I want a different layout in landscape mode. This is in NativeScript, not Java.
the correct xml file is selected if i arrive at the page in landscape, but if i change orientation, nothing gets reloaded.
Note that this is not a question of refreshing the CSS, it is a different XML file needed.
NativeScript solution:
First you need to tie into the orientation event. You have a couple ways you can tie into that event.
The first and easiest method is to install the nativescript-orientation plugin, it ties into the event globally and then it will just automatically run your exported function on each of the current page called orientation, each time the orientation changes.
To Install:
tns plugin install nativescript-orientation
Open your app.js file and add at the top of the file;
require('nativescript-orientation');
Then by creating:
exports.orientation = function(args) {
if (args.landscaped) { /* do landscape stuff */ }
else { /* do port */
};
on any page you want to be notified that the orientation changed, it will be called on those pages that have that function and you can handle the event how you need to.
However, if you prefer to not use a plugin, you can directly tie into the orientation event yourself by doing:
var application = require('application');
exports.onNavigateTo = function() {
application.on(application.orientationChangedEvent,myOrientationFunction);
}
exports.onNavigateFrom = function() {
application.off(application.orientationChangedEvent, myOrientationFunction);
function myOrientationFunction(args) {
// We have an orientation event
}
However you must ask to be notified of the event when your page first open and you must remove your self from the notification when your page closes. This is a lot of extra code per page that the plugin above just handles for you. Please note when you are doing this yourself you also need to to add the NavigateTo/NavigatedFrom to the <Page> tag in your Declarative UI XML file, otherwise those functions won't be called.
Ok, now that you have the event which ever way you prefer; lets look at how we can make your idea work.
Now, you are asking to switch layouts each time the page changes; this is typically the worst thing to do; but I will answer it first and then give you the alternative method that I use to do complex layouts that work in both Portrait and Landscape modes pretty much automatically.
MyPage-Landscape.xml
<Page><StackLayout><Label text="Landscape"/></StackLayout></Page>
MyPage-Portrait.xml
<Page><StackLayout><Label text="Portrait"/></StackLayout></Page>
MyPage-Landscape.js
var commonPage = require("./MyPage.js");
var frame = require('ui/frame');
exports.orientation = function(args) {
if (args.landscape === false) {
frame.topmost().navigate('MyPage-Portrait');
}
};
// Tie all the common page code into this pages exports
for (var key in commonPage) {
if (commonPage.hasOwnProperty(key)) {
exports[key] = commonPage[key];
}
}
MyPage-Portrait.js
var commonPage = require("./MyPage.js");
var frame = require('ui/frame');
exports.orientation = function(args) {
if (args.landscape === true) {
frame.topmost().navigate('MyPage-Landscape');
}
};
// Tie all the common page code into this pages exports
for (var key in commonPage) {
if (commonPage.hasOwnProperty(key)) {
exports[key] = commonPage[key];
}
}
MyPage.js
exports.TapHandler = function() { /* Someone Tapped */ }
exports.someOtherLogic = function() { /* More logic */ }
exports.etc = function() { /* etc */ }
You put all your common page logic in the MyPage file; but you specifically navigate to the specific landscape or portrait page; and each of them are responsible to navigate to the other version if the page orientation changes.
Notes about the above solution:
You need to navigate to the proper version of the page from any other page; ie. if you are in Landscape mode; when you navigate to another page; you need to make sure you navigate to the Landscaped version of the page.
the NS-Orientation plugin does give you a handle helper function to find out the current orientation to make this easier.
Remember to make the MyPage.js have all the common code; you want to try and eliminate any custom code on a specific page version.
Their is a frame reload command you can use; however it totally clears the history; meaning you can't navigate backwards. i.e. Page1 -> Page2, frame.reloadPage() means that the back button will NOT go back to Page1. If this is acceptable; you can make the above system a lot simpler; rather than create separate xml & js files you just need a myPage.landscape.xml and myPage.portrait.xml and you need to on every orientation change just call the frame.reloadPage();
Now to me the above is some serious overkill for what is probably a simple change that you need done between pages. So I'm going to describe how I do it in my apps; which has some pretty complex screens but they look very nice and completely change functionality on a orientation change.
This is part of the reason the NativeScript-orientation plugin was written. On a page orientation change will automatically add / remove a "landscape" class name to the <Page> element in your XML. What this allows you to do in your CSS is:
.myLabel {
font-size: 12;
background-color: blue;
height: 20;
}
.landscape .myLabel {
font-size: 16;
background-color: green;
height: 40;
}
If you haven't figured out where I am going with this; this allows you to have custom CSS for the page while in landscape mode vs it being in portrait mode. In addition when you use the exports.orientation function in union with it also you can then run custom code depending on the orientation.
So in my case; On a phone my scroll list is a single scroll list of items going up down and is sized perfectly to the screen, and looks very sharp. When you switch to landscape mode; it hides the actionbar, adds a fab button, resizes the entire grid item to fit with the same proportions and switches scrolling modes to right-left. The majority of the entire look change is done in pure css; and the rest is done in the exports.orientation function which handles things like switching scroll direction.
Disclaimer: I am the author of the NativeScript-orientation plugin
In your activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.my_layout);
}
Make sure you have layout XML with same name for both orientations
res/layout/my_layout.xml
res/layout-land/my_layout.xml
With correct resource file names Android system automatically reloads your Activities/Fragments with proper resources.
You can catch and handle events manually by setting android:configChanges (but it is a rare case).
Check some documentation:
Handling Runtime Changes
Providing Resources
I'm a newbie to Ionic framework. Is there a way to open the menu on the landscape mode, closing it while it changes to portrait mode and vice versa similar to this one, Hiding the Ionic Framework Header based on screen orientation.
By using,
window.addEventListener("orientationchange", function(){
});
I can able to detect the orientation change but couldn't find a way to hide/show the menu. And is there way to do this using CSS'
/* portrait */
#media screen and (orientation:portrait) {
}
/* landscape */
#media screen and (orientation:landscape) {
}
And if both are possible, which is the preferred way of handling this situation?
You can use the service $ionicSideMenuDelegate to open or close the menu programatically.
.controller('AppCtrl', function($scope, $ionicSideMenuDelegate) {
// ˆˆˆˆ injected ˆˆˆˆ
window.addEventListener("orientationchange", function(){
$ionicSideMenuDelegate.toggleLeft(window.orientation !== 0);
});
})
Remember to inject the service $ionicSideMenuDelegate in your controller. In this example I injected $scope and $ionicSideMenuDelegate in the AppCtrl.
This works on iOS and Android!
I have this example: http://codepen.io/poliveira89/pen/VeZLJX/
One this example, I have a <ion-nav-view></ion-nav-view> where I insert a Tab View with 2 tabs (Home and About) with nested views and nested states, as well.
My main focus: retrieve screen/device orientation and dynamically rearrange content for Portrait and Landscape orientation.
On the Home tab is what I "pretend" to achieve => update View (HTML) regarding the Models changes after a screen rotation. Which clearly does not work on emulator and real device.
I duplicated the example on About tab, because on Home tab does not work, but I have changed the code a little bit I have tried some "refresh" trigger with a button (ng-click) and $timeout with an alert. And when I click the button the View refresh the HTML with the new values on Model.
Note: I have tried with other triggers - $http, $interval, ...
I thought that could be something related to "cache" on the NavView, like this:
.state('tabs.home', {
url: "/home",
cache: false,
views: {
'home-tab': {
templateUrl: "templates/home.html",
controller: 'HomeCtrl'
}
}
})
But, after I disable it, nothing have changed and still does not work.
PS: Screen Rotation/Orientation listener works, on emulator and real device, I have debugged on console messages.
What could be not working properly on Angular or Ionic? Or why only updates the View after the triggers?
It's because you're updating the $scope outside of the Angular digest loop.
Try:
$scope.$apply(function() {
$scope.orientation = $window.orientation;
});
I create a web page(chrome & safari) for mobiles (iphone & android), I want to lock the screen orientation in portrait mode.
Unlike mobile apps,there is no manifest file and activity as it a web page.
How to lock the orientation in mobiles using technologies (css/javascript/bootstrap/jquery) or any other?
I use a manifest file for my web app, which locks orientation for Chrome on my Android. For whatever reason, Safari gives their users the "right" to do this, but not the designers of the web app... Sort of feels like copyright infringement or something! ;) Don't get me started on Safari's disgraceful rewriting/rendering of input buttons!...
Anyways, back to the answer.
1) Include a link to your manifest within the head section of your page:
<link rel="manifest" href="http://yoursite.com/manifest.json">
2) Create your manifest file, "manifest.json"
{
"name":"A nice title for your web app",
"display":"standalone",
"orientation":"portrait"
}
3) Read more about manifests HERE
From my tests, assigning the screen.lockOrientation ( every browser versions ) to a var throw an illegal invocation error. Just use wind.screen.orientation.lock('landscape'); . It
EDIT: You can't use lock orientation on safari, cause it doesn't support fullscreen api at the moment http://caniuse.com/#feat=fullscreen . The lock orientation API NEED a fullscreen page to work. In Chrome, the window.screen.orientation.lock return a promise. So, AFTER you go fullscreen with the page, you can do something like this :
var lockFunction = window.screen.orientation.lock;
if (lockFunction.call(window.screen.orientation, 'landscape')) {
console.log('Orientation locked')
} else {
console.error('There was a problem in locking the orientation')
}
However, the lock orientation and fullscreen API are still experimental, not all browsers supports it.
The lockOrientation method locks the screen into the specified orientation.
lockedAllowed = window.screen.lockOrientation(orientation);
From the following code, you can check that orientation is locked or not.
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
if (lockOrientation("landscape-primary")) {
// orientation was locked
} else {
// orientation lock failed
}
see the following link, you will get idea from this.
https://developer.mozilla.org/en-US/docs/Web/API/Screen.lockOrientation
You can use:
screen.addEventListener("orientationchange", function () {
console.log("The orientation of the screen is: " + screen.orientation);
});
and
screen.lockOrientation('landscape');
Following: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Managing_screen_orientation
after fixing another problem in my Android Application, i came to another thing.
It would be important that i can do something, like hide some visual elements, if the SoftKeyboard so a Input like Swipe or the normal Android Keyboard is shown.
I've tried the onConfigurationChange="KeyboardShow" (pseudocode) but had no change to get a event when for example skype got shown.
So now my question is, is there any solution or function or listener, with which i can handle such a action?
I hope someone can help me.
Sincerly,
Mike Penz
There might be better approaches, but a possibility is to add: android:configChanges="keyboardHidden" to the manifest. That will fire with any keyboard changes, so the you will need to query the Configuration object
static Configuration prevConf = Configuration();
static int ignoreMasks = Configuration.HARDKEYBOARDHIDDEN_NO|Configuration.HARDKEYBOARDHIDDEN_YES;
onCreate() {
prevConf = setToDefaults();
}
// all your code here
#Override
public void onConfigurationChanged (Configuration newConfig) {
int deltas = newConfig.diff (prevConf); // what changed?
prevConf = newConfig;
if (delta & ignoreMasks)
return; // you're not interested in hard keyboards.
// your code here
}
I suck at bitwise operators, so you might need to work around that.
This is the API documentation:
http://developer.android.com/reference/android/R.attr.html#configChanges
http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged%28android.content.res.Configuration%29
http://developer.android.com/reference/android/content/res/Configuration.html