2012-06-26 79 views
1

我有一個活動,實現了View.OnKeyListener,以便在用戶點擊後退按鈕時彈出對話框。以前,它工作得很好。然而,最近它已停止工作,應用程序會假裝沒有onKey方法來捕獲後退按鈕。我似乎無法弄清楚爲什麼,因爲我進行了更改,因此我幾乎沒有觸及到onKey方法。我試着用OnBackPressed()來代替,但這並沒有解決任何問題,實際上也造成了奇怪和不可預測的行爲。任何人都可以幫我弄清楚爲什麼看起來我的應用程序讓系統在後退按鈕上佔據統治地位?View.OnKeyListener爲我的活動工作過一次,不再工作

下面是我實現的重要組成部分:

import com.actionbarsherlock.app.ActionBar; 
import com.actionbarsherlock.app.SherlockFragmentActivity; 
import com.actionbarsherlock.view.Menu; 
import com.actionbarsherlock.view.MenuItem; 
import com.actionbarsherlock.view.MenuInflater; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.view.KeyEvent; 
import android.view.View; 

public class NagTasksAddTasksActivity extends SherlockFragmentActivity implements View.OnKeyListener { 
    //various parameters 
    public void onCreate(Bundle savedInstanceBundle) 
    { 
     super.onCreate(savedInstanceBundle); 
     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 
     String setTheme = prefs.getString("themeselect", "Dark Overflow"); 
     if (setTheme.toLowerCase().contentEquals("dark overflow")){ 
      setTheme(R.style.Theme_Sherlock_ForceOverflow); 
     } else if (setTheme.toLowerCase().contentEquals("light overflow")){ 
      setTheme(R.style.Theme_Sherlock_Light_ForceOverflow); 
      isDarkThemeUsed = false; 
     } else if (setTheme.toLowerCase().contentEquals("dark menu")){ 
      setTheme(R.style.Theme_Sherlock); 
     } else if (setTheme.toLowerCase().contentEquals("light menu")){ 
      setTheme(R.style.Theme_Sherlock_Light); 
      isDarkThemeUsed = false; 
     } 
     setContentView(R.layout.createtasklayout); 
     ActionBar actionBar = getSupportActionBar(); 
     setTitle(R.string.newTask); 

    } 
    ... 
    @Override 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) 
     { 
      AlertDialog.Builder builder = new AlertDialog.Builder(this); 
      builder.setCancelable(true); 
      builder.setTitle(R.string.wait); 
      builder.setMessage(R.string.confirmbackkey); 
      builder.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        //stuff 
        dialog.dismiss(); 
       } 
      }); 
      builder.setNegativeButton(R.string.discard, new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        AlertDialog.Builder subBuilder = new AlertDialog.Builder(getParent()); 
        subBuilder.setCancelable(true); 
        subBuilder.setTitle(R.string.wait); 
        subBuilder.setMessage(R.string.confirmdiscard); 
        subBuilder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { 

         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          //more stuff 
          dialog.dismiss(); 
         } 
        }); 
        subBuilder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { 

         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          dialog.cancel(); 
         } 
        }); 
        dialog.dismiss(); 
        subBuilder.create().show(); 
       } 
      }); 
      builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 
      builder.create().show(); 
      return true; 
     } 
     return false; 
    } 
} 

回答

4

捕捉後退按鈕的另一種方法是使用Activity中的dispatchKeyEvent方法(您不需要實現View.OnKeyListener)。這似乎每次都適用於我。

public class HomeActivity extends Activity 
{ 
... 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent event) 
    { 
     int action = event.getAction(); 
     int keyCode = event.getKeyCode(); 
     switch (keyCode) 
     { 
      case KeyEvent.KEYCODE_BACK: 
       if (action == KeyEvent.ACTION_DOWN) 
       { 
        Log.v("myApp", "Back button pressed."); 
        return true; 
       } 
      default: 
       return false; 
     } 
     return false; 
    } 
} 
+0

小問題:不應該用'case'語句返回'return'嗎?類似於你應該如何配置'OnOptionsItemSelected()'? – MowDownJoe

+0

是的,它絕對應該。我想這樣的東西是一個更清潔的解決方案。這種方式我返回假,除非關鍵事件實際上做了什麼... –

+0

嗯,這工作。而且這也表明我有其他的錯誤可以找到。打擾一下。 – MowDownJoe

0

嘗試取出return truebuilder.create().show();和改變return falsereturn true,看看它是否工作。這應該讓他們都在KeyEvent初始化時返回結果。

+0

......難道不會攔截每一次按鍵,並使它們無所作爲?我的意思是,我知道我只是爲了測試目的而做這件事,但這聽起來仍然很愚蠢。 – MowDownJoe

+0

不會返回true讓一個KeyEvent返回結果? – Kurty

+0

[documentation](http://developer.android.com/guide/topics/ui/ui-events.html)建議如果你已經處理了KeyEvent並且操作系統沒有'onKey()',不需要。目前,只有當後退按鈕被按下(至少應該是)並且返回false時,代碼才被設置爲返回true。將它改爲始終返回true將意味着OS永遠不會處理該活動上的任何keyEvent。 – MowDownJoe

0

最簡單的方法是重寫OnBackPressed,並填寫您希望在有人按下後退按鈕時發生的代碼。

只要確保你刪除了super.OnBackPressed行。

+0

另外,我會將您的對話框取消設置爲false。 – droider

+0

「我試着用'OnBackPressed()'來代替,但這並沒有解決任何問題,實際上卻造成了奇怪和不可預測的行爲。」 - 從我的問題引用。 – MowDownJoe