ImeOptions'ın bitmiş düğme tıklamasını nasıl ele alırım?


185

EditTextKullanıcı EditText tıkladığında klavyede bitmiş düğmesini görüntüleyebilmeniz için aşağıdaki özelliği ayarladığım bir yerde yaşıyorum.

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

Kullanıcı ekran klavyesindeki bitir düğmesini tıklattığında (yazmayı bitirdi) Bir RadioButtondurumu değiştirmek istiyorum .

Ekran klavyesinden vurulduğunda bitmiş düğmeyi nasıl takip edebilirim?

Yazılım klavyesinde sağ alt 'tamamlandı' düğmesini gösteren ekran görüntüsü


1
OnKeyboardActionListener bana herhangi bir kod örneği yardımcı olabilir ??
d-man

Yanıtlar:


210

Ben Roberts ve chirags cevapları bir kombinasyonu ile sona erdi:

((EditText)findViewById(R.id.search_field)).setOnEditorActionListener(
        new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        // Identifier of the action. This will be either the identifier you supplied,
        // or EditorInfo.IME_NULL if being called due to the enter key being pressed.
        if (actionId == EditorInfo.IME_ACTION_SEARCH
                || actionId == EditorInfo.IME_ACTION_DONE
                || event.getAction() == KeyEvent.ACTION_DOWN
                && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
            onSearchAction(v);
            return true;
        }
        // Return true if you have consumed the action, else false.
        return false;
    }
});

Güncelleme: Yukarıdaki kod bazen geri aramayı iki kez etkinleştirir. Bunun yerine, Google sohbet istemcilerinden aldığım aşağıdaki kodu seçtim:

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    // If triggered by an enter key, this is the event; otherwise, this is null.
    if (event != null) {
        // if shift key is down, then we want to insert the '\n' char in the TextView;
        // otherwise, the default action is to send the message.
        if (!event.isShiftPressed()) {
            if (isPreparedForSending()) {
                confirmSendMessageIfNeeded();
            }
            return true;
        }
        return false;
    }

    if (isPreparedForSending()) {
        confirmSendMessageIfNeeded();
    }
    return true;
}

4
Sadece IME_ACTION_DONE aradım ve tetiklemediğine şaşırdım. Ben de ACTION_DOWN ve KEYCODE_ENTER aradıktan sonra nihayet onEditorAction () tetikledi. Yerleşik klavyede hiçbir fark görmediğim için (Enter tuşunun vurgulanmasını bekledim) Edit'in metin düzeni için android: imeOptions = "actionSend" kullanmanın ne anlama geldiğini merak ediyorum.
Birisi

bu cevap neden kabul edilmiyor? bu birkaç durumda başarısız olur mu ??
Archie.bpgc

1
developer.android.com/reference/android/widget/… (Bir 'etkinliğin' ne olduğunu açıklamak aynıdır.)
Darpan

2
İkinci çözelti de iki kez tetiklenir.
Bagusflyer

1
isPreparedForSending()İkinci yöntem nedir ve neden geri döner true?
CoolMind

122

Bunu deneyin, ihtiyacınız olan şey için çalışmalıdır:


editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

10
Bu HTC Evo için çalışmaz. Anlayabildiğim kadarıyla, HTC imeOptions'ı görmezden gelen kendi yumuşak klavyelerini uyguladı.
Dan

Bu yeterlidir (kabul edilen cevapta olduğu gibi olay eylemine veya anahtar koduna bakmaya gerek yoktur); Nexus ve Samsung test cihazlarımda çalışıyor.
Jonik

sadece güvenli olmak için, koddaki ve görünümdeki eylemin eşleştiğinden emin olun <EditText android:imeOptions="actionDone" android:inputType="text"/>
bh_earth0

40
<EditText android:imeOptions="actionDone"
          android:inputType="text"/>

Java kodu:

edittext.setOnEditorActionListener(new OnEditorActionListener() { 
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            Log.i(TAG,"Here you can write the code");
            return true;
        }    
        return false;
    }
});

Eğer ele aldığınızı söylemek için if fıkrasında true ifadesini döndürmelisiniz
Tim Kist

26

Bu sorunun eski olduğunu biliyorum, ama benim için neyin işe yaradığına dikkat çekmek istiyorum.

Android Geliştiricileri web sitesinden (aşağıda gösterilen) örnek kodu kullanmayı denedim , ancak işe yaramadı. Bu yüzden EditorInfo sınıfını kontrol ettim ve IME_ACTION_SEND tamsayı değerinin olarak belirtildiğini fark ettim 0x00000004.

Android Geliştiricilerinden örnek kod:

editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextEmail
        .setOnEditorActionListener(new OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId,
                    KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    /* handle action here */
                    handled = true;
                }
                return handled;
            }
        });

Böylece, tam sayı değerini dosyama ekledim res/values/integers.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="send">0x00000004</integer>
</resources>

Sonra, düzen dosyamı res/layouts/activity_home.xmlaşağıdaki gibi düzenledim

<EditText android:id="@+id/editTextEmail"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:imeActionId="@integer/send"
  android:imeActionLabel="@+string/send_label"
  android:imeOptions="actionSend"
  android:inputType="textEmailAddress"/>

Ve sonra örnek kod çalıştı.


17

OnKeyListener'ı ayarlama ve Bitti düğmesini dinletme hakkında daha fazla ayrıntı.

