seleccionar - Cómo anular el menú de selección de texto de vista web en Android
manual de programacion android pdf (3)
Necesita sobrescribir los menús de acción de la actividad
más información que puede leer: https://developer.android.com/guide/topics/ui/menus.html
CÓMO SOBRESCRIBIR:
@Override
public void onActionModeStarted(android.view.ActionMode mode) {
mode.getMenu().clear();
Menu menus = mode.getMenu();
mode.getMenuInflater().inflate(R.menu.highlight,menus);
super.onActionModeStarted(mode);
}
realce
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/impclick"
android:title="Mark As Important"
/>
<item android:id="@+id/colorclick"
android:title="Mark with color" />
</menu>
El menú básico de selección de texto de Android es como se muestra en la imagen adjunta a continuación. Tiene opciones como copiar, compartir, seleccionar todo, búsqueda web.
Quiero sobrepasar estos menús y quererlos como mi propia lista de menú como "marcar color", "marcar como imp", etc. Miro a mi alrededor la mayoría de las preguntas disponibles sobre el menú contextual en el desbordamiento de la pila. La mayor parte de la pregunta se relaciona con el menú contextual, pero no da el resultado esperado. Quiero un menú como debajo de la imagen
Cuando realizo la selección de Android, el monitor muestra un formulario de creación de vista viewRoot like
D/ViewRootImpl: #1 mView = android.widget.PopupWindow$PopupDecorView{648898f V.E...... ......I. 0,0-0,0}
D/ViewRootImpl: #1 mView = android.widget.PopupWindow$PopupDecorView{a66541c V.E...... ......I. 0,0-0,0}
D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl: MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
¿Cómo lograr tal implementación?
También revisé https://github.com/naoak/WebViewMarker pero no obtuve el resultado correcto.
¿Qué he hecho ya?
Extiendo WebView de Android y quiero hacer soporte para un mínimo de SDK 19. Cuando realizo una pulsación larga recibí un evento de prensa larga, pero no puedo obtener tales llamadas de API de creación de menús.
Creo que aquí puedo ayudarte.
En aras de la integridad, aquí es cómo resolví el problema:
Seguí la sugerencia de acuerdo con esta respuesta, con un poco más de ajuste para que coincida más estrechamente con el código anulado:
la clase pública MyWebView extiende WebView {
private ActionMode mActionMode;
private mActionMode.Callback mActionModeCallback;
@Override
public ActionMode startActionMode(Callback callback) {
ViewParent parent = getParent();
if (parent == null) {
return null;
}
mActionModeCallback = new CustomActionModeCallback();
return parent.startActionModeForChild(this, mActionModeCallback);
}
}
Esencialmente, esto obliga a su CAB personalizado a aparecer en lugar de CAB de Android. Ahora debe modificar su devolución de llamada para que el resaltado de texto desaparezca junto con el CAB:
clase pública MyWebView extiende WebView {... clase privada CustomActionModeCallback implementa ActionMode.Callback {... // Todo hasta este punto es el mismo que en la pregunta
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
clearFocus(); // This is the new code to remove the text highlight
mActionMode = null;
}
}
}
Eso es todo al respecto. Tenga en cuenta que, siempre que utilice MyWebView con el startActionMode reemplazado, no hay forma de obtener el CAB nativo (el menú copiar / pegar, en el caso de una WebView). Es posible implementar ese tipo de comportamiento, pero esa no es la forma en que funciona este código. ACTUALIZACIÓN: ¡Hay una manera mucho más fácil de hacer esto! La solución anterior funciona bien, pero aquí hay una manera alternativa y más sencilla.
Esta solución proporciona menos control sobre ActionMode, pero requiere mucho menos código que la solución anterior.
public class MyActivity extends Activity {
private ActionMode mActionMode = null;
@Override
public void onActionModeStarted(ActionMode mode) {
if (mActionMode == null) {
mActionMode = mode;
Menu menu = mode.getMenu();
// Remove the default menu items (select all, copy, paste, search)
menu.clear();
// If you want to keep any of the defaults,
// remove the items you don''t want individually:
// menu.removeItem(android.R.id.[id_of_item_to_remove])
// Inflate your own menu items
mode.getMenuInflater().inflate(R.menu.my_custom_menu, menu);
}
super.onActionModeStarted(mode);
}
// This method is what you should set as your item''s onClick
// <item android:onClick="onContextualMenuItemClicked" />
public void onContextualMenuItemClicked(MenuItem item) {
switch (item.getItemId()) {
case R.id.example_item_1:
// do some stuff
break;
case R.id.example_item_2:
// do some different stuff
break;
default:
// ...
break;
}
// This will likely always be true, but check it anyway, just in case
if (mActionMode != null) {
mActionMode.finish();
}
}
@Override
public void onActionModeFinished(ActionMode mode) {
mActionMode = null;
super.onActionModeFinished(mode);
}
}
Aquí hay un menú de ejemplo para comenzar:
<item
android:id="@+id/example_item_1"
android:icon="@drawable/ic_menu_example_1"
android:showAsAction="always"
android:onClick="onContextualMenuItemClicked"
android:title="@string/example_1">
</item>
<item
android:id="@+id/example_item_2"
android:icon="@drawable/ic_menu_example_2"
android:showAsAction="ifRoom"
android:onClick="onContextualMenuItemClicked"
android:title="@string/example_2">
</item>
¡Eso es! ¡Terminaste! Ahora aparecerá su menú personalizado, no tiene que preocuparse por la selección, y apenas tiene que preocuparse por el ciclo de vida de ActionMode.
Esto funciona de forma casi perfecta con una WebView que ocupa toda su Actividad principal. No estoy seguro de qué tan bien funcionará si hay múltiples Vistas dentro de su Actividad a la vez. Es probable que requiera algunos ajustes en ese caso.
Esta solución no depende del modo de acción Acción y funciona para todas las plataformas Android
Traté de dar una respuesta pero excede los límites de caracteres, así que estoy poniendo parte de código
Enlace de referencia 1 para la selección en la vista web
Enlace de referencia 2 para crear un marcador de vista web
Ambos enlaces de arriba realmente juegan un papel importante y desarrollados por algunos desarrolladores increíbles. Lo primero de todo necesita algunas investigaciones sobre TextSelectionSupport Class From Reference Link 1. Personalicé dos líneas de código en la clase TextSelectionSupport para obtener un rectángulo de selección en el Listener de selección aquí.
Clone el proyecto de ejemplo desde aquí https://github.com/ab-cse-2014/WebViewSelection.git
Consulte Implementación de clases CustomWebView y Uso de TextSelectionSupport.
Esta es mi clase de vista web en el proyecto
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebView;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.cse.webviewtextselection.R;
import com.cse.webviewtextselection.webviewmaker.TextSelectionSupport;
public class CustomWebView extends WebView {
private final String TAG = this.getClass().getSimpleName();
private Context mContext;
private TextSelectionSupport mTextSelectionSupport;
private PopupWindow mPopupWindow;
private int currentTop;
public CustomWebView(Context context) {
super(context);
mContext = context;
initSetUp();
preparePopupWindow();
}
public CustomWebView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initSetUp();
preparePopupWindow();
}
public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initSetUp();
preparePopupWindow();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
initSetUp();
preparePopupWindow();
}
private void initSetUp() {
mTextSelectionSupport = TextSelectionSupport.support((AppCompatActivity) mContext, this);
mTextSelectionSupport.setSelectionListener(new TextSelectionSupport.SelectionListener() {
@Override
public void startSelection() {
}
@Override
public void selectionChanged(String text, Rect rect) {
Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
showPopAtLocation(mPopupWindow, rect.left, rect.top);
}
@Override
public void endSelection() {
if (mPopupWindow != null) {
mPopupWindow.dismiss();
}
}
});
}
private void preparePopupWindow() {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View customPopupView = layoutInflater.inflate(R.layout.custom_popup_layout, null);
mPopupWindow = new PopupWindow(customPopupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true);
mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
}
private void showPopAtLocation(PopupWindow mPopupWindow, int x, int y) {
if (mPopupWindow != null) {
if (currentTop != 0 || currentTop > ((AppCompatActivity)mContext).getWindow().getDecorView().getHeight()) {
if (y > currentTop) {
y -= currentTop;
}
}
Log.d("Current Top : ", String.valueOf(currentTop));
Log.d("Y : ", String.valueOf(y));
//mPopupWindow.showAtLocation(((AppCompatActivity)mContext).findViewById(R.id.parentRelativeLayout), Gravity.NO_GRAVITY, x, y);
mPopupWindow.showAtLocation(((AppCompatActivity)mContext).getWindow().getDecorView(), Gravity.NO_GRAVITY, x, y);
}
}
@Override
protected void onScrollChanged(int newLeft, int newTop, int oldLeft, int oldTop) {
currentTop = newTop;
super.onScrollChanged(newLeft, newTop, oldLeft, oldTop);
}
}
Menú emergente personalizado XML como la selección inteligente de texto de androides (custom_popup_layout.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myCustomMenuLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@android:color/transparent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@android:color/white"
android:elevation="5dp"
android:layout_margin="12dp">
<TextView
android:id="@+id/menuOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mark With Color"
android:textColor="@android:color/black"
android:padding="10dp"
android:maxLines="1"/>
<TextView
android:id="@+id/menuTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mark As Important"
android:textColor="@android:color/black"
android:padding="10dp"
android:maxLines="1"/>
<TextView
android:id="@+id/menuThree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show More"
android:textColor="@android:color/black"
android:padding="10dp"
android:maxLines="1"/>
</LinearLayout>
</LinearLayout>
Capturas de pantalla de salida