I have a WebView
that is displaying a local HTML page within the assets folder. The WebView
is part of larger layout in an Activity
. I'm trying to allow users to drag text from an EditText
widget to an Input Element within the WebView
. Everything works good except for converting the screen coordinates received by the drag listener to the screen coordinates used by document.elementFromPoint
. They don't match up. It'll keep dropping text into input boxes which are further down then the users finger. Any help would be appreciated. Warning: my javascript knowledge is pretty pathetic.
Basic flow:
- WebView's onDrag event catches the ACTION_DROP event.
- The event's x, y location is passed to a Javascript function
- The Javascript function finds element based on points and updates the value
In my Activity:
private class OnWebViewDragListener implements OnDragListener {
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
String dropText = event.getClipData().getItemAt(0).getText().toString();
mJavaScript._dropText(mWebView, dropText, event.getX(), event.getY());
return true;
default:
break;
}
return false;
}
}
Javascript wrapper:
public void _dropText(WebView wv, String text, float x, float y) {
wv.loadUrl("javascript:dropText('" + text + "', " + x + ", " + y + ")");
}
Javascript function:
<script type="text/javascript">
function dropText(text, x, y) {
var elem = document.elementFromPoint(x, y);
if (elem.tagName == "INPUT") {
elem.value = text;
}
}
</script>
I have a WebView
that is displaying a local HTML page within the assets folder. The WebView
is part of larger layout in an Activity
. I'm trying to allow users to drag text from an EditText
widget to an Input Element within the WebView
. Everything works good except for converting the screen coordinates received by the drag listener to the screen coordinates used by document.elementFromPoint
. They don't match up. It'll keep dropping text into input boxes which are further down then the users finger. Any help would be appreciated. Warning: my javascript knowledge is pretty pathetic.
Basic flow:
- WebView's onDrag event catches the ACTION_DROP event.
- The event's x, y location is passed to a Javascript function
- The Javascript function finds element based on points and updates the value
In my Activity:
private class OnWebViewDragListener implements OnDragListener {
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
String dropText = event.getClipData().getItemAt(0).getText().toString();
mJavaScript._dropText(mWebView, dropText, event.getX(), event.getY());
return true;
default:
break;
}
return false;
}
}
Javascript wrapper:
public void _dropText(WebView wv, String text, float x, float y) {
wv.loadUrl("javascript:dropText('" + text + "', " + x + ", " + y + ")");
}
Javascript function:
<script type="text/javascript">
function dropText(text, x, y) {
var elem = document.elementFromPoint(x, y);
if (elem.tagName == "INPUT") {
elem.value = text;
}
}
</script>
Share
Improve this question
edited Nov 12, 2012 at 19:14
Ifrit
asked Nov 8, 2012 at 19:44
IfritIfrit
6,8218 gold badges52 silver badges79 bronze badges
1 Answer
Reset to default 10Figured it out. Was making the conversion more plicated then what it needed to be. Both Android's WebView and the WebPage have their own coordinate system based on the size of their visible view port. Yes both report different sized view ports. Even though both view ports can be scrolled, there's no need to include those scrolled changes. The simple formula:
DE = DragEvent
WV = WebView
x = DE.getX() * (window.innerWidth / WV.getWidth());
y = DE.getY() * (window.innerHeight / WV.getHeight());
How my code looks now:
In Activity:
private class OnWebViewDragListener implements OnDragListener {
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
String dropText = event.getClipData().getItemAt(0).getText().toString();
mJavaScript._dropText(mWebView, dropText, event.getX(), event.getY());
return true;
default:
break;
}
return false;
}
}
Javascript wrapper:
public void _dropText(WebView wv, String text, float x, float y) {
wv.loadUrl("javascript:dropText('" + text + "', " + x + ", " + y + ", " + wv.getHeight()
+ ", " + wv.getWidth() + ")");
}
Javascript function:
<script type="text/javascript">
function dropText(text, x, y, height, width) {
x *= (window.innerWidth / width);
y *= (window.innerHeight / height);
var elem = document.elementFromPoint(x, y);
if (elem.tagName == "INPUT") {
elem.value = text;
}
}
</script>