PDA

View Full Version : Sencha + Phonegap orientation problem



oonox
23 Jul 2010, 3:12 AM
Hi,

For sencha team thank you for this beautiful tools ! Sencha is the best way for webapp !

So my problem. My web app work perfectily and whan i change the orientation, no problem.

But when i embed my webapp via phone gap the orientation change keep the initial position.

I found this solution then i use with a onOrientationChange of panel :

http://stackoverflow.com/questions/2581957/iphone-safari-does-not-auto-scale-back-down-on-portrait-landscape-portrait

but doesn't work ! any pist or way where i can find a solution ?

Thx

Fabien

CodeAmigo
23 Jul 2010, 7:02 AM
I am having the same problem. I am using the Kitchen Sink demo and PhoneGap. The orientation adjustment happens in the browser fine but when you run it on an iPad or the simulator with PhoneGap, the onOrientationChange function/listener does not seem to work, except on first load. Please help!

oonox
26 Jul 2010, 7:01 AM
so the phonegap don't send the onorientationchange event and use the orientationchanged event init by the phonegap.js.

But phonegap.js gave error with sencha.

i found this solution : http://groups.google.com/group/phonegap/browse_thread/thread/6da50c82cb7ae738/73438ccb9111c2ca?lnk=gst&q=onorientationchange#73438ccb9111c2ca

if i have more information i post the solution here.

see you.

Fabien

arlo.carreon
30 Jul 2010, 7:27 AM
Hey Fabien,

I have been following your threads since yesterday. I am also trying to launch an iPad app into the app store and my final step is getting the orientation to change on the ipad with Sencha and PhoneGap.

So far, this is the only thing that has worked for me:



<script>
document.addEventListener("orientationChanged", yourCallbackFunction, false);
</script>


I added that line to the index.html file and I created a function in my sencha file for the callback.

Sencha app.js


function yourCallbackFunction()
{
//alert("PhoneGap has triggered the event!");

// Now I need to have Sencha refresh the Panel?
}


So, basically now I am trying to get Sencha to "refresh" or stretch out on the screen like when it first starts. I have tried doLayout(), but that did not work.

If you have some luck with this let me know.

arlo.carreon
30 Jul 2010, 1:27 PM
Fabien,

I finally got this to work. I had the same problem you were having with PhoneGap and Sencha. Apparently Sencha, does recognize the WindowResize event so I used that event to manually resize my main Panel.



new Ext.setup({
glossOnIcon: false,
onReady:
function()
{
// Regular EXT JS application code here
// ......

// Setup a callback for WindowResize Event
Ext.EventManager.onWindowResize( senchaChangeOrientation );
}
});

// Callback
function senchaChangeOrientation()
{
if(Ext.getOrientation()=="landscape")
{
mainPanel.setSize(1024,748);
mainPanel.doLayout();
}else
{
mainPanel.setSize(768,1004);
mainPanel.doLayout();
}

}


Keep in mind that in the above code, my main panel is the variable name "mainPanel". This worked like a charm.

oonox
3 Aug 2010, 12:19 AM
Many thanks for your answers ! i test these solution and it work fine !

lteti77
10 Aug 2010, 11:14 PM
hi, i'm a newbie sencha user so probably my question is very "dummy"...
i have a similar problem using sencha-phonegap.


my application should display 2 different view:

in portrait, i want a long test with scrolling enabled
in landscape, i need to display an image that fits the screen bounds with no scrolling at all
rotating the device the app should switch between the views.
I created an html with 2 'divs' containing the 2 views: they are included in a container 'div' called my-div and are made visible/invisible using css media queries.
then i created a fullscreen panel with the content of my-div and tried to catch window resize event in order to set the panel size as in the example above. but it didn't worked...

When i'm in portrait and scroll to bottom and then i rotate to landscape, the scrolling is still active and the image is not visible because is on the top and i have to scroll to view it...



