Bitti eylem düğmeli çok satırlı EditText


114

Bir olması mümkün mü EditTextile widget'ı android:inputType="textMultiLine"seti ve android:imeOptions="actionDone"aynı zamanda?

Klavyedeki işlem düğmesinin Enter (Carriage Return) değil Bitti olmasını içeren çok satırlı bir düzenleme kutusu istiyorum, ancak çalışıyor gibi görünmüyor ..

Şimdiden teşekkürler


Çok satırlı EditText ve birlikte bir Düğme içeren bir bileşik pencere öğesi denemeye ne dersiniz?
Subin Sebastian

Yanıtlar:


195

kullanım

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);

ve XML'de:

android:inputType="textMultiLine"

benim için klavye aşağı indiğinde imleç hala görünüyordu, textField.setCursorVisible(false);içine bironEditorActionListener
Fonix

4.2.2 ve 7.1.1'de çalışır. Teşekkürler.
tehcpu

1
Çok iyi çalışıyor ... Onu bulmakta zorlandım. Bu cevap en iyi cevap olarak işaretlenmelidir
GTHB

7
Bu, hepsini xml'de kurmak yerine neden çalışıyor?
Andrew Steinmetz

1
Bu bilgiyi bulmakta zorlandı. Hala bir cazibe gibi çalışıyor!
Costin

51

Android belgelerinden: ' "textMultiLine" Kullanıcıların satır sonları (satır sonları) içeren uzun metin dizeleri girmesine olanak tanıyan normal metin klavyesi . Bu nedenle, klavyede 'Bitti' düğmesine sahip olmak istiyorsanız textMultiLine özniteliği uygun değildir.

Bitti düğmesiyle çok satırlı (bu durumda 3 satırlı) bir giriş alanı almanın basit bir yolu, EditText'i

android:lines="3" 
android:scrollHorizontally="false" 

Ancak, bazı nedenlerden dolayı, bu yalnızca bu ayarları düzen dosyası (onCreate'de) yerine kodda yaparsam işe yarar.

TextView tv = (TextView)findViewById(R.id.editText);
if (tv != null) {
    tv.setHorizontallyScrolling(false);
    tv.setLines(3);
}

Umarım bu, anlaşılması epey zaman aldığı için birine yardımcı olur. Manifest'ten çalışmasını sağlamanın bir yolunu bulursanız, lütfen bize bildirin.


4
Ayrıca , yüksekliğini değiştirmekten kaçınmak istiyorsanız, maxLines()bunun yerine denemenizi öneririmsetLines()EditText
Daniel Smith

Soruda android: imeOptions'ı actionSend gibi bir değerle ayarlamanız gerektiğinin açıklığa kavuşmadığını düşünüyorum. Bu yanıtı tamamladıktan sonra, setMaxLines bir çeşit kodla bunun üzerine yazsa bile android: singleLine = "true" olarak ayarlamak zorunda kaldım (bunu yapmamak, size örneğin "Gönder" ile bir giriş anahtarı vermez). <Enter> eylemini yakalamak için stackoverflow.com/questions/5014219/… adresinden ilk yanıtı kontrol edin .
DNax

Maalesef <Enter> 'i yakalamak için bulduğum en iyi alternatif @earlcasper cevabı burada stackoverflow.com/questions/1489852/…
DNax

1
Bu benim için mükemmel çalıştı (kullanarak setMaxLines(3)) Çok teşekkürler!
laurencevs

1
Harika çalıştı: XML'inize android: imeOptions = "actionDone" android: inputType = "text" ekleyin ve android: lines = "3" android: scrollHorizontally = "false" XML'den
kaldırın

24

Çalışma Örneği! Bu özelliği destekleyen aşağıdaki özel EditText sınıfını oluşturun ve sınıfı xml dosyasında kullanın. Çalışma kodu:

package com.example;

import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;

public class ActionEditText extends EditText
{
   public ActionEditText(Context context)
   {
       super(context);
   }

   public ActionEditText(Context context, AttributeSet attrs)
   {
       super(context, attrs);
   }

   public ActionEditText(Context context, AttributeSet attrs, int defStyle)
   {
       super(context, attrs, defStyle);
   }

   @Override
   public InputConnection onCreateInputConnection(EditorInfo outAttrs)
   {
       InputConnection conn = super.onCreateInputConnection(outAttrs);
       outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
       return conn;
   }
}

<com.example.ActionEditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:imeOptions="actionDone"
       android:inputType="textAutoCorrect|textCapSentences|textMultiLine" />

Bu benim için çalıştı benim ihtiyacım, çok satırlı olması gereken ve ayrıca yazılım tuşlarında bir sonraki düğmenin olması gereken bir düzenleme metni yapmaktı ... düzenleme metnindeydi 2 satır ekledim android: inputType = "textMultiLine" android: imeOptions = "actionNext" Ve yukarıdaki özel sınıfta yaptım: InputConnection conn = super.onCreateInputConnection (outAttrs); //outAttrs.imeOptions & = ~ EditorInfo.IME_FLAG_NO_ENTER_ACTION; outAttrs.imeOptions & = EditorInfo.IME_ACTION_NEXT; dönüş bağl;
yash

İşler. Andorid 6.0.1'de test edilmiştir.
AmiguelS

9

Bunu Kotlin'de yapmak (ve isteğe bağlı olarak textCapSentencessizin gibi diğer yapılandırmaları da uygulamak için bu uzantı işlevini kullanabilirsiniz:

// To use this, do NOT set inputType on the EditText in the layout
fun EditText.setMultiLineCapSentencesAndDoneAction() {
    imeOptions = EditorInfo.IME_ACTION_DONE
    setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or InputType.TYPE_TEXT_FLAG_MULTI_LINE)
}