Önce sınıfınızın aletler bölümüne OnKeyListener ekleyin. Sonra OnKeyListener arabiriminde tanımlanan işlevi ekleyin:

/*
 * Respond to soft keyboard events, look for the DONE press on the password field.
 */
public boolean onKey(View v, int keyCode, KeyEvent event)
{
    if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
        (keyCode == KeyEvent.KEYCODE_ENTER))
    {
        // Done pressed!  Do something here.
    }
    // Returning false allows other listeners to react to the press.
    return false;
}

Bir EditText nesnesi verildi:

EditText textField = (EditText)findViewById(R.id.MyEditText);
textField.setOnKeyListener(this);

2
Bu, API seviyesi 17+'yi hedefleyen uygulamalarda artık çalışmaz, çünkü OnKeyListener'ınız artık yazılımla ilgili etkinlikler için tetiklenmiyor: developer.android.com/reference/android/text/method/…
jjb

Şimdi bir alternatif öneriyorlar mı?
Robert Hawkey

2
İyi çalışıyor gibi görünen EditorInfo.IME_ACTION_DONE aramak için setOnEditorActionListener kullanarak geçtim.
jjb

onKey doğru değil, yanlış döndürmelidir.
ralphgabb

16

Çoğu insan soruyu doğrudan cevaplasa da, arkasındaki kavram hakkında daha fazla ayrıntı vermek istedim. İlk olarak, varsayılan bir Giriş Etkinliği oluşturduğumda IME'nin dikkatine çekildim. Aşağıdakileri içeren benim için bir kod üretti:

<EditText
  android:id="@+id/password"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/prompt_password"
  android:imeActionId="@+id/login"
  android:imeActionLabel="@string/action_sign_in_short"
  android:imeOptions="actionUnspecified"
  android:inputType="textPassword"
  android:maxLines="1"
  android:singleLine="true"/>

İnputType özniteliğine zaten aşina olmalısınız. Bu, Android'e e-posta adresi, şifre veya telefon numarası gibi beklenen metin türünü bildirir. Olası değerlerin tam listesi burada bulunabilir .

Ancak, imeOptions="actionUnspecified"amacını anlamadığım özellikti . Android, kullanılarak metin seçildiğinde ekranın alt kısmından açılan klavyeyle etkileşime girmenizi sağlar InputMethodManager. Klavyenin alt köşesinde, geçerli metin alanına bağlı olarak genellikle "İleri" veya "Bitti" yazan bir düğme bulunur. Android bunu kullanarak özelleştirmenizi sağlar android:imeOptions. Bir "Gönder" düğmesi veya "İleri" düğmesi belirleyebilirsiniz. Tam liste burada bulunabilir .

Bununla TextView.OnEditorActionListener, EditTexteleman için bir tanımlayarak eylem düğmesine basmayı dinleyebilirsiniz . Örneğinizde olduğu gibi:

editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
       //do here your stuff f
       return true;
    }
    return false;
    } 
});

Şimdi benim örneğimde android:imeOptions="actionUnspecified"sıfat vardı . Bu, enter tuşuna bastığında kullanıcı oturum açmayı denemek istediğinizde kullanışlıdır. Etkinliğinizde bu etiketi tespit edebilir ve ardından giriş yapmayı deneyebilirsiniz:

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

6

Kotlin'deki chikka.anddev ve Alex Cohn sayesinde :

text.setOnEditorActionListener { v, actionId, event ->
    if (actionId == EditorInfo.IME_ACTION_DONE ||
        event?.action == KeyEvent.ACTION_DOWN && event.keyCode == KeyEvent.KEYCODE_ENTER) {
        doSomething()
        true
    } else {
        false
    }
}

Burada Enteranahtarı kontrol ediyorum , çünkü bunun EditorInfo.IME_NULLyerine geri dönüyor IME_ACTION_DONE.

Ayrıca bkz. Android imeOptions = "actionDone" çalışmıyor . Ekle android:singleLine="true"içinde EditText.


6

Kotlin Çözümü

Kotlin'de baş etmenin temel yolu:

edittext.setOnEditorActionListener { _, actionId, _ ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        callback.invoke()
        true
    }
    false
}

Kotlin Uzantısı

Bunu sadece edittext.onDone{/*action*/}ana kodunuzu aramak için kullanın . Kodunuzu çok daha okunaklı ve bakım yapılabilir hale getirir

fun EditText.onDone(callback: () -> Unit) {
    setOnEditorActionListener { _, actionId, _ ->
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            callback.invoke()
            true
        }
        false
    }
}

Bu seçenekleri düzenleme metninize eklemeyi unutmayın

<EditText ...
    android:imeOptions="actionDone"
    android:inputType="text"/>

inputType="textMultiLine"Desteğe ihtiyacınız varsa bu yayını okuyun


1
Harika cevap, paylaştığın için teşekkürler! setOnEditorActionListenerGerçi dönüş değeri ile ilgili bir tüysüz uyarı almaya devam gibi görünüyor . Belki de sadece yerel yapılandırma ayarları meselesidir, ancak linter'ım gerçekten, dinleyicinin bir dönüş ifadesi olarak ( -block yerine) "true" ifadesini kabul etmem için gerçekten bir elseşube eklememi istiyor if.
dbm

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.