EditText में टेक्स्ट के अंत में कर्सर रखें


883

मैं एक के मान को परिवर्तित कर रहा हूँ EditTextपर keyListener

लेकिन जब मैं पाठ को बदलता हूं तो कर्सर शुरुआत की ओर बढ़ रहा है EditText। मुझे पाठ के अंत में कर्सर की आवश्यकता है।

कैसे एक में पाठ के अंत में कर्सर को स्थानांतरित करने के लिए EditText


3
मैं उसी मुद्दे पर आया था। लेकिन मैंने अपने आप से बेहतर पूछा कि ऐसा क्यों हो रहा है, ताकि मैं खुद इस मामले को सुलझाने के बजाय समस्या को हल कर सकूं।
कनाडे

3
@ कोंकडा मैं पूरी तरह से सहमत हूं, हालांकि अगर आपने वास्तविक समाधान जोड़ा होता तो यह मददगार होता।
AgentKnopf

1
@Zainodis यह सिर्फ एक विचार था। जैसा मैंने कहा कि मैं उसी मुद्दे पर आया हूं, जो जरूरी नहीं है कि मैंने इसका हल ढूंढ लिया है। मेरे मामले में मैं EditTextएक आइटम के रूप में एस के साथ मुद्दा था ListView। प्रयोग के रूप में, मैंने ListViewस्रोत कोड पर ही कुछ बदलाव किए , जो एक जटिल जानवर है, और एमुलेटर पर परीक्षण किया गया है। यह घटक द्वारा किए गए नियंत्रण नियंत्रण प्रबंधन से संबंधित था। तो बेशक यह एक समाधान नहीं है जो मैं अपने दोस्त की मदद करने के लिए दे सकता हूं। :)
कण्डा


यह OnFocusChangedकॉलबैक के अंदर काम नहीं करता है । वहाँ समाधान एक रननीय के अंदर सेटसेलेक्शन डालना है और इसे मुख्य धागे पर चलाना है। यहां देखें stackoverflow.com/a/32156989/4514796
अली नेम

जवाबों:


1317

इसे इस्तेमाल करे:

EditText et = (EditText)findViewById(R.id.inbox);
et.setSelection(et.getText().length());

15
यह मेरे मामले में काम नहीं करता है। सेटस्लेक्शन () विधि का कोई प्रभाव नहीं है। मेरे EditText दृश्य में ImageSpans शामिल हैं। क्या किसी और तरह का वर्कअराउंड है?
तोब्स्को 42

@marqss, मेरे पास एक ही मुद्दा था और मेरे लिए पूरी तरह से काम किया। मैं मुख्य स्क्रीन से डायलॉग और प्री-पॉपुलेटिंग टेक्स्ट पर एडिट टेक्स्ट का उपयोग कर रहा था। जब ऐसा होता है तो कर्सर शुरुआत में रहता था और अंत में नहीं, लेकिन मैंने आपके सुझाव की कोशिश के बाद सब कुछ ठीक है, जिस तरह से मैं चाहता था। इसे पोस्ट करने के लिए आपका धन्यवाद।
विंसी

4
अरे @ मुल्ले, मैं अब इसे onSelectionChanged()एक EditTextक्लास की विधि से आगे बढ़ाते हुए देख रहा हूँ : public void onSelectionChanged(int start, int end) { CharSequence text = getText(); if (text != null) { if (start != text.length() || end != text.length()) { setSelection(text.length(), text.length()); return; } } super.onSelectionChanged(start, end); }
toobsco42