Kullanımı:

myEditText.setMultiLineCapSentencesAndDoneAction()

1
Haziran 2019 itibarıyla çalışıyor! Teşekkürler :)
Rohan Taneja

Benim için anahtar setRawInputTypebunun yerine kullanmaktısetInputType
Tamoxin

9

Sanırım bu senin işini yapmanın yolu. Sahip olmak android:inputType="textMultiLine", android:imeOptions="actionDone"anahtar işlevlerini belirsiz hale getirir. Sadece kullanabileceğinizi android:lines="10"ve belki kaldırabileceğinizi unutmayın android:inputType="textMultiLine", ancak neyi başarmak istediğinize bağlı olarak bazen sadece ihtiyacınız android:inputType="textMultiLine"vardır ve bunun yerine geçemez.

EditText ed=new EditText(this);
ed.setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if(keyCode == KeyEvent.KEYCODE_ENTER){
                //do your stuff here
            }
            return false;
        }
});

Android: lines = "10" ile sabit bir maksimum sayı kullanmak benim için çalıştı, klavyede ok düğmesini alıyorum. Örneğin küçük bir maxLength set ile kaç satır olacağını bilirseniz iyi bir numara.
sunadorer

# 66 numaralı keyCode'u devre dışı bırakmak istiyorum mümkün mü? Bunu nasıl yapabilirim?
Adil Malik

1
neden keyCode == 66 yerine keyCode == EditorInfo.IME_ACTION_GO?
tse

5

Bu benim için mükemmel çalışıyor gibi görünüyor

int lineNum = 2;
mEditText.setHorizontallyScrolling(false);
mEditText.setLines(3);

4

Yeniden Kullanılabilir Kotlin Çözümü

Bu değerleri kodda ayarlamak benim için işe yarayan tek şeydi

edittext.inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
edittext.setHorizontallyScrolling(false)
edittext.maxLines = Integer.MAX_VALUE // Or your preferred fixed value

Buna sık sık ihtiyacım var, bu yüzden kodu temiz tutmak için bunu yaptım:

fun EditText.multilineIme(action: Int) {
    imeOptions = action
    inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
    setHorizontallyScrolling(false)
    maxLines = Integer.MAX_VALUE
}

// Then just call
edittext.multilineIme(EditorInfo.IME_ACTION_DONE)

"Bitti" üzerine isteğe bağlı bir özel işlem eklemek istiyorsanız, şunu deneyin:

fun EditText.multilineDone(callback: (() -> Unit)? = null) {
    val action = EditorInfo.IME_ACTION_DONE
    multilineIme(action)
    setOnEditorActionListener { _, actionId, _ ->
            if (action == actionId) {
                callback?.invoke()
                true
            }
            false
        }
    }
}

// Then you can call
edittext.multilineDone { closeKeyboard() }

// or just
edittext.multilineDone()

Geri aramada klavyeyi kolayca kontrol etmeniz mi gerekiyor? Bu yazıyı okuyun

Sonra hideKeyboard()aramayı ekleyinEditText.multilineDone


1
☝️Bu harika bir cevap
Michael

3

Kısa cevap: Hayır, API seviyesi 11'den (3.0) önce bunun mümkün olmadığına inanıyorum.

Aynı sorun burada kırpıldı (kabul edilen cevaba yapılan yorumlarda tartışıldı):

Android Yumuşak klavye eylem düğmesi

Son yorumdan:

Telefonumdaki birkaç uygulamaya baktığımda, çok satırlı kutunun altında görünür bir "Bitti" veya "Gönder" düğmesi ile en sonda olması yaygın görünüyor (örneğin, E-posta uygulaması).


3

Bu durumu aşmanın basit bir yolu:

  • bu öznitelikleri EditText'te tutun:

    android:inputType="textMultiLine" 
    android:scrollHorizontally="false"
  • daha sonra, yalnızca ENTER tuşuna basıldığında klavyeyi gizlemek için bu kodu ekleyin:

    editText.setOnEditorActionListener(new OnEditorActionListener() 
    {
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) 
        {
            editText.setSelection(0);
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);      
            return true;
         } 
         else 
         {
            return false;
         }
         }
    });