new Ext.setup({
onReady:
function(){
mainPanel = new Ext.Panel {
contentEl: 'my-div',
scroll: 'vertical',
fullscreen: true
// Setup a callback for WindowResize Event
Ext.EventManager.onWindowResize( senchaChangeOrientation );
}
});

// Callback
function senchaChangeOrientation()
{
if(Ext.getOrientation()=="landscape")
{
mainPanel.setSize(480,320);
mainPanel.setScrollable('false');
mainPanel.doLayout();
}
else {
mainPanel.setSize(320,480);
mainPanel.setScrollable('vertical');
mainPanel.doLayout();
}
};


do you have any suggestion to fix this problem or a different solution?
thanks in advance for any help.
Luca

arlo.carreon
11 Aug 2010, 5:48 AM
Although this is not the fix you are looking for, I have suggested some syntax correction from the code you provided. I believe the callback was not working before, because of where you had that line of code.



new Ext.setup({
onReady:
function(){
mainPanel = new Ext.Panel({
contentEl: 'my-div',
scroll: 'vertical',
fullscreen: true
});

// Setup a callback for WindowResize Event
Ext.EventManager.onWindowResize( senchaChangeOrientation );
});

// Callback
function senchaChangeOrientation()
{
if(Ext.getOrientation()=="landscape")
{
mainPanel.setSize(480,320);
mainPanel.setScrollable('false');
mainPanel.doLayout();
}
else {
mainPanel.setSize(320,480);
mainPanel.setScrollable('vertical');
mainPanel.doLayout();
}
};

lteti77
11 Aug 2010, 8:27 AM
yes. it was a typing error...there is also a missing curly bracket after the line:

Ext.EventManager.onWindowResize( senchaChangeOrientation );

by the way, the event is catched by senchaChangeOrientation function (i tried to display an alert and worked...) but after few seconds the application crashes...

lteti77
11 Aug 2010, 9:11 AM
finally i got it to work!
it was simpler than i believed...simply declared 2 panel with a card layout and set active item on window resize
here's the code i used.


Ext.setup({
onReady: function() {
panel = new Ext.Panel({
fullscreen: true,
layout: 'card',
items:[{xtype:'panel',contentEl:'portrait-container',scroll:'vertical'},
{xtype:'panel',contentEl:'landscape-container',scroll:'false'}]
});
Ext.EventManager.onWindowResize(setActivePanel);
}
});

function setActivePanel(){
if (Ext.getOrientation()=="landscape") {
panel.getLayout().setActiveItem(1);

} else {
panel.getLayout().setActiveItem(0);
}
};

arlo.carreon
11 Aug 2010, 10:02 AM
That is awesome! I am glad you got it working. About the issue with the app crashing after an alert, that has to do with the phonegap.js code. You should not include phonegap.js file, it appears to conflict in some way with sencha framework.

The only reason you would need the phonegap.js file is if you want to access the native maps, compass, accelerometer, camera, etc. Phonegap.js acts as a Javascript API for those native components, so make sure not to include the file if you are not tapping into native components.

lteti77
12 Aug 2010, 4:39 AM
yes but i need to develop an application using sencha and phonegap together...so there is no choice.
now i have only a problem when the application starts because the text is zoomed out after a second. it's probably due to the fact that the component is rendered and then the text is added (an so adjusted to fit the screen...).
i fixed this issue by inserting the html text directly inside the panel but that's not what i really wanted... i would prefer the text to be contained in a 'div' and displayed in the container at startup...

oonox
12 Aug 2010, 9:52 AM
Hi,

I found an another quickiest syntax.


Ext.setup({
onReady: function() {
panel = new Ext.Panel({
fullscreen: true,
layout: 'card',
items:[{xtype:'panel',contentEl:'portrait-container',scroll:'vertical'},
{xtype:'panel',contentEl:'landscape-container',scroll:'false'}]
});
Ext.EventManager.onWindowResize(setActivePanel);
}
});

function setActivePanel(){
panel.setOrientation(Ext.getOrientation(),window.innerWidth,window.innerHeight);
};

Enjoy !

Thx for all your message.

Fabien

arlo.carreon
12 Aug 2010, 9:59 AM
That looks awesome!!! Can't wait to try it, I like this better than static width and heights. Thanks for sharing.

p.s. this was tested with phonegap and ipad simulator correct?

oonox
12 Aug 2010, 10:23 PM
yes test on the iphone and ipad simulator and device with phonegap.

calvinjfress
23 Sep 2010, 11:59 PM
Hi

i'm discovering all the awesomeness offered by sencha, it's really great.
I get some trouble with phonegap, and i thought i found the solution on this topic, but i can't get your solution to work with the kitchen sink example.
On this one, the orientation have to deal with the navigation panel, and i don't really get how to make this all work.

thanks

arlo.carreon
24 Sep 2010, 7:12 AM
Well in our case sencha was not capturing the event of turning the iPad/iPhone sideways. So in order to help sencha recognize the orientation change, we listen to this event:

Ext.EventManager.onWindowResize(YOUR_HANDLER_FUNCTION_HERE);

You should create a function to handle this event, and set an alert("Hello orientation change"); in that function.
Let us know what you get.

devver
5 Oct 2010, 12:14 AM
Within the simulator, while using PhoneGap, applying the following code:


panel.setOrientation(Ext.getOrientation(),window.innerWidth,window.innerHeight);

Within a listener to Ext.EventManager.onWindowResize will seemingly only trigger once. Upon changing the orientation back to portrait mode, the layout doesn't update and becomes clipped on the right side. Placing a debug.log call inside of the handler suggests that the function doesn't so much as fire.

I speculate that something inside of Ext.lib.Component.doComponentLayout() is the culprit, however I'm not certain.

Is anyone else seeing this behavior?

Full code below:




Ext.setup({
onReady: function() {
panel = new Ext.Panel({
fullscreen: true,
layout: 'card',
defaults: {
cls: 'card'
},
items:[{
xtype: 'panel',
html: "Panel One",
scroll: 'vertical'
},{
xtype: 'panel',
html: "Panel Two",
scroll: 'false'
}]
});

Ext.EventManager.onWindowResize(setActivePanel);
}
});

function setActivePanel() {
debug.log("Orientation changed to: " + Ext.getOrientation());
panel.setOrientation(Ext.getOrientation(),window.innerWidth,window.innerHeight);
};

lteti77
5 Oct 2010, 11:27 AM
i'm having the same problem with a tab panel. the window resize event triggers only once.

devver
5 Oct 2010, 1:54 PM
Here's a bit of a solution.

First, inside of Ext.onReady listen directly for the orientationChanged event, like so:



document.addEventListener("orientationChanged", function() {
setTimeout(setOrientation, .125);
});


Later in your JS, define the setOrientation function:



function setOrientation() {
panel.setOrientation(Ext.getOrientation(),window.innerWidth,window.innerHeight);
};


The setTimeout duration is pretty arbitrary, but it seems to work fine with a mildly complex setup - your mileage may vary.

gabrielstuff
5 Oct 2010, 1:57 PM
Hello !

I was wondering if anyone of you have tried to use the video example of Sencha with PhoneGap ? How to relay the event, so that the video will change on orientation but not the app ???

Thank

anothermarcus
7 Jan 2011, 5:55 PM
This solution is great!

When I start the application in Portrait for example and rotate to landscape, everything shuffles into place.

Unfortunately, for my case, I'm using a map as an item,along with a number of buttons I want to "swipe". I find as soon as I touch the map, the entire Panel shifts up beyond the bounds of the screen. When I rotate back into Portrait, everything is fine again.

Here is how my example is laid out:



toolbar = new Ext.Toolbar({
dock: 'top',
xtype: 'toolbar',
ui : 'light',
scroll: 'horizontal',
bodyStyle:'overflow-x:hidden',
defaults: {
iconMask: true
},
items : [
myButtonGroup
]
});

mapdemo = new Ext.Map({

mapOptions : {
center : new google.maps.LatLng(49.25,-123.133333), //The couver
zoom : 12,
mapTypeId : google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
}

new Ext.Panel({
fullscreen: true,
layout: {
type: 'fit'
},
dockedItems: [toolbar],
items: [mapdemo]
});



Integrating a map using a simple DIV with phonegap alone, I can rotate portrait landscape, without any problems.

If there is a robust solution or a fix that Sencha or PhoneGap is putting out for this, I'd be glad to hear about it :)


Thanks a lot!
-Mark

ed.canas
8 Jan 2011, 8:41 AM
Here is my solution on the orientation problem with phonegap. I stop using it and instead using quickconnect which does not have the problem with orientation
Here is a video on it
http://www.sencha.com/forum/showthread.php?120009-HOWTO-Convert-Sencha-Touch-Project-to-a-Native-App-using-QuickConnect

anothermarcus
10 Jan 2011, 5:23 PM
Thanks Ed. I was hoping to work through my Phonegap issues, but I'll definitely give Quick Connect a try!

tkzic
25 Jan 2011, 1:15 AM
I'm having the exact same issue when going from portrait to landscape. Have tried way to many things to no avail.

However, If I start the app in landscape, everything is fine & I can resize panels, etc on orientation changes. The best I can guess is that 'some screen dimension' for window height stays set at 480 when orientation goes from portrait to landscape - so the panel gets placed in the top 2/3 of that and scrolls as soon as you tap the screen.

Have tried setting scrollable to false, resetting panel size and origin, trapping tap events, .etc.,

On the simulator I can get it to work fine by destroying the panel on orientation change, and then recreating it 0.5 seconds after orientation change. But not on the device. I'd be thrilled to hear of a workaround.

tz

hitman01
25 Jan 2011, 8:53 AM
This is what i use.

// Somewhere on top
var nativeAppOrientation = Ext.getOrientation();

if(Ext.is.iOS && navigator.userAgent.match(/safari/i) == null) {
Ext.EventManager.onWindowResize(function(){
if(nativeAppOrientation != Ext.getOrientation()) {
var e = document.createEvent('Events');
e.initEvent('orientationchange', true, false);
document.dispatchEvent(e);
nativeAppOrientation = Ext.getOrientation();
}
}, this, {buffer: 500});
}

tkzic
25 Jan 2011, 12:10 PM
That's very cool code hitman01 - thanks for teaching me how to create new events in js!

It doesn't solve the problem that anothermarcus posted - that is, if your app starts in portrait mode (with sencha/phonegap) and then reorients to landscape, even if you respond to the orientationChange event and use panel.setOrientation() to make things look right... as soon as you tap the screen anywhere other than the status bar, it will scroll up by about 160 pixels - as if the viewport is still in portrait height.

this behavior doesn't happen if you start the app in landscape mode - which you can do in phonegap on the simulator, but not on the device, because the user can defeat it while the app is loading by just turning the device... arggghhhh.

Actually does anyone know a way to lock the device in landscape mode until after the app is done loading? this would be a workaround.

tkzic
25 Jan 2011, 12:13 PM
actually I meant: scroll "down" by about 160 pixels, when you tap the screen, leaving the top of your panel up out of sight until you tap the status bar to bring it back...

hitman01
25 Jan 2011, 12:13 PM
Sorry man, didnt read the whole thing :)

sikander singh
26 Jan 2011, 12:59 AM
i was facing this problem and it really irritated me . Now i got the solution .cheers .thanks

tkzic
29 Jan 2011, 10:28 PM
Here is a solution to the phonegap orientation problem that solved all issues above. I will post a complete example if anyone wants it. Thanks again to hitman01 for the code above that is a big part of the solution. Hopefully someone at Sencha will read this....

1. include the hitman01 code (above) near the top of your Ext.setup Onready() - this fixes event issues.

2. in sencha-touch-debug.js around line 14082, Ext.Viewport - getOrientation(), Replace the return(window.orientation ==0... statement in the first if() statement with:


return(window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape';

For some reason, in phonegap, window.orientation always returns a 0

3. Back in your Ext.setup Onready() - add an event listener for orientation change:


document.addEventListener('orientationChanged', ocHandler );

4. add the handler function with the following statements, assuming mainPanel is a var containing your main panel object.


function ocHandler() {
mainPanel.hide();
setTimeout('mainPanel.show()', 1000);
}


The one second delay was the minimum that worked on my ipod touch...

ok hope this helps... I am psyched to actually be able to use phonegap + sencha touch now.

tkzic

dariux
25 Feb 2011, 2:26 PM
Tkzic - Hitman you save me guys, I have been searching for a solution all entire day it was very frustrated for this orientation issue. Your code it works fine. Regards.

kgilb
28 Feb 2011, 9:39 AM
tkzic, can you post that complete example? I still cannot get orientation changes to fire on iOS after following your instructions.

hitman01
28 Feb 2011, 1:58 PM
Here is an update to my code. It runs both in native app and web browser.

// Somewhere on top
var nativeAppOrientation = Ext.getOrientation();


//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// This code enables orientation change in native apps
// This should run only when embeded in native application
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
if(Ext.is.iOS && navigator.userAgent.match(/safari/i) == null) {
document.body.style.overflow='hidden';
document.getElementsByTagName('html')[0].style.overflow='hidden';

Ext.EventManager.onWindowResize(function(){

if(nativeAppOrientation != Ext.getOrientation()) {
var e = document.createEvent('Events');
e.initEvent('orientationchange', true, false);
document.dispatchEvent(e);

nativeAppOrientation = Ext.getOrientation();
}
}, this, {buffer: 500});
}
});

rdp
22 Mar 2011, 4:13 AM
I'm trying your code, but, when "orientationchange" occurs, it run an infinite loop and the application is blocking?

Do you know why?

my code:

app.js


Ext.regApplication({
name: 'app',
launch: function() {
this.launched = true;
this.mainLaunch();
},
mainLaunch: function() {
if (!device || !this.launched) {return;}
this.views.viewport = new this.views.Viewport();

nativeAppOrientation = Ext.getOrientation();


if(Ext.is.iOS && navigator.userAgent.match(/safari/i) == null) {
document.body.style.overflow='hidden';
document.getElementsByTagName('html')[0].style.overflow='hidden';

Ext.EventManager.onWindowResize(function(){
console.log('ecco qui');
if(nativeAppOrientation != Ext.getOrientation()) {
var e = document.createEvent('Events');
e.initEvent('orientationchange', true, false);
document.dispatchEvent(e);

nativeAppOrientation = Ext.getOrientation();
}
}, this, {buffer: 500});
}

}
});



viewport.js



app.views.Viewport = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: 'card',

cardSwitchAnimation: 'slide',

initComponent: function() {
//put instances of cards into app.views namespace
Ext.apply(app.views, {
contactsList: new app.views.ContactsList(),
contactDetail: new app.views.ContactDetail(),
contactForm: new app.views.ContactForm()
});
//put instances of cards into viewport
Ext.apply(this, {
items: [
app.views.contactsList,
app.views.contactDetail,
app.views.contactForm
],
listeners : {
orientationchange: function() {
//alert('cambiato');

console.log(nativeAppOrientation);
this.setOrientation(Ext.getOrientation(),window.innerWidth,window.innerWidth);
//this.doLayout();
}
}

});
app.views.Viewport.superclass.initComponent.apply(this, arguments);
}

});

rdp
22 Mar 2011, 5:47 AM
I found a solution to my error... this.setOrientation() cause an infinite WindowResize event. :)

