2011-06-08 86 views
80

在我的應用程序中,有一個註冊屏幕,我不希望用戶能夠將文本複製/粘貼到EditText字段中。我在每個EditText上設置了一個onLongClickListener,以便顯示覆制/粘貼/輸入方法和其他選項的上下文菜單不顯示。所以用戶將無法複製/粘貼到編輯字段。如何從/向EditText禁用複製/粘貼

OnLongClickListener mOnLongClickListener = new OnLongClickListener() { 

     @Override 
     public boolean onLongClick(View v) { 
      // prevent context menu from being popped up, so that user 
      // cannot copy/paste from/into any EditText fields. 
      return true; 
     } 
    }; 

但是,如果用戶已啓用比Android的默認以外的第三方鍵盤,它可以有一個按鈕,複製/粘貼或可以顯示相同的上下文菜單中就會出現問題。那麼,我該如何禁用複製/粘貼在這種情況下?

請讓我知道是否有其他方法複製/粘貼。 (並可能如何禁用它們)

任何幫助,將不勝感激。

+0

如果「粘貼」操作來自IME,那麼您沒有將其與正常擊鍵區分的標準方法。要嘗試的一個想法是衡量每個角色到達之間的時間,如果時間太短,則角色來自「粘貼」操作。 – BitBank 2011-11-13 17:10:16

+0

似乎是骯髒的soloution!值得一看,但。 – rDroid 2011-11-14 08:10:12

回答

77

如果您使用的API級別11或以上,那麼你可以停止複製,粘貼,剪切和自定義上下文菜單。

edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() { 

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

      public void onDestroyActionMode(ActionMode mode) {     
      } 

      public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
       return false; 
      } 

      public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
       return false; 
      } 
     }); 

從onCreateActionMode(ActionMode,菜單)返回false將阻止啓動的動作模式(全選,剪切,複製和粘貼操作)。

+0

API級別高於13的智能手機的任何東西。這與平板電腦 – Unknown 2012-12-27 05:13:00

+1

罰款如何關於api級別低於13? – jonney 2013-02-08 11:05:02

+1

不理解任何意見,這個樣本作品api11 +,pre-api11沒有複製和粘貼IIRC – scottyab 2013-09-11 12:56:32

1

閱讀剪貼板,檢查輸入和輸入「鍵入」的時間。如果剪貼板文本相同且速度太快,請刪除粘貼的輸入。

0

我發現當您創建一個輸入過濾器以避免輸入不需要的字符時,將這些字符粘貼到編輯文本中是沒有任何效果的。所以這也解決了我的問題。

20

我可以用下面的禁用複製和粘貼功能:

textField.setCustomSelectionActionModeCallback(new ActionMode.Callback() { 

    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { 
     return false; 
    } 

    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { 
     return false; 
    } 

    public boolean onActionItemClicked(ActionMode actionMode, MenuItem item) { 
     return false; 
    } 

    public void onDestroyActionMode(ActionMode actionMode) { 
    } 
}); 

textField.setLongClickable(false); 
textField.setTextIsSelectable(false); 

希望它爲你工作;-)

1

@Zain Ali,你的答案適用於API 11.我只是想提出一種在API 10中做的方法。由於我必須在該版本上維護我的項目API,因此我一直在玩2.3.3中提供的功能,並有可能做到這一點。我已經分享下面的代碼片段。我測試了代碼,它爲我工作。我在緊急情況下做了這個片段。隨意提高代碼是否有可以做任何改變..

// A custom TouchListener is being implemented which will clear out the focus 
// and gain the focus for the EditText, in few milliseconds so the selection 
// will be cleared and hence the copy paste option wil not pop up. 
// the respective EditText should be set with this listener 
// tmpEditText.setOnTouchListener(new MyTouchListener(tmpEditText, tmpImm)); 

public class MyTouchListener implements View.OnTouchListener { 

    long click = 0; 
    EditText mEtView; 
    InputMethodManager imm; 

    public MyTouchListener(EditText etView, InputMethodManager im) { 
     mEtView = etView; 
     imm = im; 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 

     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      long curr = System.currentTimeMillis(); 
      if (click !=0 && (curr - click) < 30) { 

       mEtView.setSelected(false); 
       new Handler().postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         mEtView.setSelected(true); 
         mEtView.requestFocusFromTouch(); 
         imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); 
        } 
       },25); 

      return true; 
      } 
      else { 
       if (click == 0) 
        click = curr; 
       else 
        click = 0; 
       new Handler().postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         mEtView.requestFocusFromTouch(); 
         mEtView.requestFocusFromTouch(); 
         imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); 
        } 
       },25); 
      return true; 
      } 

     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      mEtView.setSelected(false); 
      new Handler().postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        mEtView.setSelected(true); 
        mEtView.requestFocusFromTouch(); 
        mEtView.requestFocusFromTouch(); 
        imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN); 
       } 
      },25); 
      return true; 
     } 
     return false; 
    } 
84

最好的方法是使用:

etUsername.setLongClickable(false); 
+40

或者,只需在xml'android:longClickable =「false」':) – lomza 2014-01-24 10:12:53

+13

點擊藍色光標指示器時,會出現粘貼按鈕。 – void 2014-03-13 05:08:01

+10

這肯定會阻止視圖長時間點擊,但編輯控件也可以通過雙擊文本來請求,這意味着此解決方案不完整。記住你的目的。 – 2014-04-22 19:09:28

