I'm making an app where people will be able to place circles in WebView. So, my algorithm is:
So at first I was able to write a code that would draw a circle on LongClick
, the only problem was that when I changed scale(zoomed), circle moved from it's place. With the help of karaokyo answer I have fixed this moving issue) with adding scale
float Canvas.drawCircle(x * scale, y * scale, 10, p)
, where scale = getScale()
. Unfortunately new problem appeared - when I make the circle it draws in wrong coordinates. This image shows what I mean:
public DrawWebView (Context context, AttributeSet attrs)
{
super (context, attrs);
wv1 = (DrawWebView) findViewById(R.id.webView1);
wv1.loadUrl("file://" + Environment.getExternalStorageDirectory() + "/Pictures/ScolDetectPics/boxes.jpg");
wv1.getSettings().setBuiltInZoomControls(true);
wv1.getSettings().setDisplayZoomControls(false);
wv1.getSettings().setSupportZoom(true);
wv1.getSettings().setUseWideViewPort(true);
wv1.getSettings().setLoadWithOverviewMode(true);
wv1.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
mContext = context;
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
draw = true;
this.invalidate();
break;
case MotionEvent.ACTION_MOVE:
this.invalidate();
break;
case MotionEvent.ACTION_UP:
this.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw (canvas);
text = MainActivity.text;
zoomPos = MainActivity.zoomPos;
Paint p = new Paint();
p.setColor (Color.RED);
if(initScale == 0){
initScale = getScale();
}
float scale = getScale();
float refScale = scale/initScale;
if(MainActivity.drawConfirm){
zoomPos = MainActivity.zoomPos;
draw1 = true;
}
canvas.drawCircle(330 * refScale, 618 * refScale, 10, p);
//text.setText(Float.toString(scale));
text.setText(Float.toString(initScale));
canvas.drawCircle(330, 618, 10, p);
if(draw1){
canvas.drawCircle(zoomPos.x * refScale, zoomPos.y * refScale, 10, p);
}
}
}
Also if I double-tap multiple times circles(both) appear in wrong place, move to the right place when I click.
If you know how to do this or know a good tutorial - it would be much appreciated.
[Update for karaokyo's answer]
I've copied your code, but circle's still in the wrong place, in fact, initialScale
value is 2.0. It is clearly seen on this image. 1. Circle that has moving issue, but in correct coordinates. 2. Circle without moving issue, coordinates multiplied by scale = getScale
. 3. Circle without moving issue, coordinates multiplied by scale/initScale
To address your circle moving problem, you would have to adjust your coordinates based on the zoom scale of the WebView. For the long press, set up a GestureDetector
that saves the click location and current scale onLongPress
to be used in your onDraw
:
public class DrawWebView extends WebView {
private GestureDetector mDetector;
private float mInitialScale;
private int mX;
private int mY;
public DrawWebView(Context context) {
super(context);
init();
}
public DrawWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init(){
loadUrl("file://" + Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");
setWebViewClient(new WebViewClient());
getSettings().setBuiltInZoomControls(true);
getSettings().setDisplayZoomControls(false);
getSettings().setSupportZoom(true);
getSettings().setUseWideViewPort(true);
getSettings().setLoadWithOverviewMode(true);
getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
mDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
mX = (int) e.getX() + getScrollX();
mY = (int) e.getY() + getScrollY();
mInitialScale = getScale();
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mDetector.onTouchEvent(event);
}
});
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw (canvas);
float scale = getScale() / mInitialScale;
Paint p = new Paint();
p.setColor(Color.RED);
canvas.drawCircle(mX * scale, mY * scale, 10, p);
p.setColor(Color.GREEN);
canvas.drawCircle(mX, mY, 5, p);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.