My Webview Reloads When I Change From Portrait To Landscape - webview

I have a simple WebView that runs a web application on an Android. The problem is when I rotate the phone to change it to landscape the webview reloads and goes back to the beginning.
How can I prevent this action?
Ron

Beginning with Android 3.2 (API level 13), the "screen size" also
changes when the device switches between portrait and landscape
orientation. Thus, if you want to prevent runtime restarts due to
orientation change when developing for API level 13 or higher (as
declared by the minSdkVersion and targetSdkVersion attributes), you
must include the "screenSize" value in addition to the "orientation"
value. That is, you must decalare
<activity android:configChanges="orientation|screenSize">
Excerpt from Handle configuration changes (webarchive to original page)

This can be resolved by overriding onSaveInstanceState(Bundle outState) in your activity and calling saveState from the Webview:
This blog post may be of help to you.

Add the following to your AndroidManifest:
android:configChanges="orientation|keyboard|keyboardHidden"
So it should look something like this:
<activity android:name=".MyActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboard|keyboardHidden">
Obviously, if your WebView needs keyboard support then don't include the keyboard options.

Add this before the oncreate
#Override
protected void onSaveInstanceState(Bundle outState) {
webview.saveState(outState);
}
Write the oncreate this way. put final
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutname);
if (savedInstanceState != null)
{
((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);
}
else
{
webview.loadUrl("http://www.playbuzz.org/");
}
}
In Androidmanifest insert under the activity
android:configChanges="keyboardHidden|orientation"

#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
Add above method in your activity.. and
android:configChanges="keyboard|keyboardHidden|orientation"
in your manifest file

The problem with the above solution is that it renders the screen white for some time before the webview redraws the contents.
Try using
android:configChanges="orientation|keyboardHidden" inside your AndroidManifest.xml file for the activity that displays the webview. That should help.

Add in Activity
android:configChanges="keyboardHidden|orientation"

Related

React native orientation is not working || locking on IOS

I created an app with React-native. All pages I made are designed for portrait mode except 1 page. The page accessibility comes from a button onPress then navigates to the page, so I can't lock orientation on Xcode
I installed this package and I can run it on android perfectly
import Orientation from 'react-native-orientation';
When I tried it on IOS simulator on every page it can turns orientation to landscape.
I put this line in every pages componentdidmount but nothing changes.
componentDidMount() {
Orientation.lockToPortrait()
...
}
What should I do?
Hey again #masterAvatarr,
I believe that this is what you're looking for, if you need something else please explain it to me :) We can make it happen.
I made a simple example for you.
https://github.com/WrathChaos/react-native-portrait-locker-example
I use React Native Orientation Locker Library
The important parts are:
Make sure that you linked the library manually (check AppDelegate.m)
You need to make a logic for unlocking and lock the portrait mode depends on your use-case
Please take a look at HomeScreen and DetailScreen
import Orientation from "react-native-orientation-locker";
React.useEffect(() => {
const unsubscribe = navigation.addListener("focus", () => {
// The screen is focused
// Call any action
Orientation.unlockAllOrientations();
Orientation.lockToPortrait();
});
// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
}, [navigation]);
Note: There is a little GIF Demo on the Github Repo

WebView qml doesn't work correctly on iOS 11

I've a problem, i need to open url inside app, and I used a WebView, but doesn't work correctly.
imported this:
import QtWebView 1.0
my code:
Rectangle{
width: Screen.width
height: Screen.height
color: "Orange"
anchors.fill: parent
z:9999999
WebView {
id: webviewer
anchors.fill: parent
url: "http://www.google.com"
onLoadProgressChanged: {
console.log(webviewer.loadProgress)
}
}
}
and in the .pro file i've put:
QT += webview
And my main.cpp
QtWebView::initialize();
my console.log is printing correctly the load status, but on the screen I don't see nothing.
Why?
Works on iOS, the solution is:
Open project in Xcode from build folder, and set App Transport Security Settings, you must add Allow Arbitrary Loads and sets it on YES.
Now the WebView works.
initialize() creates opengl surface, in this case You must first open parent window(surface to display) , other solution is to comment initialize() - page will show. If you'll decide to show it on GL surface, try to se ALWAYSSTACKONTOP attribute to see, if other windows dont cover webview, opengl is rendered first,so any other background can make it not visible. You may also open webview class parented to other, visible window, but if you will show it fullscreen, it will be flicker a while

StageOrientationEvent.ORIENTATION_CHANGING not dispatched

I'm testing my starling application on iPhone 4, I suspect this is happening because of the obsolete IOS version.
package
{
import flash.events.Event;
import flash.events.StageOrientationEvent;
import flash.display.Sprite;
public class Startup extends Sprite
{
public function Startup():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChangeListener);
}
private function orientationChangeListener(e:StageOrientationEvent):void
{
Debug.write("orientation: " + stage.orientation); //Never called
}
}
}
application.xml has autoOrients set to "true" and aspectRatio set to "landscape", I also tried deleting aspectRatio as suggested in some stackoverflow answer, to no avail.
StageOrientationEvent.ORIENTATION_CHANGING is never dispatched in my application.
Another weird thing is happening, which might help you understand the situation better:
Even though aspectRatio is set to "landscape" in application.xml, the app opens in portrait mode, and stage.orientation returns "rotatedRight" (meaning landscape).
I can only set to landscape properly by setting aspectRatio to "portrait" in application.xml, and then manually setting to "landscape" in runtime:
stage.setOrientation(StageOrientation.ROTATED_RIGHT);
If all you want is to lock landscape mode then first in description XML set aspectRatio to landscape and autoOrient to true then in code do:
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
stage.autoOrients = true;
And the device will not go through portrait.
<autoOrients>true</autoOrients>
<aspectRatio>landscape</aspectRatio>
should be the way to gay, it has always worked for us but we dont have published apps using this setting with air sdk 18
since it seems that it doesnt work for you, you may try the dynamic way as a workaround, like we use in our universal build (detects device iphone/ipad in preloader frame, applies correct orientation, instantiates the right main class), tested on old devices/os versions
with
<autoOrients>true</autoOrients>
<aspectRatio>any</aspectRatio>
and call stage.setAspectRatio(StageAspectRatio.LANDSCAPE); asap, meaning right in you main or preloader class constructor

