問題描述
剛剛嘗試在真實設備上測試我的應用程序(HTC Desire Z 與 Android 2.2).并發現我的上下文菜單在 EditText
上根本不起作用.否則上下文菜單有效:在 ListView
、ImageView
等.在模擬器上一切正常...
當我點擊 EditText 時,它會顯示類似縮放框的內容,然后顯示不尋常的(不是標準的 Android 類似的)上下文菜單,內容為:選擇文本"、全選".它不顯示我的菜單.以下是截圖:
- 點擊前
- 點擊期間
- 點擊后(就是普通的選擇文字,全選,粘貼)
但沒有我在模擬器中的菜單 - 看這里p>
這是我的活動的源代碼:
公共類 MyActivity 擴展 Activity{私有靜態最終字符串 TAG=MyActivity.class.getName();編輯文本編輯文本;/*** 在第一次創建活動時調用.*/@覆蓋public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);設置內容視圖(R.layout.main);editText=(EditText)findViewById(R.id.editText);this.registerForContextMenu(editText);}@覆蓋public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){Log.v(TAG, "為視圖創建上下文菜單="+view);menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "測試菜單");super.onCreateContextMenu(menu, view, menuInfo);}@覆蓋公共布爾 onContextItemSelected(菜單項項){Log.v(TAG, "上下文項選擇為="+item.toString());返回 super.onContextItemSelected(item);}}
我已經徹底調試/記錄了我的代碼周圍的所有內容,但仍然沒有調用 Activity.onCreateContextMenu()(盡管它以正確的方式注冊).
請幫忙 - 它可能是什么?它與 HTC 的特性有關嗎?
是的,我想你看到的是 HTC 菜單.
我相信,您看到的圖形編輯上下文菜單是較新的 Desire 模型(Desire HD 和 Desire Z)的新功能.我在原始 Desire 上看到(使用您的代碼)是一個基于文本的彈出菜單,其中 HeaderTitle 設置為編輯文本"和一個列表,例如全選"、復制"、粘貼"等.但是,我還會看到一個條目說測試菜單".
我突然想到,當為 ListView 和 ImageView 等調用 onCreateContextMenu() 時,默認情況下不會預先填充傳入該調用的菜單"對象.然而,在 EditText 的情況下,它被設計為與剪貼板交互,因此系統提供基于 EditText 的內容狀態的預填充菜單(例如,如果選擇文本,則提供復制"選項;如果剪貼板上有文本,請提供粘貼"選項;...等等).
通過修改代碼清除標題和內容,我能夠獲得沒有編輯"選項的上下文菜單...
@Overridepublic void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){Log.v(TAG, "為視圖創建上下文菜單="+view);//清除當前內容menu.clearHeader();menu.clear();menu.setHeaderTitle("測試菜單");menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "測試菜單");super.onCreateContextMenu(menu, view, menuInfo);}
您得到一個圖形菜單(可能從 ContextMenu 派生)的事實表明上述技術將不起作用,因此唯一的解決方法是實例化您自己的 ContextMenu 對象,而不是使用傳遞給 onCreateContextMenu().
<塊引用>我已經徹底調試/記錄了我的代碼周圍的所有內容,但仍然沒有調用 Activity.onCreateContextMenu()
這似乎很奇怪 - 顯然它是為我調用的,因為我已經能夠使用傳遞給它的 ContextMenu.
編輯 1: 重新考慮這一點,您提到您點擊"了 EditText - 這就是您實際在做的事情(短暫觸摸然后手指向上)?
要獲得我的 ContextMenu,我必須使用長按"/單擊(觸摸并按住大約 1 秒鐘).當我簡單地點擊/觸摸我的 EditText 時,會出現軟"鍵盤,或者,如果鍵盤已經可見,則光標會簡單地移動到 EditText 框中的不同位置.
顯然 Desire Z 有一個物理鍵盤,這可能會導致行為略有不同(以及 Desire Z 的 Sense UI 版本與我的 Desire 不同).
永遠不會為您調用 onCreateContextMenu() 這一事實僅意味著一件事,即您所看到的不是 ContextMenu,而是某種其他類型的彈出 UI 元素.至少這是我能理解的唯一合乎邏輯的方式.
您能否確認長按"仍然沒有為您創建 ContextMenu,或者您一直在使用長按?
如果您嘗試過長按,請嘗試修改代碼如下...
實現 OnClickListener
公共類 MyActivity 擴展 Activity實現 OnLongClickListener {
在 onCreate 中為 editText 設置監聽器...
@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);設置內容視圖(R.layout.main);editText=(EditText)findViewById(R.id.editText);this.registerForContextMenu(editText);editText.setOnLongClickListener(this);//<-- 添加這個}
添加監聽代碼...
@Override公共布爾 onLongClick(查看 arg0){android.util.Log.v(TAG, "onLongClick() 調用");如果(arg0 == 編輯文本){android.util.Log.v(TAG, "arg0 == editText");Toast.makeText(this, "onLongClick 被攔截", 2000).show();返回真;}別的{android.util.Log.v(TAG, "arg0 != editText");返回假;}}
通過這樣做,我能夠攔截長按,并且通過從 onLongClick() 返回true",我向系統表明我已經消費"了該事件并且它沒有通過開始創建我的 ContextMenu.
如果這對您不起作用并且短按仍然會導致出現該彈出窗口,請嘗試實現 OnClickListener 并改寫 onClick().
練習的目的是,如果您可以攔截導致創建您所看到的彈出窗口的任何內容,那么您可以手動創建并顯示您自己的 ContextMenu.
Just tried to test my app on real device (HTC Desire Z with Android 2.2). And found that my context menus doesn't work at all on EditText
s. Otherwise context menus works: in ListView
, ImageView
and so on. On emulator everything works fine...
When I tap on EditText it shows something like zoom frame and then shows unusual (not standard Android alike) context menu which reads: "select text", "select all". It doesn't show my menus. Here are screenshots:
- Before tap
- During tap
- After tap (just ordinary select text, select all, paste)
but no my menu like in emulator - look here
Here's source code of my activity:
public class MyActivity extends Activity
{
private static final String TAG=MyActivity.class.getName();
EditText editText;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText=(EditText )findViewById(R.id.editText);
this.registerForContextMenu(editText);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
{
Log.v(TAG, "Creating context menu for view="+view);
menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "Test menu");
super.onCreateContextMenu(menu, view, menuInfo);
}
@Override
public boolean onContextItemSelected(MenuItem item)
{
Log.v(TAG, "Context item selected as="+item.toString());
return super.onContextItemSelected(item);
}
}
I have thoroughly debugged/logged everything around my code, but still Activity.onCreateContextMenu() not even called (though it's registered in proper way).
Please help - what it can be? Does it related to HTC peculiarities?
Yes, I think what you are seeing there is an HTC menu.
The graphical edit context menu you are seeing is, I believe, new to more recent Desire models (Desire HD and Desire Z). What I see (with your code) on my original Desire is a popup text-based menu with the HeaderTitle set as 'Edit text' and a list such as 'Select all', 'Copy', 'Paste' etc. BUT, I do also see an entry saying 'Test menu'.
It occurs to me that when onCreateContextMenu() is called for things like ListView and ImageView, the 'menu' object passed in to that call isn't pre-populated by default. In the case off an EditText, however, it is designed to interact with the Clipboard and as such the system is providing a pre-populated menu based on the EditText's content state (e.g., if text is selected, provide a 'Copy' option; if there's text on the Clipboard provide a 'Paste' option; ...and so on).
I was able to get a Context menu without the 'edit' options by clearing the header and contents by modifying your code...
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
{
Log.v(TAG, "Creating context menu for view="+view);
// Clear current contents
menu.clearHeader();
menu.clear();
menu.setHeaderTitle("TEST MENU");
menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "Test menu");
super.onCreateContextMenu(menu, view, menuInfo);
}
The fact you're getting a graphical menu (possibly derived from ContextMenu) suggests the above technique won't work so the only way around it would be to instantiate your own ContextMenu object rather than use the one passed in to onCreateContextMenu().
I have thoroughly debugged/logged everything around my code, but still Activity.onCreateContextMenu() not even called
This seems very odd - obviously it's being called for me as I've been able to play around with the ContextMenu that is being passed to it.
EDIT 1: Re-thinking this, you mention that you 'tap' the EditText - is that what you are actually doing (a short touch down then finger up)?
To get my ContextMenu I have to use a 'long' press/click (touch and hold for about 1 second). When I simply tap/touch my EditText the 'soft' keyboard appears or, if the keyboard is already visible, the cursor is simply moved to a different position in the EditText box.
Obviously the Desire Z has a physical keyboard and that may cause slightly different behaviour (as well as the Desire Z having a different version of the Sense UI to my Desire).
The fact that onCreateContextMenu() is never called for you can mean only one thing and that is, what you are seeing is NOT a ContextMenu and is some other type of popup UI element. At least that is the only logical way I can understand it.
Can you confirm that a 'long' press still doesn't create a ContextMenu for you or have you been using a long press all along?
If you have tried a long press then try modifying the code as follows...
Implement OnClickListener
public class MyActivity extends Activity implements OnLongClickListener {
Set the listener for editText in onCreate...
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); editText=(EditText )findViewById(R.id.editText); this.registerForContextMenu(editText); editText.setOnLongClickListener(this); // <-- ADD THIS }
Add the listener code...
@Override public boolean onLongClick(View arg0) { android.util.Log.v(TAG, "onLongClick() called"); if (arg0 == editText) { android.util.Log.v(TAG, "arg0 == editText"); Toast.makeText(this, "onLongClick intercepted", 2000).show(); return true; } else { android.util.Log.v(TAG, "arg0 != editText"); return false; } }
By doing this, I'm able to intercept the long press and, by returning 'true' from onLongClick() I'm indicating to the system that I've 'consumed' the event and it doesn't get passed on to cause the creation of my ContextMenu.
If this doesn't work for you and a short tap still causes that popup to appear, then try implementing OnClickListener and overriding onClick() instead.
The object of the exercise is that if you can intercept whatever is causing the creation of the popup you're seeing, you can then manually create and show your own ContextMenu.
這篇關于EditText 的 onCreateContextMenu() 在真實設備上不起作用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!