3

https://github.com/neopixl/PixlUI提供了一種方法

myEditText.disableCopyAndPaste()EditText

而且它是在舊的API

+1

這與http://stackoverflow.com/a/22756538/3063884提供的半解決方案完全相同。請參閱代碼:https://github.com/neopixl/PixlUI/blob/master/Library/src/com/neopixl/pixlui/components/edittext/EditText.java#L304 ...這種方法仍然無法阻止文本選擇處理程序顯示「PASTE」,如果剪貼板中有文本。 – CJBS 2015-02-28 08:54:10

11

這裏是禁止的EditText的長按來禁用EDITTEXT工作的剪切複製粘貼在所有版本

if (android.os.Build.VERSION.SDK_INT < 11) { 
     editText.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { 

      @Override 
      public void onCreateContextMenu(ContextMenu menu, View v, 
        ContextMenuInfo menuInfo) { 
       // TODO Auto-generated method stub 
       menu.clear(); 
      } 
     }); 
    } else { 
     editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() { 

      public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
       // TODO Auto-generated method stub 
       return false; 
      } 

      public void onDestroyActionMode(ActionMode mode) { 
       // TODO Auto-generated method stub 

      } 

      public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
       // TODO Auto-generated method stub 
       return false; 
      } 

      public boolean onActionItemClicked(ActionMode mode, 
        MenuItem item) { 
       // TODO Auto-generated method stub 
       return false; 
      } 
     }); 
    } 
+0

這爲我工作,我不得不添加 @TargetApi(Build.VERSION_CODES.HONEYCOMB) – Sheepdogsheep 2014-04-24 11:53:55

23

你可以這樣做一個最好的方式工作

要實現它,只需添加以下行的XML -

android:longClickable="false" 
+3

的問題是,我的應用程序用戶具有複製和粘貼按鈕第三方鍵盤。 – rDroid 2015-04-16 07:49:42

+0

另一個問題是您可以通過雙擊選擇文本,並顯示覆制/粘貼 – Nikola 2018-01-24 14:19:46

8

除了setCustomSelectionActionModeCallbackdisabled long-click解決方案,有必要prevent the PASTE/REPLACE menus出現單擊該文本選擇手柄時,按照下面的圖片:

Text selection handle with paste menu

解決之道在於防止粘貼/替換菜單從出現在(未記錄)android.widget.Editor類的show()方法中。在菜單出現之前,將對if (!canPaste && !canSuggest) return;進行檢查。被用作基礎來設置這些變量的兩種方法都處於EditText類:

更完整的答案是available here

+0

這是正確和完整的解決方案 – FireZenk 2016-01-26 15:29:40

0

您可以嘗試android:focusableInTouchMode =「false」。爲我工作

0

的解決方案是創建自定義EDITTEXT並重寫以下方法:

public class MyEditText extends EditText { 

private int mPreviousCursorPosition; 

@Override 
protected void onSelectionChanged(int selStart, int selEnd) { 
    CharSequence text = getText(); 
    if (text != null) { 
     if (selStart != selEnd) { 
      setSelection(mPreviousCursorPosition, mPreviousCursorPosition); 
      return; 
     } 
    } 
    mPreviousCursorPosition = selStart; 
    super.onSelectionChanged(selStart, selEnd); 
} 

}

1

這裏是禁用「粘貼」彈出黑客攻擊。你必須重寫EditText方法:

@Override 
public int getSelectionStart() { 
    for (StackTraceElement element : Thread.currentThread().getStackTrace()) { 
     if (element.getMethodName().equals("canPaste")) { 
      return -1; 
     } 
    } 
    return super.getSelectionStart(); 
} 

類似可以其他的操作來完成。

1

科特林解決方案:

fun TextView.disableCopyPaste() { 
    customSelectionActionModeCallback = object : ActionMode.Callback { 
     override fun onCreateActionMode(mode: ActionMode?, menu: Menu): Boolean { 
      return false 
     } 

     override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean { 
      return false 
     } 

     override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean { 
      return false 
     } 

     override fun onDestroyActionMode(mode: ActionMode?) {} 
    } 
    isLongClickable = false 
    setTextIsSelectable(false) 
} 

然後,你可以簡單地調用這個方法對你TextView

override fun onCreate() { 
    priceEditText.disableCopyPaste() 
} 
0

如果不wan't禁用長按,因爲你需要執行一些長時間點擊而不是返回true功能是一個更好的選擇。

你的edittext長按就會是這樣。

edittext.setOnLongClickListener(new View.OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 
      // Do Something or Don't 
      return true; 
     } 
}); 

documentation 返回「真」將表明,長按已處理所以沒有必要進行默認操作。

我在API等級16,22和25上測試了它。它對我來說工作得很好。希望這會有所幫助。

1

嘗試使用。

myEditext.setCursorVisible(false); 

     myEditext.setCustomSelectionActionModeCallback(new ActionMode.Callback() { 

     public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
      // TODO Auto-generated method stub 
      return false; 
     } 

     public void onDestroyActionMode(ActionMode mode) { 
      // TODO Auto-generated method stub 

     } 

     public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
      // TODO Auto-generated method stub 
      return false; 
     } 

     public boolean onActionItemClicked(ActionMode mode, 
       MenuItem item) { 
      // TODO Auto-generated method stub 
      return false; 
     } 
    });