2011-02-03 12 views
5

Actualmente estoy tratando de obtener un WebView personalizado que muestre un ContextMenu cuando se presiona por un tiempo más prolongado. A medida que la clase WebView por defecto sólo muestra un ContextMenu cuando se longPressed un enlace, escribí mi propia clase para anular este comportamiento:Android: abrir un ContextMenu desde onLongPress en WebView personalizado

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

Esto funciona sin problemas el LongPress se detecta y el método onLongPress se llama, sin embargo estoy a pérdida cuando se trata de mostrar el ContextMenu. He intentado hacerlo de la manera habitual en mi Actividad:

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

Sin embargo, cuando el LongPress MyWebView en el emulador, no pasa nada. ¿A qué tengo que llamar desde onLongPress() para visualizar ContextMenu?

Respuesta

1

Llame a Activity.openContextMenu (Ver v) en onLongPress. Sin embargo, esto significaría que MyWebView guardará una referencia a la Actividad.

3

Lo tengo trabajando ahora, basándose en la sugerencia de gngr44. Hice que mi actividad implementara la clase OnLongClickListener y proporcioné un método onLongClick() que abre el menú contextual.

El código revisado:

La vista web personalizado:

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

Mi Actividad:

@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

Esto hace que el menú contextual funcione. Sin embargo, ya no puedo desplazarme por la página web. En realidad, cualquier toque emergerá el menú contextual. ¿Alguna idea de cómo hacer que funcione perperly? – newman

+1

Lo mismo aquí, la vista web pierde su capacidad de desplazamiento – KingFu

+0

Creo que se debe a que ha anulado el evento onTouch pero no ha implementado la superclase. @Override public boolean onTouchEvent (evento MotionEvent) { if (gestureDetector.onTouchEvent (event)) return true; return super.onTouchEvent (evento); } El código proporcionado debería ser el truco :) –

0

me di cuenta de que a largo presionar nada en el emulador requiere mucho presionando, como 5-7 segundos en comparación con un 1-2 normal en la vida real. Asegúrese de presionar durante al menos 10 segundos, de lo contrario, parecería que no pasa nada.

2

En lugar de acceder a la actividad desde su vista, le recomendaría usar una interfaz en su vista e implementar esa interfaz desde su actividad.

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: 
    } 
} 
+0

O active un evento usando algo como EventBus. –

Cuestiones relacionadas