danmux
18 Apr 2011, 5:29 PM
I think this is the best solution to this issue...

It does mean that you will have to recompile the phonegap static library...

http://www.sencha.com/forum/showthread.php?109839-onOrientationChange-event-is-not-being-handled-properly-on-ip*-devices-by-uiwebview&p=592739#post592739

fac3
26 May 2011, 7:15 AM
rdp, can you tell me please, how you fix your problem?

mnjacobs
26 May 2011, 9:53 AM
Here is my patch to Sencha Touch to fix orientation issues with PhoneGap 0.9.5.


var senchaHandler = Ext.createDelegate(Ext.Viewport.onOrientationChange, Ext.Viewport);

var orientationChangedHandler = function(){
senchaHandler.call();
};

window.onorientationchange = this.orientationChangedHandler;The problem is in the private Viewport class. The above event registration is in the constructor, but since the object is a singleton, it is never called.

fac3
30 May 2011, 3:17 AM
can you please explain me, where i must put your code in and how i must call the onoriantationchange function? thank you for your help!

vertex
11 Aug 2011, 5:55 AM
try this:

onOrientationChange:function(t,o,w,h){
tempWidth = window.innerWidth;
try{

getPlaceHolder();
}catch(e){}

var cardReference=t.getActiveItem().id;
if(cardReference=="yourcard"){
if(Ext.is.Android){
yourviewport.setHeight(window.innerWidth);
}
else{


document.getElementById("yourcard").style.width = (window.innerWidth-175)+"px";
document.getElementById("yourcard").style.width = (window.innerWidth-15)+"px";
}

RandyMcMillan
8 Feb 2012, 9:10 AM
ALot of the issues with orientation event in PhoneGap have been resolved but I wanted to post this link to sample code .

https://github.com/RandyMcMillan/SenchaTouch