在自定义的WebView中通过长按打开上下文菜单的Android技术问题

5

我目前正在尝试获取一个自定义的WebView,当被长时间按下时显示上下文菜单。由于默认的WebView类只有在链接被长按时才会显示上下文菜单,所以我编写了自己的类来覆盖这种行为:

public class MyWebView extends WebView {
    Context context;
    GestureDetector gd;

    public MyWebView(Context context, AttributeSet attributes) {
        super(context, attributes);
        this.context = context;
        gd = new GestureDetector(context, sogl);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gd.onTouchEvent(event);
    }

    GestureDetector.SimpleOnGestureListener sogl =
                new GestureDetector.SimpleOnGestureListener() {

        public boolean onDown(MotionEvent event) {
            return true;
        }

        public void onLongPress(MotionEvent event) {
            // The ContextMenu should probably be called here
        }
    };
}

这段代码没有问题,长按事件被检测到并调用了onLongPress方法,但是当涉及到显示ContextMenu时,我有些困惑。我尝试在我的Activity中按照通常的方式来实现:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);

    MyWebView mwv = (MyWebView) findViewById(R.id.mwv);
    registerForContextMenu(mwv);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
                    ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context, menu);
}

然而,当我在模拟器中长按MyWebView时,没有任何反应。我需要从onLongPress()中调用什么来显示上下文菜单?

4个回答

4

现在我已经解决了问题,借鉴了gngr44的建议。我让我的活动实现了OnLongClickListener类,并提供了一个onLongClick()方法来打开上下文菜单。

修改后的代码:

自定义WebView:

public class MyWebView extends WebView {
    MyActivity theListener;
    Context context;
    GestureDetector gd;

    public MyWebView(Context context, AttributeSet attributes) {
        super(context, attributes);
        this.context = context;
        gd = new GestureDetector(context, sogl);
    }

    // This is new
    public void setListener(MyActivity l) {
        theListener = l;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gd.onTouchEvent(event);
    }

    GestureDetector.SimpleOnGestureListener sogl =
                new GestureDetector.SimpleOnGestureListener() {

        public boolean onDown(MotionEvent event) {
            return true;
        }

        public void onLongPress(MotionEvent event) {
            theListener.onLongClick(MyWebView.this);
        }
    };
}

我的活动:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);

    MyWebView mwv = (MyWebView) findViewById(R.id.mwv);
    registerForContextMenu(mwv);
}

public boolean onLongClick(View v) {
    openContextMenu(v);
    return true;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
                    ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context, menu);
}

2
这样可以使上下文菜单起作用。但是,我无法再滚动Webview了。实际上,任何触摸都会弹出上下文菜单。有什么办法可以让它正常工作吗? - newman
1
同样的问题,WebView失去了滚动功能。 - KingFu
我认为这是因为你重写了onTouchEvent,但没有实现超类。@Override public boolean onTouchEvent(MotionEvent event) { if (gestureDetector.onTouchEvent(event)) return true; return super.onTouchEvent(event); }给定的代码应该可以解决问题 :) - Nirab Pudasaini

2

建议您在视图中使用接口,并从您的活动中实现该接口,而不是从视图中访问活动。

public class MyWebView extends WebView {
    private OnLongPressListener mListener;

    public MyWebView(Context context, AttributeSet attributes) {
        mListener = (OnLongPressListener) context;
    }

    public void onLongPress(MotionEvent event) {
        mListener.onLongPress(your variables);
    }

    public interface OnLongPressListener {
        public void onLongPress(your variables);
    }
}

public class YourActivity extends Activity implements OnLongPressListener {

    @Override
    public void onLongPress(your variables) {
        // handle the longPress in your activity here:
    }
}

或者使用类似EventBus的东西来触发事件。 - Alen Siljak

1
在onLongPress中调用Activity.openContextMenu(View v)。这意味着MyWebView需要保留对Activity的引用。

0
我注意到在模拟器中长按任何东西需要很长时间的按压,大约需要5-7秒,而不是现实生活中的1-2秒。确保您按压至少10秒钟,否则似乎什么也不会发生。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接