2014-04-01 12 views
6

Ich hatte eine benutzerdefinierte Ansicht für meine App durch Erweitern RelativeLayout erstellt. Es öffnet sich als dialog, indem man eine ImageView zieht. Es hat EditTexts und Buttons. Ich überschreie onKeyDown aus meiner Sicht, da ich zurück Knopf von dieser Ansicht abfangen muss. Wenn die benutzerdefinierte Ansicht sichtbar ist, hat der Bearbeitungstext den Fokus nicht erreicht, und wenn ich die Zurück-Schaltfläche drücke, wird die Ansicht verworfen, was gewünscht ist.Android: Handle Back-Schaltfläche von benutzerdefinierten Ansicht

Problem entsteht, wenn edittext Fokus gewonnen hat, und Tastatur ist sichtbar, beim Zurückdrücken Taste, Soft-Tastatur wird entlassen, aber wenn ich wieder Taste drücken, dann statt super.onKeyDown() aufgerufen wird, und ich gehe aus Meine App, wo als gewünschte Funktion ist, die Ansicht nach der Entlassung der Soft-Tastatur zu entlassen. Was mache ich falsch?

Unten ist mein benutzerdefinierte Ansicht Code:

public class AddTransactionView extends RelativeLayout implements View.OnClickListener { 
    private final String TAG = "AddTransactionView"; 

    private Context context; 

    private ViewGroup parentView; 

    private FriendsDAO mFriendsDAO; 

    private AppPreference mAppPreference; 

    private ImageLoader imageLoader; 

    private DisplayImageOptions options; 

    private CircularImageView friendsImage; 

    private Button btnIOwe, btnTheyOwe; 

    private EditText edtTransactionDesc, edtTransactionAmt; 

    private RelativeLayout relAddTransaction; 

    private int status; 

    public AddTransactionView(Context context, View anchorView, int marginTop, 
     ViewGroup parentView, FriendsDAO mFriendsDAO) { 
     super(context); 
     Log.e(TAG, "AddTransactionView constructor"); 
     this.context = context; 
     this.parentView = parentView; 
     this.mFriendsDAO = mFriendsDAO; 
     doInitialization(); 
     LayoutInflater inflater = (LayoutInflater) context 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view = inflater.inflate(R.layout.add_transaction_popup, this); 

     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
      RelativeLayout.LayoutParams.MATCH_PARENT, 
      RelativeLayout.LayoutParams.MATCH_PARENT); 

     params.addRule(RelativeLayout.ABOVE, anchorView.getId()); 
     params.setMargins(0, marginTop, 0, 0); 
     view.setLayoutParams(params); 
     this.setFocusableInTouchMode(true); 
     this.requestFocus(); 
     parentView.addView(this); 
     initializeView(view, mFriendsDAO); 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     Log.e(TAG, "onKeyCodeDown"); 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      Log.e(TAG, "onKeyCodeDown if"); 
      Log.e(TAG, "onKeyCodeDown else"); 
      dismiss(); 
      return true; 
     } else { 
      Log.e(TAG, "onKeyCodeDown default"); 
      return super.onKeyDown(keyCode, event); 
     } 
    } 

    private void dismiss() { 
     parentView.removeView(this); 
    } 
} 

PS: Ich hatte in meiner app nicht verwendet Dialog oder Popup-Fenster Beschränkung auf Grund zu entwerfen.

Update 1

Wenn Tastatur geschlossen ist, der Fokus nicht verschiebt zurück zu meiner benutzerdefinierten Ansicht. Ich habe versucht, die vorgeschlagene Antwort unten, aber ich fand heraus, Android sendet keine IME-Ereignisse, wenn die Tastatur abgewiesen wird. Gibt es eine andere Möglichkeit, den Fokus nach meiner Tastaturabkürzung wieder auf meine Ansicht zu lenken?

Update 2 Jetzt Just, fand ich, dass onKeyListener von EditText nur gefeuert, nachdem ich zurück Taste zweites Mal gedrückt, dass nach Entlassung der Tastatur. Deshalb hat die Lösung unten nicht funktioniert.

Antwort

11

ich endlich mein Problem gelöst haben, ist die Lösung dispatchKeyEventPreIme zu verwenden. Im Folgenden wird von meinem eigentlichen Code-Snippet:

@Override 
public boolean dispatchKeyEventPreIme(KeyEvent event) { 
    Log.e(TAG, "dispatchKeyEventPreIme(" + event + ")"); 
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 
     KeyEvent.DispatcherState state = getKeyDispatcherState(); 
     if (state != null) { 
      Log.e(TAG, "dispatchKeyEventPreIme state != null"); 
      if (event.getAction() == KeyEvent.ACTION_DOWN 
        && event.getRepeatCount() == 0) { 
       Log.e(TAG, "dispatchKeyEventPreIme ACTION_DOWN"); 
       state.startTracking(event, this); 
       return true; 
      } else if (event.getAction() == KeyEvent.ACTION_UP 
        && !event.isCanceled() && state.isTracking(event)) { 
       Log.e(TAG, "dispatchKeyEventPreIme ACTION_UP"); 
       if (edtTransactionAmt.hasFocus() 
         || edtTransactionDesc.hasFocus()) { 
        Log.e(TAG, "dispatchKeyEventPreIme edittext has focus"); 
        AppUtils.hideSoftKeyboard(context, edtTransactionAmt); 
        edtTransactionAmt.clearFocus(); 
        edtTransactionDesc.clearFocus(); 
       } else { 
        Log.e(TAG, "dispatchKeyEventPreIme dismiss view"); 
        dismiss(); 
       } 
       return true; 
      } 
     } 
    } 

    return super.dispatchKeyEventPreIme(event); 
} 

Aber der eigentliche Kredit geht an this post.

-1

Können Sie nicht onbackpress in Ihrer Haupttätigkeit mit

if (myAddTransactionView.getVisibility == LinearLayout.VISIBLE) { 
    myAddTransactionView.dismiss(); 
} else { 
    Super..... 

oder Ihren Text bearbeiten

edtTransactionDesc.setOnKeyListener(new OnKeyListener() 
{ 
    public boolean onKey(View v, int keyCode, KeyEvent event) 
    { 
     if (event.getAction() == KeyEvent.ACTION_DOWN) 
     { 
      //check if the right key was pressed 
      if (keyCode == KeyEvent.KEYCODE_BACK) 
      { 
       InputMethodManager imm = (InputMethodManager)getSystemService(
       Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(edtTransactionDesc.getWindowToken(), 0); 
       AddTransactionView.this.requestFocus(); 
       return false; 
      } 
     } 
     return true; 
    } 
}); 
+0

Diese Ansicht wird von Fragmenten sichtbar sein. Um Back-Button von Fragment abzufangen, muss ich Callback innerhalb der Aktivität implementieren, die mit vielen Bedingungen und Prüfungen enden wird. Ich möchte diesen Overhead vermeiden, daher muss ich den Zurück-Button in meiner benutzerdefinierten Ansicht abfangen. Es wird dasselbe sein, wie sich ein Dialog auf dem Zurück-Knopf verhält – Nitish

+0

ok, können Sie das Schließen der Tastatur auf Rückdruck behandeln, wenn Sie edittext verwenden. und fragen Sie nach dem Layout? – RuAware

+0

Ich habe es früher versucht. Wenn die Tastatur sichtbar war, wurde beim Drücken der Zurück-Taste die Tastatur wie gewünscht ausgeblendet, loggte sich aber ein, mein übersteuertes onKeyDown tauchte nicht auf. – Nitish