0

So I wrote some code that gets the x and y from an ontouch event, passes it to a WebView javascript function and then from there (for the sake of this explanation) puts the box where it was touched...

After a battle and a half, I worked out that if I put x/2 and y/2 the co-ordinates would be perfect.. questions:

1) Why on earth is this happening?! I tried getting the width and height comparison from js and android, and it is the same width and height for both..

2) Is there any way to tidy this up?

3) Will it work like this on any other device (with different dimensions)?

Code:

HTML

function menuClick(x, y){
document.getElementById("jumprequested").innerHTML = "X: "+x+", Y: "+y;
document.getElementById("jumprequested").style.top = y/2;
document.getElementById("jumprequested").style.left = x/2;
theclick = document.elementFromPoint(x/2, y/2);
if(theclick !== "" && theclick.className == "number"){
   loadLevel(theclick.outerText);
 }
}

Android Code

         myWebView.setOnTouchListener(new View.OnTouchListener() {  
        public boolean onTouch(View v, MotionEvent event) {
            gettheY = event.getY();
            gettheX = event.getX();
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            if(menuToggle == true){
                myWebView.loadUrl("javascript:menuClick("+gettheX+","+gettheY+")");
            }
            else {
            if(gettheY<halfWidth){
                myWebView.loadUrl("javascript:touchDown(1)");
            }
            else {
                myWebView.loadUrl("javascript:touchDown(0)");
            }
          }
        }

        if(event.getAction() == MotionEvent.ACTION_UP){
            if(menuToggle == false){
            if(gettheX - jumpHeight > event.getX()){
            //jump
            }
            else if (event.getY()<halfWidth){
                myWebView.loadUrl("javascript:touchUp(1)");
            }
            else{
                myWebView.loadUrl("javascript:touchUp(0)");
            }
        }
        }
          return true;
        }
    });

2 Answers2

0

EDIT: For future reference, whilst this works - for the best compatibility I went with the selected chosen answer.

https://coderwall.com/p/ygcyha

This link is the answer, finally found it after no one replying on this! I got lucky when I divided it by 2..

The CSS pixel ratio is different . enter image description here

0

1) This is because the relationship between the values of CSS pixels (as seen by your JavaScript) and physical pixels (as seen by the Android view system) is expressed by the (deprecated) webview.getScale() method.

If you enabled pinch-zoom this value will change while your application is running as the user zooms in/out. Even if you disable pinch zoom it's still possible for this value to vary across devices (up till Android 4.4 it was possible to prevent this using the targetdensity-dpi viewport attribute, but that's not supported anymore).

2) Implement WebViewClient.onScaleChanged and stash the newScale value somewhere. Use that instead of the fixed value of 2 in your calculations.

3) Using a fixed value will not work across devices.

marcin.kosiba
  • 3,221
  • 14
  • 19
  • Thanks for the heads up on part 3, better than what I originally suggested - can I call it onCreate to get the scale? –  May 19 '14 at 16:45
  • if you really can't be bothered to do 2) then it's better to call the deprecated `WebView.getScale()` method every time you need it instead of stashing the value once. – marcin.kosiba May 19 '14 at 16:51
  • Sorry I meant part 2! I would like to implement it, what I'm asking is onCreate will it register the value? –  May 19 '14 at 16:52
  • @TristanComley no, in `onCreate` you can set the WebViewClient instance but you won't get the `onScaleChanged` callback. To be honest I don't think you'll ever get the callback if the scale doesn't change - your best bet is to initialize your value with webView.getScale() in `onCreate`. – marcin.kosiba May 19 '14 at 17:31
  • Would this work better? http://stackoverflow.com/questions/3166501/getting-the-screen-density-programmatically-in-android/19256186#19256186 –  May 19 '14 at 19:45
  • @TristanComley - you'd be hardcoding the assumption that the WebView's scale is always equal to the screen's DPI scale. That's only true in certain cases. It really is better to just call webView.getScale(). – marcin.kosiba May 20 '14 at 11:40
  • If it is not the same, wouldn't this work? http://developer.android.com/reference/android/view/View.html#getScaleX() –  May 20 '14 at 18:43
  • @TristanComley - no, they're completely different things. `WebView.getScale()` == 2 means the contents of the WebView is 2x bigger, but the WebView's size doesn't change. `WebView.getScaleX/Y()` == 2 means the webview contents and size are scaled up twice. – marcin.kosiba May 21 '14 at 09:39