19
कतार में आने के लिए आपको et.post (नया Runnable ({... et.setSel ...) का उपयोग करना पड़ सकता है। इसका कारण यह है कि android कुछ लेआउट सामान को पोस्ट करने से बेहतर समय तक इंतजार करता है, यदि आप सेट करने की कोशिश करते हैं। सिस्टम समाप्त होने से पहले यह आपके काम को पूर्ववत कर देगा।
मिन्समैन

1
यह यहाँ काम करता है, आपके उत्तर के लिए धन्यवाद। लेकिन क्या आपको ऐसा करना चाहिए: editText.setText (s); editText.setSelection (editText.getText () लंबाई ()।); //
सेटटेक्स्ट के

223

Ediitext के लिए append नामक एक फ़ंक्शन है जो स्ट्रिंग को वर्तमान edittext मान पर जोड़ता है और कर्सर को मूल्य के अंत में रखता है। आपके पास मौजूदा एडिटेक्स मान के रूप में स्ट्रिंग वैल्यू हो सकती है और एपेंड () कॉल कर सकते हैं;

myedittext.append("current_this_edittext_string"); 

1
यदि आपके पास पहले से ही अपने EditText में पाठ है, तो बस लिखेंmyedittext.append("");
ymerdrengene

4
@ymerdrengene सिर्फ आवेदन करने से myedittext.append("");मेरे लिए काम नहीं किया!
चिंतन शाह

4
यह सही है क्योंकि यह केवल मेरे पास कोड की पंक्ति को बदल देता है। Edittextfield.setText का उपयोग कर रहा था और बस इसे ऐपेंड के लिए स्वैप कर दिया था। बहुत आसान।
theblitz

उपयोग पर निर्भर करता है कि काम करता है या नहीं। मेरे लिए यह नहीं था। उपयोग करना Selectionउस IMO को प्राप्त करने का सही तरीका है।
सुद ००

139

कोटलिन :

कर्सर को शुरुआती स्थिति पर सेट करें :

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(0)

EditText के अंत में कर्सर सेट करें :

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(editText.text.length)

नीचे दिए गए कोड को दूसरे वर्ण के बाद कर्सर रखना है :

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(2)

जावा :

कर्सर को शुरुआती स्थिति पर सेट करें :

 EditText editText = (EditText)findViewById(R.id.edittext_id);
 editText.setSelection(0);

EditText के अंत में कर्सर सेट करें :

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(editText.getText().length());

नीचे दिए गए कोड को दूसरे वर्ण के बाद कर्सर रखना है :

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(2);

1
का उपयोग कर के findViewById(R.id.edittext_id) as EditTextसाथ बदल सकते हैं findViewById<EditText>(R.id.edittext_id)या सिर्फ कास्टिंग से बच सकते हैंAPI 26+
Evin1_

96

यदि आपको setTextपहले बुलाया गया था और नए पाठ setSelectionमें इस विषय View.post(Runnable)से अलग रिपन द्वारा निकाल दिए गए एक अलग रनवेबल में लेआउट चरण कॉल नहीं मिला था ।

तो, मेरे लिए यह कोड काम करता है:

editText.setText("text");
editText.post(new Runnable() {
         @Override
         public void run() {
             editText.setSelection(editText.getText().length());
         }
});

संपादित करें 05/16/2019: अभी मैं इसके लिए कोटलिन एक्सटेंशन का उपयोग कर रहा हूं:

fun EditText.placeCursorToEnd() {
    this.setSelection(this.text.length)
}

और फिर - editText.placeCursorToEnd ()।


धन्यवाद यह वास्तव में मेरे लिए काम किया। मैं सेट सेलेक्शन बुलाने की कोशिश कर रहा था, लेकिन यह काम नहीं करेगा। मेरे मामले में, मैं पाठ को संपादित करने के लिए एक निश्चित उपसर्ग सेट करने की कोशिश कर रहा था, और इसलिए उपसर्ग सेट करने के बाद, मुझे उपसर्ग के अंत में कर्सर सेट करने की आवश्यकता थी ताकि उपयोगकर्ता उपसर्ग के बाद डेटा दर्ज कर सके। जब से मैं एक TextWatcher के निर्माण में setSelection कर रहा था, यही कारण है कि यह काम नहीं किया जा सकता है। लेकिन आपके समाधान ने बहुत काम किया!
वैंड मेकर

मैं इस पोस्ट मेथड को अपने MultiAutoCompleteTextView के Clickablespan मेथड में इस्तेमाल कर रहा हूं और यह काम करता है ..... मैं चाहता हूं कि टेक्स्ट स्पैन में डिलीट आइकन पर क्लिक करते ही कर्सर अंत में चला जाए ... यह सभी लेटेस्ट एंड्रॉइड मोबाइल में काम करता है। .. लेकिन पुराने संस्करणों में पहले क्लिक के बाद कुछ समय लगता है ... मेरे सभी अन्य आइटम क्लिक करने योग्य नहीं बनते ... कोई सुराग ??
विजयराज

1
मुझे पता नहीं क्यों, लेकिन यह केवल एक ही है जो मेरे लिए काम करता है! मेरे संपादित पाठ में एक फोकस / पाठ परिवर्तित श्रोता है और इसे TextInputLayout में लपेटा गया है। उन चीजों में से एक यह गड़बड़ कर रहा है।
डैनियल विल्सन

42

आप कर्सर को टेक्स्ट के अंत में EditTextइस तरह से देख सकते हैं:

EditText et = (EditText)findViewById(R.id.textview);
int textLength = et.getText().length();
et.setSelection(textLength, textLength);

27
editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        editText.setSelection(editText.getText().length());
        return false;
    }
});

