2011-05-19 14 views
13

Voglio consentire all'utente di selezionare alcuni testi da webview e deve essere inviato come messaggio di testo. pls trova il modo di selezionare il testo e di copiarlo negli appunti e di estrarlo dagli appunti. Ho visto molti esempio, ma niente mi ha aiutato davvero ... TIAAndroid: come selezionare i testi dalla webview

Modifica
utilizzando il codice fornito nel collegamento da @ orangmoney52. con le seguenti modifiche

secondo parametro getmethod e richiamo metodo secondo parametro. se io do nulla, l'avvertimento arriverà ... quale è corretto?

public void selectAndCopyText() { 
    try { 
     Method m = WebView.class.getMethod("emulateShiftHeld", Boolean.TYPE); 
      m.invoke(BookView.mWebView, false); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      // fallback 
      KeyEvent shiftPressEvent = new KeyEvent(0,0, 
       KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_SHIFT_LEFT,0,0); 
      shiftPressEvent.dispatch(this); 
     } 

} 

questo errore:

05-26 16:41:01.121: WARN/System.err(1096): java.lang.NoSuchMethodException: emulateShiftHeld 
+0

Si prega di aggiungere snippet completo –

risposta

14

Le risposte di cui sopra sembra perfettamente bene e sembra che stai perdendo qualcosa durante la selezione del testo. Quindi è necessario ricontrollare il codice e trovare il tuo override qualsiasi TouchEvent di webview.

ho provato sotto il codice che funziona bene ...

La funzione è

private void emulateShiftHeld(WebView view) 
    { 
     try 
     { 
      KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, 
                KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0); 
      shiftPressEvent.dispatch(view); 
      Toast.makeText(this, "select_text_now", Toast.LENGTH_SHORT).show(); 
     } 
     catch (Exception e) 
     { 
      Log.e("dd", "Exception in emulateShiftHeld()", e); 
     } 
    } 

chiamata Sopra metodo dove si vuole (si può mettere un pulsante e chiamare questo metodo nel suo evento click): emulateShiftHeld (mWebView);

+1

Su Android 4+ non funziona. http://stackoverflow.com/questions/21101181/android-webview-how-to-correctly-copy-selected-text –

+10

Non capisco nemmeno cosa stia cercando di dire questa risposta. – Michael

+0

per favore aggiungi qui tutto lo snippet in modo che il debuttante possa usarlo facilmente –

0

@vnshetty, utilizzando il codice fornito nel collegamento da @ orangmoney52, sono stato in grado di completare questo problema qualche mese fa. Puoi creare un pulsante nel tuo menu che ti consenta di copiare il testo. Poi, in onOptionsItemSelected, si può avere una clausola del genere:

case R.id.select_and_copy: { 
     Toast.makeText(getApplicationContext(), "Select Text", Toast.LENGTH_SHORT).show(); 
     selectAndCopyText(); 
     return true; 
    } 
+0

Sì Dopo che viene visualizzato il toast ho premuto il tasto MAIUSC e provare a selezionare il contenuto del webview usando il mouse ma non è selezionato nulla? Mi manca qualcosa? – vnshetty

+0

Non è necessario premere il tasto Maiusc. Basta selezionare il testo dopo la visualizzazione del messaggio di toast. – Phil

5

Il modo più semplice, anche se non così bella come quella che sembra una per fabbricante implementato funzionalità di copia/incolla, è la seguente:

https://bugzilla.wikimedia.org/show_bug.cgi?id=31484

In sostanza, se si sta impostando il proprio WebChromeClient tramite webview.setWebChromeClient(...) quindi la selezione del testo è disabilitata per impostazione predefinita. Per abilitarlo vostre esigenze WebChromeClient dover seguente metodo implementato:

//@Override 
/** 
* Tell the client that the selection has been initiated. 
*/ 
public void onSelectionStart(WebView view) { 
    // Parent class aborts the selection, which seems like a terrible default. 
    //Log.i("DroidGap", "onSelectionStart called"); 
} 
+0

Nel mio caso non funziona anche. Sto sovrascrivendo onTouch() ma restituisce false. Qual è stato il vero problema, hai sovrascritto gli eventi di tocco? – DroidBot

+0

Il mio suggerimento non era quello di sovrascrivere onTouch(). Le impostazioni sono personalizzate, personalizzate, WebChromeClient? –

+0

Ehi, questo funziona davvero! – Bruce

6

Fase: 1 Crea classe WebView personalizzata. Questa classe sovrascriverà la barra di azione nativa alla lunga pressione sul testo della vista web. Inoltre gestisce il caso di selezione per diverse versioni di Android (testato in 4.0 in poi) Questo codice prende il testo selezionato utilizzando javascript.