2

Ekran klavyesinin görünümü ile ilgili değilse, klavyeye bir giriş dinleyicisi koyabilir ve kullanıcı bir satırsonu girerse "bitti" durumunu ateşleyebilirsiniz.


2

textImeMultiline giriş seçeneğini imeoptions flagnext ve actionnext ile kullanırsanız, cariage return yerine sonraki bir düğme alırsınız


2

Diğer çözümlerin hiçbiri benim için hiç işe yaramasa da, aşağıdakiler güzelce çalıştı ve günler ve günlerce daha fazla google'dan kurtardı, elbette birkaç bükülme ile. Maalesef kodu tam olarak nereden aldığımı hatırlamıyorum ve bu nedenle yazara hak ettiği krediyi veremem.

Java kodunuzda:

////////////Code to Hide SoftKeyboard on Enter (DONE) Press///////////////
editText.setRawInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD|InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeActionLabel("DONE",EditorInfo.IME_ACTION_DONE);              //Set Return Carriage as "DONE"
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);

editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) 
    {
                if (event == null) {
                    if (actionId == EditorInfo.IME_ACTION_DONE) {
                        // Capture soft enters in a singleLine EditText that is the last EditText
                        // This one is useful for the new list case, when there are no existing ListItems
                        editText.clearFocus();
                        InputMethodManager inputMethodManager = (InputMethodManager)  getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
                        inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
                    }

                    else if (actionId == EditorInfo.IME_ACTION_NEXT) {
                        // Capture soft enters in other singleLine EditTexts
                    } else if (actionId == EditorInfo.IME_ACTION_GO) {
                    } else {
                        // Let the system handle all other null KeyEvents
                        return false;
                    }
                } 
        else if (actionId == EditorInfo.IME_NULL) {
                    // Capture most soft enters in multi-line EditTexts and all hard enters;
                    // They supply a zero actionId and a valid keyEvent rather than
                    // a non-zero actionId and a null event like the previous cases.
                    if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        // We capture the event when the key is first pressed.
                    } else {
                        // We consume the event when the key is released.
                        return true;
                    }
                } 
        else {
                    // We let the system handle it when the listener is triggered by something that
                    // wasn't an enter.
                    return false;
                }
                return true;
        }
});




1

4.x'teyim ve setHorizontallyScrolling () (setLine () veya setMaxLines () ile veya olmadan) ve ayrıca Bitti düğmesinin gösterilmesi için birçok farklı XML yapılandırmasını çağırmayı denedim. Hiçbiri işe yaramadı. Sonuç olarak, EditText'iniz çok satırlıysa, Android her zaman "Bitti" düğmesi yerine satır başını göstermek isteyecektir, eğer bu konuda biraz hack yapmadığınız sürece.

Taşıyıcı dönüşünün davranışını yeniden eşlemeyi içermeyen bulduğum en az karmaşık çözüm burada: https://stackoverflow.com/a/12570003/3268329 . Bu çözüm, Android'in çok satırlı görünümler için IME_FLAG_NO_ENTER_ACTION bayrağının ayarını zorlama yönündeki amansız arzusunu geçersiz kılarak Bitti düğmesinin kaybolmasına neden olur.


0

Ben de epeyce mücadele ettim ama sonunda bir çözüm buldum!

Sadece özel bir EditText sınıfı oluşturun:

public class EditTextImeMultiline extends EditText {

    public void init() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                for (int i = s.length(); i > 0; i--)
                    if (s.subSequence(i - 1, i).toString().equals("\n"))
                        s.replace(i - 1, i, "");
            }
        });
        setSingleLine();
        setHorizontallyScrolling(false);
        this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                EditTextImeMultiline.this.setLines(EditTextImeMultiline.this.getLineCount());
            }
        });
    }

    public EditTextImeMultiline(Context context) {
        super(context);
        init();
    }

    public EditTextImeMultiline(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }
}

Bu sınıf lineBreaks'i (\ n) kaldırır, metni textMultiline'ın yapacağı gibi kaydırır VE Enter düğmesini bir ImeAction ile değiştirmenize izin verir;).

Klasik EditText sınıfı yerine XML'inizde çağırmanız yeterlidir.

Buradaki mantığı açıklamak için:

  • Enter yerine bir ImeAction düğmesi gösterebilmek için EditText'i singleLine olarak ayarlayın.
  • Görünümün sonuna ulaşıldığında metnin sonraki satıra gitmesini sağlamak için yatay kaydırmayı kaldırın.
  • OnGlobalLayoutListener ile düzen değişikliklerini izleyin ve "line" parametresini editText tarafından tutulan mevcut metnin "lineCount" değerine ayarlayın. Yüksekliğini tazeleyen şey budur.

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.