21

यह एक और संभव उपाय है:

et.append("");

यदि यह किसी कारण से काम नहीं करता है, तो बस इस समाधान का प्रयास करें:

et.setSelection(et.getText().length());

12
/**
 * Set cursor to end of text in edittext when user clicks Next on Keyboard.
 */
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean b) {
        if (b) {
            ((EditText) view).setSelection(((EditText) view).getText().length());
        }
    }
};

mEditFirstName.setOnFocusChangeListener(onFocusChangeListener); 
mEditLastName.setOnFocusChangeListener(onFocusChangeListener);

यह मेरे लिए अच्छा काम करता है!


12

मेरे मामले में मैंने निम्नलिखित कोटलिन को बनाया। फ़ंक्शन, किसी के लिए उपयोगी हो सकता है

 private fun EditText.focus(){
        requestFocus()
        setSelection(length())
    }

फिर निम्नानुसार उपयोग करें

mEditText.focus()



10

मुझे लगता है कि यह आप जो चाहते हैं उसे प्राप्त कर सकते हैं।

 Editable etext = mSubjectTextEditor.getText();
 Selection.setSelection(etext, etext.length());

यदि मेरी टिप्पणियां सही हैं, तो यह प्रत्येक विजेट के लिए android.widget.TextView $ IClipboardDataPasteEventImpl का एक उदाहरण देता है। मैं उनमें से टन के साथ समाप्त हो गया। जाहिरा तौर पर वे अंततः साफ हो जाते हैं, लेकिन स्मृति की खपत को बढ़ाते हैं। मेरे पास एक संवाद के 12 उदाहरण हैं, यह केवल उपदेशक है (इसे जीवित रखने वाले व्हाट्सएप) उपरोक्त उदाहरण हैं।
AgentKnopf

कोड में उपयुक्त स्थान पर कोड के उस टुकड़े को रखना (जहाँ आप पाठ को सीधे EText में जोड़ रहे हैं)। धन्यवाद!
सूद

9

प्रश्न पुराना है और इसका उत्तर दिया गया है, लेकिन मुझे लगता है कि यह उत्तर देने के लिए उपयोगी हो सकता है यदि आप एंड्रॉइड के लिए नए जारी किए गए डेटाबाइंडिंग टूल का उपयोग करना चाहते हैं, तो बस इसे अपने XML में सेट करें:

<data>
    <variable name="stringValue" type="String"/>
</data>
...
<EditText
        ...
        android:text="@={stringValue}"
        android:selection="@{stringValue.length()}"
        ...
/>

6

यहां छवि विवरण दर्ज करें

हैलो यह कोशिश करो

 <EditText
       android:id="@+id/edt_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Hello World!"
       android:cursorVisible="true"/>

EditText editText = findViewById(R.id.editText); editText.setSelection(editText.getText().length()); // End pointकर्सर


5

यदि आप सभी पाठ का चयन करना चाहते हैं और पुराने के बजाय केवल नए पाठ में प्रवेश कर रहे हैं, तो आप उपयोग कर सकते हैं

    android:selectAllOnFocus="true"


5

editText.setSelectionयहाँ जादू है। मूल रूप से चयन आपको किसी भी स्थान पर कर्सर रखना चाहता है।

EditText editText = findViewById(R.id.editText);
editText.setSelection(editText.getText().length());

यह EditText के अंत में कर्सर रखता है। मूल रूप editText.getText().length()से आप पाठ लंबाई देता है। फिर आप setSelectionलंबाई के साथ उपयोग करें ।

editText.setSelection(0);

यह प्रारंभ स्थिति (0) पर कर्सर सेट करने के लिए है।


4

मेरे द्वारा परीक्षण किए गए अन्य सभी कोड इस तथ्य के कारण अच्छे काम नहीं कर पाए हैं कि उपयोगकर्ता अभी भी कैरट / कर्सर को स्ट्रिंग के बीच में कहीं भी रख सकता है (उदाहरण: 12 | 3.00 - जहाँ - जहाँ कर्सर है)। मेरा समाधान हमेशा जब भी एडिट टेक्स्ट पर टच होता है, तब स्ट्रिंग को अंत में कर्सर को रखता है।