public class CustomWebView extends WebView { 
private Context context; 
// override all other constructor to avoid crash 
public CustomWebView(Context context) { 
    super(context); 
    this.context = context; 
    WebSettings webviewSettings = getSettings(); 
    webviewSettings.setJavaScriptEnabled(true); 
    // add JavaScript interface for copy 
    addJavascriptInterface(new WebAppInterface(context), "JSInterface"); 
} 

// setting custom action bar 
private ActionMode mActionMode; 
private ActionMode.Callback mSelectActionModeCallback; 
private GestureDetector mDetector; 

// this will over ride the default action bar on long press 
@Override 
public ActionMode startActionMode(Callback callback) { 
    ViewParent parent = getParent(); 
    if (parent == null) { 
     return null; 
    } 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 
     String name = callback.getClass().toString(); 
     if (name.contains("SelectActionModeCallback")) { 
      mSelectActionModeCallback = callback; 
      mDetector = new GestureDetector(context, 
        new CustomGestureListener()); 
     } 
    } 
    CustomActionModeCallback mActionModeCallback = new CustomActionModeCallback(); 
    return parent.startActionModeForChild(this, mActionModeCallback); 
} 

private class CustomActionModeCallback implements ActionMode.Callback { 

    @Override 
    public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
     mActionMode = mode; 
     MenuInflater inflater = mode.getMenuInflater(); 
     inflater.inflate(R.menu.menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
     return false; 
    } 

    @Override 
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 

     switch (item.getItemId()) { 
     case R.id.copy: 
      getSelectedData(); 
      mode.finish(); 
      return true; 
     case R.id.share: 
      mode.finish(); 
      return true; 
     default: 
      mode.finish(); 
      return false; 
     } 
    } 
    @Override 
    public void onDestroyActionMode(ActionMode mode) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      clearFocus(); 
     }else{ 
      if (mSelectActionModeCallback != null) { 
       mSelectActionModeCallback.onDestroyActionMode(mode); 
      } 
      mActionMode = null; 
     } 
    } 
} 
private void getSelectedData(){ 

    String js= "(function getSelectedText() {"+ 
      "var txt;"+ 
      "if (window.getSelection) {"+ 
       "txt = window.getSelection().toString();"+ 
      "} else if (window.document.getSelection) {"+ 
       "txt = window.document.getSelection().toString();"+ 
      "} else if (window.document.selection) {"+ 
       "txt = window.document.selection.createRange().text;"+ 
      "}"+ 
      "JSInterface.getText(txt);"+ 
      "})()"; 
    // calling the js function 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
     evaluateJavascript("javascript:"+js, null); 
    }else{ 
     loadUrl("javascript:"+js); 
    } 
} 

private class CustomGestureListener extends GestureDetector.SimpleOnGestureListener { 
    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     if (mActionMode != null) { 
      mActionMode.finish(); 
      return true; 
     } 
     return false; 
    } 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    // Send the event to our gesture detector 
    // If it is implemented, there will be a return value 
    if(mDetector !=null) 
     mDetector.onTouchEvent(event); 
    // If the detected gesture is unimplemented, send it to the superclass 
    return super.onTouchEvent(event); 
} 

}

Fase 2: creare classe separata per l'interfaccia WebView. Questa listnes classe per l'evento da una volta codice javascript è sempre eseguito

public class WebAppInterface { 
Context mContext; 

WebAppInterface(Context c) { 
    mContext = c; 
} 

@JavascriptInterface 
public void getText(String text) { 
    // put selected text into clipdata 
    ClipboardManager clipboard = (ClipboardManager) 
      mContext.getSystemService(Context.CLIPBOARD_SERVICE); 
    ClipData clip = ClipData.newPlainText("simple text",text); 
    clipboard.setPrimaryClip(clip); 
    // gives the toast for selected text 
    Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show(); 
} 
} 

Fase 3: Aggiungi menu.xml per il menu personalizzato in res> cartella di menu

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" > 
<item 
    android:id="@+id/copy" 
    android:icon="@drawable/ic_action_copy" 
    android:showAsAction="always" 
    android:title="copy"> 
</item> 
<item 
    android:id="@+id/share" 
    android:icon="@drawable/ic_action_share" 
    android:showAsAction="always" 
    android:title="share"> 
</item> 

ho preso aiuto di diversi collegamenti elencati di seguito per raggiungere questo obiettivo: grazie a voi ragazzi.

come utilizzare javascript WebView http://developer.android.com/guide/webapps/webview.html#UsingJavaScript

per l'iniezione di javascript Why can't I inject this javascript in the webview on android?

per superiori bar azione predefinita How to override default text selection of android webview os 4.1+?

per la versione 4.0. a 4.3 selezione del testo Webview text selection not clearing

+0

come abilitare la selezione sulla lunga pressione della webview? per favore aiutami per quello :) –