2014-04-01 19 views
6

Avevo creato una visualizzazione personalizzata per la mia app estendendo RelativeLayout. Si apre come dialog, trascinando uno ImageView. Ha EditTexts e Buttons. Sto sovrascrivendo onKeyDown a mio avviso poiché ho bisogno di intercettare il pulsante indietro da questa vista. Se la vista personalizzata è visibile, edittext non ha acquisito il focus e se premo il pulsante indietro, la vista verrà chiusa, il che è desiderato.Android: Gestisci il pulsante Indietro dalla visualizzazione personalizzata

Si verifica un problema, quando edittext ha acquisito la messa a fuoco e la tastiera è visibile, premendo il pulsante Indietro, la tastiera virtuale viene ignorata, ma se si preme di nuovo il pulsante di nuovo, invece di ignorare la vista personalizzata, viene chiamato super.onKeyDown() e si esce da la mia app, in cui la funzione desiderata è quella di chiudere la visualizzazione dopo il licenziamento della tastiera virtuale. Che cosa sto facendo di sbagliato?

Qui di seguito è il mio codice personalizzato vista:

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: dialogo non avevo usato o finestra pop-up a causa di progettare limitazione nella mia app.

Update 1

Quando la tastiera è chiuso, la messa a fuoco non si sposta di nuovo alla mia vista personalizzata. Ho provato la risposta suggerita di seguito, ma ho capito, Android non invia eventi IME quando la tastiera viene chiusa. C'è un altro modo per riportare l'attenzione sulla mia vista dopo il licenziamento della tastiera?

Update 2 Proprio ora, ho trovato che onKeyListener di EditText sparato solo dopo ho premuto di nuovo il pulsante seconda volta, vale a dire dopo il licenziamento della tastiera. Ecco perché la soluzione di seguito, non ha funzionato.

risposta

11

ho finalmente risolto il mio problema, la soluzione è quella di utilizzare dispatchKeyEventPreIme. Qui di seguito è frammento dal mio codice vero e proprio:

@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); 
} 

Ma il merito effettivo va a this post.

-1

si fa a non avere onbackpress nella vostra attività principale con

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

o sui tuoi modificare il testo

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

Questa vista sarà visibile dai frammenti. Per intercettare il pulsante back da framment, devo implementare la callback all'interno dell'attività, che si concluderà con molte condizioni e verifiche. Voglio evitare questo sovraccarico, quindi ho bisogno di intercettare il pulsante indietro all'interno della mia visualizzazione personalizzata. Sarà come una finestra di dialogo si comporta sul pulsante Indietro – Nitish

+0

ok, puoi gestire la chiusura della tastiera su backpress quando usi edittext. e requestfocus sul layout? – RuAware

+0

L'ho provato prima. Quando la tastiera era visibile, premendo il pulsante Indietro, la tastiera si chiudeva come desiderato, ma non si presentava la registrazione di OverKeyDown sovrascritta. – Nitish

Problemi correlati