Properly preventing orientation change in Flex Mobile app

Is anyone able to actually make it work properly in Flex SDK 4.6?
Here's a short snippet :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
addedToStage="onAddedToStage(event)"
title="Title">
<fx:Script>
<![CDATA[
private function onAddedToStage(event:Event):void {
if (stage.autoOrients) {
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 0, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) {
event.preventDefault();
}
}
]]>
</fx:Script>
</s:View>
What I'm trying to achieve is to support Landscape mode in both orientations, so if user turns the device 180 degress, the screen should also rotate. But there should be no action at all, when user rotates the device to one of portrait orientations. Instead, I'm seeing width changes to navigator action bar and sometimes content in portrait orientations, so apparently preventing the event is not enough. I'm using the "official" way Adobe suggests, but the problem is that it's not working very well. Granted, the stage does not change, but it seems that there's something firing in navigator anyway, since you can see the action bar width changing.
I had some success with explicitly setting layoutbounds to fixed width in handler method - this prevents changing the actionbar width, but it's only a temporary solution - if the view is a subject to a transition, or some other redraw - it will again render with bad sizes. As if there was something below that was telling it that it's in portrait mode, even though I'm trying to prevent it.
Before you detonate with some silly ideas like "autoOrient = false", don't. It's clearly not a solution for this problem. Obviously it's a bug with Flex SDK - did anyone find a way to fix it or a stable workaround?
EDIT: apparently others bumped into similar issue:
- http://forums.adobe.com/message/3969531 (the main topic is about something else, but read magic robots's comment)
- http://forums.adobe.com/message/4130972
I'm not sure if this is the right one, did I do something wrong in the end, but after a lot of struggle, I've found this one to be stable solution:
private function onAddedToStage(event:Event):void {
if (stage.autoOrients) {
stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
event.stopImmediatePropagation();
if (event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN) {
event.preventDefault();
}
}
First thing to note is that addedToStage fires few times (2-3) in mobile application. I don't know why, there's no addChild in my code, obviously. Maybe the AIR runtime does something else. So, to avoid adding unnecessary amount of handlers, the common technique is to remove handler first - it won't do anything, if such handler is not yet registered, but if there is, it will remove it, which will maintain the handler count on 1.
Second thing is the priority of the event - it won't work on 0, it has to be set on something big, to launch before stuff in AIR runtime.
Last thing - event.stopImmediatePropagation() - now, that we're the first to handle the event, we cant prevent this event to be sent further up in this particular scenario.
This together makes the orientation preventing working perfectly - for me the landscape and the reversed landscape (rotated_left, rotated_right) were working and transitioning, while portrait modes did not affect the view at all.
Now, there's danger here - you might want to remove the listener upon leaving the view (on transition animation end, view deactivate or something), because stopImmediatePropagation will prevent the event to be handled in other parts of your application.
I hope Adobe (or Apache now, actually) will take a closer look at this problem and trace my solution.
EDIT
There remaisn a last issue with this solution, which is if application starts while device is in DEFAULT or UPSIDE_DOWN orientation, in this case application will be in portrait mode.
To fix this, a solution is to change Aspect Ratio within addedToStage handler:
if(Stage.supportsOrientationChange) {
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
}
So I had the same problem you had. I think I finally figured out the solution. Heres what I did:
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
...blahblahblah...
width="1024"/>
protected function tabbedviewnavigatorapplication2_applicationCompleteHandler(event:FlexEvent):void {
stage.autoOrients=true;
preventOrient();
}
private function preventOrient():void {
if (stage.autoOrients) {
stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging, false, 100, true);
}
}
private function orientationChanging(event:StageOrientationEvent):void {
if(event.afterOrientation == StageOrientation.DEFAULT || event.afterOrientation == StageOrientation.UPSIDE_DOWN || event.afterOrientation == StageOrientation.UNKNOWN) {
event.preventDefault();
}
}
Worth noting is that in the application complete handler I set stage.autoOrients to true because in the app.xml file I have it set to false, due to having a splash screen and not wanting users to re-orient the screen during that time. Really the only thing I did different is account for the StageOrientation.UNKNOWN and prevent whatever that would do, set the width to 1024(for the iPad screen, might be different for other tablet devices) in the main mxml file, and removed the stopimmediatepropagation. Hope this helps.

View Rotation in MonoTouch iPad Application

I'm pretty new to MonoTouch and I'm having problems getting my app to rotate from portrait to landscape mode.
My project has two XIB files, the MainWindow added by MonoTouch and MainController.xib which I have added. The MainController has a single label and no other controls. In my Main.cs I have the following to load the MainController.xib file:
UIViewController controller = new MainController();
window.AddSubview(controller.View);
In the MainController code I added
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return false;
}
It all runs fine and the label displays but when I rotate the simulator nothing rotates. I'm sure it's something really simple that I'm getting wrong but I just can't seem to crack it.
Any help would be appreciated.
You can look at TweetStation for a sample.
In this particular case, you might want to return "true" instead of false in the sample above.

Resources