【问题标题】:How to draw Canvas in WebView?如何在 WebView 中绘制 Canvas?
【发布时间】:2015-08-11 18:34:40
【问题描述】:

我正在制作一个应用程序,人们将能够在 WebView 中放置圆圈。所以我的 算法是:

  1. 检测长按
  2. 在 WebView 上获取手指坐标
  3. 在 Canvas 中画圆

所以一开始我可以编写一个在LongClick 上画一个圆圈的代码,唯一的问题是当我改变比例(缩放)时,圆圈从它的位置移动了。在 karaokyo 回答的帮助下,我已经解决了这个移动问题)添加scale float Canvas.drawCircle(x * scale, y * scale, 10, p),其中scale = getScale()。 不幸的是,出现了新问题 - 当我制作圆圈时,它绘制了错误的坐标。这张图片显示了我的意思:

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);
    }

}

}

此外,如果我双击多次圆圈(两者)出现在错误的位置,点击时移动到正确的位置。

如果您知道如何执行此操作或知道一个好的教程 - 将不胜感激。

[更新卡拉京的答案]

我已经复制了你的代码,但是circle仍然在错误的地方,实际上initialScale的值是2.0。在这张图片上可以清楚地看到。 1. 有移动问题的圆,但坐标正确。 2. 圆无移动问题,坐标乘以scale = getScale。 3.圆无移动问题,坐标乘以scale/initScale

【问题讨论】:

  • 我认为你最好使用 javascript 绘制圆圈。

标签: javascript android canvas webview android-webview


【解决方案1】:

要解决您的圆圈移动问题,您必须根据 WebView 的缩放比例调整坐标。对于长按,设置一个GestureDetector 保存点击位置和当前比例onLongPress 用于您的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);
    }
}

【讨论】:

  • 我尝试使用您的解决方案 - 请参阅更新的图像问题。虽然 circle 不再移动,但它在错误的位置,加上 getScale() 已弃用。
  • WebView 中的比例为 0.6698988
  • 对,您只是根据之前的位置随意确定它在错误的位置。如果您希望它位于以前的相同位置,则必须考虑一个初始比例因子。如果您对 getScale 弃用提出质疑,另一种选择是使用自定义 WebViewClient 覆盖 onScaleChanged 并设置一些在您的 onDraw 中使用的字段变量“比例”。
  • 我有自定义的WebView,但不确定它是否与WebViewClient 相同。您还谈到了初始规模,我该怎么办?
  • 我的意思是通过WebView.setWebViewClient设置的客户端。人们一直在报告它不可靠,所以我没有搞砸它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 2020-02-15
  • 2013-11-01
  • 1970-01-01
  • 2015-01-11
  • 2020-09-03
  • 1970-01-01
相关资源
最近更新 更多