Android TextField: ustaw fokus + programowe wprowadzanie danych programowo

81

Moim zdaniem mam wyszukiwanie EditText i chciałbym programowo wywołać zachowanie zdarzenia kliknięcia na polu, tj. Skupić się na polu tekstowym ORAZ wyświetlić klawiaturę ekranową, jeśli to konieczne (jeśli nie ma twardej klawiatury).

Próbowałem field.requestFocus(). Pole faktycznie jest fokusem, ale klawiatura programowa nie jest wyświetlana.

Próbowałem field.performClick(). Ale to tylko wywołuje OnClickListener pola.

Dowolny pomysł ?

sdabet
źródło

Odpowiedzi:

149

Dobry panie, spróbuj tego:

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

Nie jestem pewien, ale może to być wymagane na niektórych telefonach (niektóre starsze urządzenia):

final InputMethodManager inputMethodManager = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT);
pgsandstrom
źródło
3
Taki sam wynik jak w przypadku samej requestFocus () ... Pole jest aktywowane, ale klawiatura programowa nie jest uruchamiana.
sdabet
12
Wreszcie rozwiązano wyemitowanych przez wywołanie field.requestFocus()w onResume()sposobie działania (zamiast onCreate()). Nie wiem dokładnie, dlaczego to działa ...
sdabet
31
Widok nie może się skupić, zanim nie zostanie faktycznie umieszczony na ekranie. Nie można tego zrobić, gdy onCreate () przechowuje wątek UI, dlatego widok jest układany bezpośrednio po onCreate () i przed onResume (). :)
pgsandstrom
@fiddler To działa, onResumeponieważ onResumejest wywoływane po onCreate, więc fieldnie istnieje, dopóki nie onCreatezostanie uruchomione. Zobacz tutaj: developer.android.com/reference/android/app/…
Randy,
3
Doskonała sugestia, stary chłopie. Oświadczam; to zasługuje na pochwałę!
MW.
63

Oto kod, który działał dla mnie.

edittext.post(new Runnable() {
    public void run() {
        edittext.requestFocusFromTouch();
        InputMethodManager lManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); 
        lManager.showSoftInput(edittext, 0);
    }
});

Otóż ​​to! Cieszyć się ;)

elisabel
źródło
1
Dzięki i ten zadziałał dla mnie. Dodaje EditTextprogramowo, gdy użytkownik naciska przycisk.
dumbfingers
Dodałem EditTextz okna dialogowego. Niektóre flagi są ustawiane przez Androida, które powodują, że ta kontrolka nie otrzymuje żadnych dotknięć. Jeśli dodasz pole w pliku runnable, flagi nie zostaną ustawione.
JeffRegan
Wygląda InputTypena EditTextto, że Android ustawia wartość null. Jeśli ustawisz InputType, powinno działać.
JeffRegan
Jedyne działające rozwiązanie dla mnie (jeśli używam InputMethodManager do wymuszonego wyświetlania klawiatury, to nie mogę tego ukryć)
Paweł
Żadna z innych metod nie zadziałała, ale ta zadziałała. Chciałem mieć pole, w którym użytkownicy mogliby kliknąć, aby otworzyć okno dialogowe edycji, zamiast mieć linię edycji, w której można kliknąć, aby wyświetlić widok EditText. W telefonie linia edycji traci większość swojej funkcjonalności, ponieważ okno dialogowe edycji obejmuje cały ekran, więc użytkownik i tak nie widzi linii edycji, w tym liter wchodzących w nią podczas pisania.
Androidcoder
6

Poniższy kod pracował dla mnie , po dwóch innych odpowiedzi nie działa dla mnie :

@Override
public void onResume() {
    super.onResume();
    SingletonBus.INSTANCE.getBus().register(this);
    //passwordInput.requestFocus(); <-- that doesn't work
    passwordInput.postDelayed(new ShowKeyboard(), 300); //250 sometimes doesn't run if returning from LockScreen
}

Gdzie ShowKeyboardjest

private class ShowKeyboard implements Runnable {
    @Override
    public void run() {
        passwordInput.setFocusableInTouchMode(true);
  //      passwordInput.requestFocusFromTouch();
        passwordInput.requestFocus();            
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
    }
}

Po udanym wprowadzeniu upewniam się, że ukryłem klawiaturę

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(getView().getWindowToken(), 0);

Technicznie, właśnie dodałem 300 ms opóźnienia przed uruchomieniem żądania wyświetlania klawiatury programowej. Dziwne, prawda? Zmieniono również requestFocus()na requestFocusFromTouch().

EDYCJA: Nie używaj requestFocusFromTouch(), daje to zdarzenie dotykowe programowi uruchamiającemu. Trzymaj się requestFocus().

EDIT2: W Dialogs ( DialogFragment) użyj następującego

getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

zamiast

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
EpicPandaForce
źródło
requestFocusFromTouch()wydaje się wywoływać zdarzenie dotykowe w programie uruchamiającym. To jest dziwne.
EpicPandaForce
0
        field.post(new Runnable() {
            @Override
            public void run() {
                field.requestFocus();
                field.onKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
            }
        });
Intra
źródło
0

W moim przypadku chciałem wyświetlić wirtualną klawiaturę bez odniesienia do konkretnego pola tekstowego, więc skupiłem się na pierwszej części zaakceptowanej odpowiedzi :

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

Następnie pokazuję wirtualną klawiaturę :

InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Zależność
źródło