I am trying to detect screen rotation in Webkit on my Motorola Droid 1. I have the following JavasCript code:
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
alert("screen.width: " + screen.width + ", window.orientation: " + window.orientation);
}, false);
The problem is: it alerts screen.width 569 when the phone is rotated in portrait, and 320 when it is rotated in landscape. This does not any sense to me! Can somebody clarify?
Thank you,
Igor
I bet you are running Android 2.2. There is a bug in the browser's reporting of width and height. See screen.width + android and Shouldn't window.screen.width/height correspond to actual screen width/height? for starters.
I wish I had something better to offer than the setTimeout() workaround in that first post, but that may be the best you can do. (I'd love to be wrong about that, so if someone knows a better solution, please share!)
Related
I'm developing in qt 5.3 on android device. I can't get the screen resolution.
With the old qt 5 version this code worked:
QScreen *screen = QApplication::screens().at(0);
largh=screen->availableGeometry().width();
alt =screen->availableGeometry().height();
However now it doesn't work (returns a screen size 00x00). Is there another way to do it? thanks
Size holds the pixel resolution
screen->size().width()
screen->size().height();
Whereas, availableSize holds the size excluding window manager reserved areas...
screen->availableSize().width()
screen->availableSize().height();
More info on the QScreen class.
for more information, screen availableSize is not ready at the very beginning, so you have to wait for it, here is the code:
Widget::Widget(QWidget *parent){
...
QScreen *screen = QApplication::screens().at(0);
connect(screen, SIGNAL(virtualGeometryChanged(QRect)), this,SLOT(getScreen(QRect)));
}
void Widget::getScreen(QRect rect)
{
int screenY = screen->availableSize().height();
int screenX = screen->availableSize().width();
this->setGeometry(0,0,screenX,screenY);
}
I found that there are several ways to obtain the device resolution, each outputs the same results and thankfully works across all Os-es supported by Qt...
1) My favorite is to write a static function using QDesktopWidget in a reference class and use it all across the code:
QRect const CGenericWidget::getScreenSize()
{
//Note: one might implement caching of the value to optimize processing speed. This however will result in erros if screen resolution is resized during execution
QDesktopWidget scr;
return scr.availableGeometry(scr.primaryScreen());
}
Then you can just call across your code the function like this:
qDebug() << CGenericWidget::getScreenSize();
It will return you a QRect const object that you can use to obtain the screen size without the top and bottom bars.
2) Another way to obtain the screen resolution that works just fine if your app is full screen is:
QWidget *activeWindow = QApplication::activeWindow();
m_sw = activeWindow->width();
m_sh = activeWindow->height();
3) And of course you have the option that Zeus recommended:
QScreen *screen = QApplication::screens().at(0);
largh=screen->availableSize().width();
alt =screen->availableSize().height();
I have worked so hard on an app that displays perfectly on my Galaxy Note 3. However, it does not display right on iPhone and also one other Droid I tested on. My issue is with addChild() and then resizing it to fit the screen. For some reason when I add the Background (addBG(); The screen size works but if I load addChild to the BG, this works great on my Note 3 but not on the iPhone or another android device.
My issue is with the screenX, screenY var I created. They seem to be different for devices. Or it is a "rendering order issue" I am not sure. Would be so greatful for the help to fix this issue so it looks great on each phone. I have read some tuts on this subject but they are confusing. I think my code is close, I hope, and maybe it just needs a tweak. !
Here is a shot of the about screen on an IPhone. See the white does not fit the whole screen.
and Here is a shot from my Droid Note 3.
Declared Vars in a package:
This is not my full code, of course but only that which I believe is relevant.
public var screenX:int;
public var screenY:int;
public function Main()
{
if (stage)
{
setStage();
addBG();
}
}
public function setStage()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
if (flash.system.Capabilities.screenResolutionX > stage.stageWidth)
{
screenX = stage.stageWidth;
screenY = stage.stageHeight;
}
else
{
screenX = flash.system.Capabilities.screenResolutionX;
screenY = flash.system.Capabilities.screenResolutionY;
}
}
This works: addBG();
public function addBG()
{
theBG = new BG();
addChild(theBG);
theBG.width = screenX;
theBG.height = screenY;
}
This does not: addAbout();
public function addAbout()
{
About = new viewAbout();
About.width = screenX;
About.height = screenY;
theBG.addChild(About);
TweenMax.fromTo(About,1, {alpha:0}, {alpha:1, ease:Expo.easeOut} );
}
UPDATE: And yet another more complex load is also called from a button and having the same issue. I hope you see the logic of what I am trying to do. First set the BG to the device then load and resize content to fit proportionally into the BG I loaded. The reason being, the BG will be distorted to different proportions and that's ok, but the content can not. So here is the example that loads content into the BG and then content into that container.
public function addRosaryApp()
{
Rosary = new viewRosaryApp();
Rosary.width = screenX;
Rosary.height = screenY;
theBG.addChild(Rosary);
TweenMax.fromTo(Rosary,1, {alpha:0}, {alpha:1, ease:Expo.easeOut} );
contentRosary = new contentRosaryApp();
theBG.addChild(contentRosary);
contentRosary.width = screenX;
contentRosary.scaleY = contentRosary.scaleX;
contentRosary.x = screenX/2 - contentRosary.width/2;
contentRosary.y = menuBanner.height;
}
Have you tried adding the child to stage first, and then setting the size? That's the only difference I can see between addBG and addAbout
About = new viewAbout();
theBG.addChild(About); // do this first
About.width = screenX; // then set width
About.height = screenY; // and height
I think your problem may have to do with either of several things.
My findings so far from my own devices (an Ipad Air, an iphone 4S, an LG G2 and an Acer Iconia A500) is that the only device size that's being reported correctly at all times is the stage.fullScreenWidth and the stage.fullScreenHeight
1st, Android reports Capabilities.screenResolutionX as the LONG side of your Android device.
IOS devices however report the SHORT side of your device to Capabilities.screenResolutionX.
2nd, stage.stageWidth and stage.stageHeight seem to report the wrong size on both Android and IOS.
And in fact if you check these before and after setting stage.scaleMode and stage.align then the values will differ completly (although Android will show it almost correctly).
My suggestion is that you set a base size (width and height) for your app and then compare it with the actual stage.fullScreenWidth and stage.fullScreenHeight reported by the device. That way you can get some nice scaleratios to use to scale your displayobjects. That's what I'm currently on my apps and it scales just fine :-)
i can get the window.innerWidth or window.innerHeight on mobile platforms
such as android of iphone.
var w = window.innerWidth;
but i want to set it back to its old value, i mean when the user zooms by pinch, the innerWidth and innerHeight values are changed. i can get the new values, but i want that
the screen size is back to its old position, but i could never change the size by
window.innerWidth = foo;
window.innerWidth = 'foopx';
window.resizeTo(foo,bar);
None of them worked in android or in iphone, ipad (safari, mobile chrome) above.
How can i remove the effect of pinch zoom? I do not want to block it or disable, user may zoom but after the zoom action i want to de-zoom to back its original position.
how can resize(change) window.innerWidth, innerHeight values?
I present to you, an ugly kludge, but so far the only way i know how to do what you want.
Let's say that in your html you've got
<meta id="myViewPort" name="viewport" content="whatever" />
Then in a script somewhere you've got this
function resetScale()
{
var viewport = document.getElementById('myViewPort')
var content = viewPort.content;
viewport.content = 'what=ever, user-scalable=no';
window.setTimeout(function()
{
viewport.content = content;
},1);
}
Yes, the timeout is required. Without it, the scale is not reset.
Also, the viewport takes a moment before it will notice that user-scalable is no longer urned off. I've had delays as long as 10 seconds before you can start zooming again, and other times where you can start zooming immediately.
When you hide the addressbar in WebbApps you got nearly the feeling of native Apps. Unfortunately, to hide the address bar works in jQuery mobile only if the content is large enough. If the content is too small it does not work - also with fullscreen and fixed footer - see http://jquerymobile.com/demos/1.2.0/docs/toolbars/bars-fixed.html. Reason appears to be a bug in the browser in Android. If the content is too small the jQuery funktion $(window).height() delivers only 450px as screen height (I'm using Android 2.3.6 with a Galaxy S2). The height of the addressbar is missing. Is the content big enough the function delivers 508px - as expected. Also a quite good approach - http://www.semicomplete.com/blog/tags/jquery%20mobile -does not work. I found a solution which works but need a delay of 500ms. It brings a flipping adressbar when you load a page for a small time. Is there an another approch, that there is no flipping of the addressbar?
But maybe someone has an idea how this could work even better. And does it work well with iOS? It would be great if someone could test this with an iPhone.
Thanks in advance.
Here the code:
var fixgeometry = function() {
/* Calculate the geometry that our content area should take */
var header = $(".header:visible");
var footer = $(".footer:visible");
var content = $(".content:visible");
var viewport_height = $(window).height()+60; /*Here is the idea! Make it bigger here and make it later smaller*/
var content_height = viewport_height - header.outerHeight() - footer.outerHeight();
/* Trim margin/border/padding height */
content_height -= (content.outerHeight() - content.height());
content.height(content_height);
setTimeout(function(){
window.scrollTo(0, 1);
content.height(content_height-60); }, 500 );
};
$(document).ready(function(){
$(window).bind("orientationchange resize pageshow", fixgeometry);
});
The scrollTo-function is implemented in jQuery, but it doesnt work after an oriantationchange or an input in a textfield. So its necessary here in the setTimeout-function.
I am developing an android application in phonegap / HTML5.
As its first step I am taking device's width using
var viewport = {
width : parseInt($(window).width()),
height : parseInt($(window).height())
};
alert(viewport.width);
But first time wile deploying its showing 320 as alert, but when I restart application its showing 0. after that oftenly showing 320 ( in rare )
How to get the actual width of the device permanently ?
Sorry for my typos
have you tried this
$(function(){
document.addEventListener("deviceready", function() {
var windowWidth = $(window).width();
var windowHeight = $(window).height();
});
});
This question is made every now and then. See my previous answer at, and read the blog article itself: JavaScript+Phonegap+Android: screen.width returns bad (almost random) values
Hope this helps you out.