अंतिम समाधान है:

// For a EditText like:
<EditText
                android:id="@+id/EditTextAmount"
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:hint="@string/amount"
                android:layout_weight="1"
                android:text="@string/zero_value"
                android:inputType="text|numberDecimal"
                android:maxLength="13"/>

@ स्ट्रिंग / राशि = "0.00" @ स्ट्रिंग / शून्य_वायु = "0.00"

// Create a Static boolean flag
private static boolean returnNext; 


// Set caret/cursor to the end on focus change
EditTextAmount.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View editText, boolean hasFocus) {
                if(hasFocus){
                    ((EditText) editText).setSelection(((EditText) editText).getText().length());
                }
            }
        });

// Create a touch listener and put caret to the end (no matter where the user touched in the middle of the string)
EditTextAmount.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View editText, MotionEvent event) {
                ((EditText) editText).onTouchEvent(event);
                ((EditText) editText).setSelection(((EditText) editText).getText().length());
                return true;
            }
        });


// Implement a Currency Mask with addTextChangedListener
EditTextAmount.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String input = s.toString();
                String output = new String();
                String buffer = new String();
                String decimals = new String();
                String numbers = Integer.toString(Integer.parseInt(input.replaceAll("[^0-9]", "")));

                if(returnNext){
                    returnNext = false;
                    return;
                }

                returnNext = true;

                if (numbers.equals("0")){
                    output += "0.00";
                }
                else if (numbers.length() <= 2){
                    output += "0." + String.format("%02d", Integer.parseInt(numbers));
                }
                else if(numbers.length() >= 3){
                    decimals = numbers.substring(numbers.length() - 2);
                    int commaCounter = 0;
                    for(int i=numbers.length()-3; i>=0; i--){
                        if(commaCounter == 3){
                            buffer += ",";
                            commaCounter = 0;
                        }
                        buffer += numbers.charAt(i);
                        commaCounter++;
                    }
                    output = new StringBuilder(buffer).reverse().toString() + "." + decimals;
                }
                EditTextAmount.setText(output);
                EditTextAmount.setSelection(EditTextAmount.getText().length());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                /*String input = s.toString();
                if(input.equals("0.0")){
                    EditTextAmount.setText("0.00");
                    EditTextAmount.setSelection(EditTextAmount.getText().length());
                    return;
                }*/
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

आशा है ये मदद करेगा!


3

ViewModel, LiveData और डेटा बाइंडिंग के लिए

मुझे EditTextअपने नोट्स ऐप में बहुस्तरीय समर्थन के लिए इस कार्यक्षमता की आवश्यकता थी । मुझे पाठ के अंत में कर्सर चाहिए था जब उपयोगकर्ता उस टुकड़े पर नेविगेट करता है जिसमें नोट पाठ होता है।

Djleop द्वारा सुझाया गया समाधान करीब आता है। लेकिन इसके साथ समस्या यह है कि यदि उपयोगकर्ता संपादन के लिए कर्सर को टेक्स्ट के बीच में कहीं रख देता है और टाइप करना शुरू कर देता है, तो कर्सर फिर से टेक्स्ट के अंत में कूद जाएगा। ऐसा इसलिए हुआ क्योंकि LiveDataनए मान का उत्सर्जन होगा और कर्सर पाठ के अंत में फिर से कूद जाएगा जिसके परिणामस्वरूप उपयोगकर्ता पाठ को बीच में कहीं संपादित करने में सक्षम नहीं होगा।

इसे हल करने के लिए, मैं इसका उपयोग करता हूं MediatorLiveDataऔर इसे Stringकेवल एक ध्वज का उपयोग करते हुए लंबाई बताता हूं । यह LiveData को केवल एक बार मान पढ़ने के लिए कारण होगा, जब उपयोगकर्ता टुकड़ा करने के लिए नेविगेट करता है। इसके बाद उपयोगकर्ता कर्सर को कहीं भी रख सकता है जहाँ वे पाठ को संपादित करना चाहते हैं।

ViewModel

private var accessedPosition: Boolean = false

val cursorPosition = MediatorLiveData<Event<Int>>().apply {
    addSource(yourObject) { value ->
        if(!accessedPosition) {
            setValue(Event(yourObject.note.length))
            accessedPosition = true
        }
    }
}

