My application is a simple WebView "wrapper" that displays a web page in a fixed landscape orientation, the page has a centered div that is 760px wide and 415px high and this should be displayed scaled on all devices so it (roughly) fits the screen, the user cannot change the scaling... I've almost got everything working apart from the scaling.
I have the following viewport meta tag on the page :
<meta name="viewport" content="width=device-width, target-densityDpi=device-dpi, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
The manifest for the WebView wrapper .apk I've created is as follows:
<supports-screens android:smallScreens="true"
android:normalScreens="true" android:largeScreens="true"
android:anyDensity="true" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name="{my name}"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I should mention that originally the .apk target was Android 2.2 and I've recently changed up to 2.3.1 and added another line to the manifest but that's made no difference to anything :
android:xlargeScreens="true"
I added the following in to the .java code :
webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webview.setScrollbarFadingEnabled(false);
webview.getSettings().setSupportZoom(false);
webview.getSettings().setBuiltInZoomControls(false);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
For the purpose of this question just assume that the only content on the entire site is the following <div>:
<div style="margin: auto; position:relative; align:center; top:0px; width:760px; height:415px; background-color:#000000">
My problem is I can't to come up with a "one-size-fits-all" scaling solution across all Android devices, everything else I've tasked myself with delivering works fine.
I've tried this on three different devices, one tablet and two phones, and there is a large gap on the left, right and bottom of the <div> layer. It looks like the 760px width has about another 50px gap on either side and the same underneath on each of the devices, all I want to do is scale that up so it roughly fills the screen on all of the devices.
My phone says it's got a window.innerWidth of 854 with a window.devicePixelRatio of 1.5 and if I change the initial and maximum scale to 1.12 the <div> layer fits just about perfectly on my device. The table says it's got a window.innerWidth of 980 with a window.devicePixelRatio of 1.0 and seems to like a scale of around 1.27. I don't know the details of the third device but using 1.1 seem to do the trick on that.
Of course changing the initial scaling isn't a solution and even attempting it would be a complete nightmare so, fingers crossed, can anyone tell me the blindingly obvious thing that I'm missing that'll make this work? Or am I just asking the impossible to automatically scale the view to a fixed size <div>?
Right... On the way home I was stuck in a jam and had a jolly good think, I came to the conclusion that I was dramatically over-thinking this problem.
This is rough but it does the job, I removed the meta tag from the site and added this to the application :
// Set up up the scaling value
float scaling = 100;
int display_width;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
display_width = dm.widthPixels;
scaling = (((float)display_width/760)*100); // 760 here is my container div width
scaling = (int) Math.floor(scaling);
// Set up the webview and apply the scale value
webview = (WebView) findViewById(R.id.webview);
webview.setInitialScale((int)scaling);
That works quite well but I have encountered two issues since I made this post.
The first is that by removing the meta tag I seem to have removed my limitation on the maximum/minimum scale, this means that clicking on any <INPUT> element which displays the Android keyboard will result in a change in the scaling. Luckily, adding this line to the code solves this issue so far :
webview.getSettings().setDefaultZoom(ZoomDensity.FAR);
The second I don't have a workable solution for and is that some devices, such as the Archos101 tablet, have software buttons instead of hardware buttons. The scaling code here will scale to the device width and that means the site goes underneath the software buttons... Currently thinking about implementing a solution based on READ_PHONE_STATE or optionally adding the ability to quit the application without hardware buttons and adding this to the manifest :
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
Hopefully someone else will find this and save themselves some time.
Related
I created a web-app, with a target of a Nexus 4 phone in mind, intended to be used in landscape orientation.
It looks fine using chrome. But when I then used that HTML/CSS to create a Cordova App, the display is way too big for the phone. I have tried many things suggested by many people to no avail.
As an example, if I have the following div defined:
#content {
border: thin ;
border-style: solid ;
width: 960px ;
height: 475px ;
}
and as a web-app, the border fits nicely in the display of the Nexus 4 using chrome. But I have to reduce that 960px down to around 570px to get it to fit when it is a App installed via cordova. I am doing a 'fixed' position for all my divs inside that #content div. There is only 1 target device that this App will get used on - I don't care about any other devices. (Yes, I really want to do that). I don't want scrolling.
I tried setting the target-densitydpi=medium-dpi" as suggested in Phonegap/Cordova App Shrink too small on high resolution device like Samsung Galaxy S4
and Phonegap Application text and layout too small
I've tried setting initial-scale=1.0 like many people suggest.
I've tried 1.5 and 2.0 which makes it even bigger, but 0.5 does not make it smaller.
I tried adding
preference name="EnableViewportScale" value="true"
to my config.xml as suggested by PhoneGap: Scaling down a webpage with viewport
While I have tried many combinations, my basic viewport definition is:
<meta name="viewport" content="user-scalable=no,
initial-scale=1, maximum-scale=1, minimum-scale=1,
width=device-width, height=device-height,
target-densitydpi=medium-dpi" />
Nothing has worked for me.
I have no idea how this stuff works and I have very little experience with front-end and mobile App technologies. I see no relationship between the advertised hardware devices resolution and what I see on a web-app, and what I see on a native App. I don't know why they would behave differently on the same device with the same CSS.
Any suggestions and/or pointers would be greatly appreciated.
I found a solution at Android 4.1 viewport scaling ( setInitialScale, meta initial-scale not working)
(although there is a missing opening curly bracket).
By using:
function customScaleThisScreen() {
var contentWidth = document.body.scrollWidth,
windowWidth = window.innerWidth,
newScale = windowWidth / contentWidth;
document.body.style.zoom = newScale;
}
and setting my viewport to:
<meta name="viewport" content="user-scalable=no,
initial-scale=0.6, maximum-scale=0.6, minimum-scale=0.6,
width=device-width, height=device-height,
target-densitydpi=medium-dpi" />
it now fits within my Nexus 4 screen.
Although the height (in landscape mode) comes a bit short of what I ideally wanted, the entire display is shown. It uses up about 90% of my available height which I can live with.
I also found that setting:
<preference name="EnablEnableViewportScale" value="false" />
in config.xml does nothing - whether I set it to true or false.
Before, I was able to scale upwards of 1.0 (such as 2 and 4), but not below 1.0, no matter what EnableViewportScale was set to. But the above code solved this.
I am running Android 4.4.4
I've been working on a responsive design. To stop the content from crossing boundaries i've used viewpoint meta tag with width = 480. The problem is i want my website to load with minimum of 480px no matter what. If the screen width is less than 480px I want it to fit the screen width by "Zooming out".
I've used the following viewpoint meta tag:
<meta name="viewport" content="width=480px, initial-scale=1, maximum-scale=1" />
I've also used min-width css tag to specify minimum width.
<body style="min-width: 480px; width:100%; margin:auto;">
So after all this when i tried to load the website in DevTools Emulator (Google Chrome), it shows a horizontal scrollbar. Got any ideas on how to do it.
Have you tried width=device-width?
I don't think forcing the 480px in the meta will do what you want (not crossing media-query-type boundries).
I'm using the following line in my webapp:
<meta name="viewport" content="width=720, maximum-scale=1, user-scalable=no" />
This works perfectly fine on mobile safari - the document is 720px wide and fits the screen perfectly. However, when tested on the HTC One, the content was like 2.5x the width of the screen.
Android is supposed to support the viewport tag, so why is it ignoring the pixel width it should be displaying in?
All help appreciated.
Answer taken from Android docs:
Whether the user can change the scale of the page at all (zoom in and out). Set to yes to allow scaling and no to disallow scaling. The default is yes. If you set this to no, then the minimum-scale and maximum-scale are ignored, because scaling is not possible.
In that case, remove user-scalable=no and see what happens. That might be the fix you need.
I've written a very simple Android app which basically presents a full screen WebView (no title bar, notification bar or URL bar) in landscape.
The Activity then basically loads a client.html file from the user's PC which then loads a fixed image meant to fill the whole of the screen. The client.html file has a meta element as follows...
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width, height=device-height, initial-scale=1.0, user-scalable=no" />
In the <html><body> the <img> src attribute is set by requesting the image at a specific size as follows...
<div id="BasicDemo" >
<img id="nscreen" />
</div>
<script type="text/javascript">setImageSource()</script>
...and this is the javascript setImageSource()...
function setImageSource() {
$.getScript("myscript.js", function() {
$("#nscreen").attr("src", "/control?size=" + getDimensions());
});
}
The getDimensions() function is another piece of javascript which calls into the Android app and retrieves the 'absolute' screen dimensions in pixels.
So here's my problem (and I know using absolute pixels is probably the root of it)....
On my Desire, it's classed as hdpi for web apps and has 800x480 actual pixels. The call to set the image source looks like..."/control?size=800x480" and works perfectly. The image fits my full screen. One tester, however, has a 7in tablet - also 800x480 but due to screen size it's classed as mdpi. Requesting the same sized image with "/control?size=800x480" and the fact the <meta> tag forces mdpi obviously means the image is oversized.
So the question - I'm forced to specify dimensions when requesting the image source - how am I supposed to translate things properly? Has anyone a similar experience they can share?
I've read Targeting Screens from Web Apps several times over and I'm clearly missing something.
Try CSS media queries to target LDPI, MDPI and HDPI:
http://designbycode.tumblr.com/post/1127120282/pixel-perfect-android-web-ui
I need my website to adjust itself according to the device. I used the following viewport meta tag:
<meta name="viewport" content="user-scalable=no,width=device-width, height=device-height, minimum-scale=0.1, maximum-scale=0.65" />
It works alright on iPhone. but on android it looks it doesn't responded to it at all even when I change the scale values. Is there a different tag for android?
You should use the same tag for Android, but there are a few differences how different platforms calculate initial scale from viewport size, or viewport size if not set. Also keep in mind that initial-scale only works first time you load the page, if you reload the page it will keep the scaling that you currently have.
I'm unsure what result you are looking for, but you have a great reference for Android here ( http://developer.android.com/guide/webapps/targeting.html ) and for Iphone here ( http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html ).
Also, you can google for "tale of two viewports" (i was unable to post link because of low reputation)