यहां, yourObjectएक और LiveData डेटाबेस से पुनर्प्राप्त किया गया है जो स्ट्रिंग पाठ रखता है जिसे आप प्रदर्शित कर रहे हैं EditText

फिर इसे MediatorLiveDataबाइंडिंग अडैप्टर का उपयोग करके अपने एडिटटेक्स्ट से बांधें ।

एक्सएमएल

पाठ को प्रदर्शित करने के साथ-साथ पाठ इनपुट को स्वीकार करने के लिए दो-तरफ़ा डेटा बाइंडिंग का उपयोग करता है।

<!-- android:text must be placed before cursorPosition otherwise we'll get IndexOutOfBounds exception-->
<EditText
    android:text="@={viewModel.noteText}"
    cursorPosition="@{viewModel.cursorPosition}" />

बाइंडिंग एडॉप्टर

@BindingAdapter("cursorPosition")
fun bindCursorPosition(editText: EditText, event: Event<Int>?) {
    event?.getContentIfNotHandled()?.let { editText.setSelection(it) }
}

Event कक्षा

Eventवर्ग एक की तरह है SingleLiveEvent गूगल से जोस Alcérreca ने लिखा है। मैं इसे स्क्रीन रोटेशन की देखभाल के लिए यहां उपयोग करता हूं। सिंगल का उपयोग करने Eventसे यह सुनिश्चित हो जाएगा कि जब उपयोगकर्ता टेक्स्ट को बीच में कहीं संपादित कर रहा हो और स्क्रीन घूम जाए तो टेक्स्ट टेक्स्ट के अंत में नहीं जाएगा। स्क्रीन के घूमने पर यह उसी स्थिति को बनाए रखेगा।

यहाँ Eventवर्ग है:

open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

यह वह समाधान है जो मेरे लिए काम करता है और अच्छा उपयोगकर्ता अनुभव प्रदान करता है। आशा है कि यह आपकी परियोजनाओं में भी मदद करता है।


इस जवाब को आगे बढ़ाने की जरूरत है। बहुत धन्यवाद
अब्दुल रहमान शमायर

2

@ एएनयू ड्यू के जवाब के समान, लेकिन यह मेरे लिए काम नहीं करता था। मुझे केवल कर्सर को अंत तक स्थानांतरित करने की आवश्यकता थी, जब उपयोगकर्ता संपादन पाठ को टैप करता है और फिर भी कर्सर की स्थिति का चयन करने में सक्षम होता है, यह एकमात्र कोड है जो मेरे लिए काम करता है

boolean textFocus = false; //define somewhere globally in the class

//in onFinishInflate() or somewhere
editText.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        editText.onTouchEvent(event);

        if(!textFocus) {
            editText.setSelection(editText.getText().length());
            textFocus = true;
        }

        return true;
    }
});

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        textFocus = false;
    }
});



2

उपरोक्त उत्तर मेरे लिए काम नहीं किया। तो मुझे एक नया उपाय पता चला। यह शायद किसी के लिए उपयोगी है। मैं वर्तमान तिथि के अनुसार एंड्रॉइड स्टूडियो के नवीनतम संस्करण यानी 3.5 का उपयोग कर रहा हूं। हो सकता है कि यही कारण हो कि उपरोक्त उत्तर में कोई प्रभाव नहीं दिखा।

कोड:

EditText available_seats = findViewById(R.id.available_seats);
Selection.setSelection(available_seats.getText(),available_seats.getText().length());

यहाँ, 1 तर्क स्पैननेबल टेक्स्ट वैल्यू है जिसे आप प्लेविथ करना चाहते हैं जबकि दूसरा तर्क इंडेक्स वैल्यू है। चूंकि, हम पाठ के अंत में कर्सर चाहते हैं, हमने getText () लंबाई () को लिया जो पाठ की लंबाई लौटाता है।


1
मेरा सौभाग्य! हैप्पी कोडिंग!
प्रज्वल डब्ल्यू

1
public class CustomEditText extends EditText {
    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomEditText(Context context) {
        super(context);
    }

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


    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        this.setSelection(this.getText().length());
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {

    }
}

अपने XML फ़ाइल में यह CustomEditText उपयोगकर्ता, यह काम करेगा। मैंने इसका परीक्षण किया है और यह मेरे लिए काम कर रहा है।


1

यदि आप EditText दृश्य में पाठ के अंत में कर्सर रखना चाहते हैं

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.