EditTextのテキストの最後にカーソルを置きます


883

EditTexton の値を変更していますkeyListener

しかし、テキストを変更すると、カーソルがの先頭に移動しますEditText。カーソルをテキストの最後に置く必要があります。

カーソルをのテキストの最後に移動する方法EditText


3
私は同じ問題に出くわしました。しかし、私がよりよく自問したのは、これがなぜ起こっているのかということです。これにより、自分でキャレットを移動する代わりに問題を解決できました。
kaneda

3
@kaneda完全に同意しますが、実際のソリューションを追加しておけば助かります。
AgentKnopf 2013年

1
@Zainodisそれは単なる考えでした。私が言ったように、私は同じ問題に出くわしました、それは必ずしも私が解決策を見つけたことを意味しません。私の場合、EditTextの項目としてsに問題がありましたListView。実験に関してListViewは、かなり複雑な獣であるソースコード自体にいくつかの変更を加え、エミュレーターでテストしました。これは、コンポーネントによって行われたフォーカス制御管理に関連していました。もちろん、それは私が友人を助けるために私が与えることができる解決策ではありません。:)
kaneda 2013年


これはOnFocusChangedコールバック内では機能しません。そこでの解決策は、setSelectionをランナブル内に置き、メインスレッドで実行することです。ここを確認してください。stackoverflow.com/ a / 32156989/4514796
Ali Nem

回答:


1319

これを試して:

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

15
これは私の場合は機能しません。setSelection()メソッドは効果がないようです。EditTextビューにImageSpansが含まれています。他の種類の回避策はありますか?
toobsco42 2013年

@marqss、私は同じ問題を抱えており、私のために完全に働きました。ダイアログでEditTextを使用し、メイン画面からテキストを事前入力していました。そうなると、カーソルは最初ではなく最後に留まっていましたが、あなたの提案を試した後、すべてが問題なく、私が望んでいた方法でした。これを投稿していただきありがとうございます。
Vincy 2013年

4
@Mullayねえ、私は今、オーバーライドすることで、それを処理しています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(new Runnable({... et.setSel ...システムが完了する前に、作業が取り消されます
MinceMan

1
それはここで機能します、あなたの答えに感謝します。しかし、あなたはこのようにするべきです:editText.setText(s); editText.setSelection(editText.getText()。length()); // setTextの後
smileVann 14年

224

文字列値を現在のedittext値に追加し、カーソルを値の最後に置く、ediitextの追加と呼ばれる関数があります。文字列値を現在のediitext値として持つことができ、append()を呼び出すことができます。

myedittext.append("current_this_edittext_string"); 

1
EditTextに既にテキストがある場合は、次のように入力しますmyedittext.append("");
ymerdrengene

4
@ymerdrengeneを適用myedittext.append("");しただけではうまくいきませんでした!
Chintan Shah、2015

4
私が持っていたコード行を単に置き換えるだけなので、これは完璧です。edittextfield.setTextを使用していて、それを追加用に交換しました。とてもシンプル。
theblitz 2016

それが機能するかどうかは、使用方法によって異なります。私にとってはそうではありませんでした。使用Selectionは、そのIMOを達成するための正しい方法です。
sud007 2017

140

コトリン

カーソルを開始位置に設定します。

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)

コードの下は、2番目の文字の後にカーソルを置くことです。

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

JAVA

カーソルを開始位置に設定します。

 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());

コードの下は、2番目の文字の後にカーソルを置くことです。

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

1
置き換えることができfindViewById(R.id.edittext_id) as EditTextfindViewById<EditText>(R.id.edittext_id)か、単に使用している場合は、鋳造を避けるAPI 26+
Evin1_

97

あなたが呼んだ場合 setTextの前にして、新しいテキストがレイアウト・フェーズ呼び出しを取得していないsetSelection別の実行可能にすることにより発射View.post(Runnable)(から再投稿このトピック)。

したがって、私にとってこのコードは機能します:

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

編集05/16/2019:現在、私はKotlin拡張機能を使用しています:

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

その後-editText.placeCursorToEnd()。


これは本当に私のために働いたおかげで。setSelectionを呼び出そうとしましたが、機能しません。私の場合、テキストを編集するために固定接頭辞を設定しようとしていたため、接頭辞を設定した後、ユーザーが接頭辞の後にデータを入力できるように、カーソルを接頭辞の末尾に設定する必要がありました。私はTextWatcherのコンストラクターでsetSelectionを行っていたので、それが機能しない理由かもしれません。しかし、あなたのソリューションはうまくいきました!
ワンドメーカー

MultiAutoCompleteTextViewのClickablespanメソッドでこのpostメソッドを使用していますが、機能します。テキストスパンの削除アイコンをクリックすると、カーソルが最後に移動します...すべての最新のAndroidモバイルで機能します。 ..しかし、古いバージョンでは、最初のクリックからしばらく時間がかかります...他のすべてのアイテムがクリック可能になりません...手がかりはありますか?
VijayRaj

1
理由はわかりませんが、これが私に有効な唯一の方法です。私の編集テキストにはフォーカス/テキスト変更リスナーがあり、TextInputLayoutでラップされています。それらの1つはそれを台無しにすることです。
Daniel Wilson

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

私の場合、次のkotlin extを作成しました。機能、誰かに役立つかもしれません

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

次に、次のように使用します

mEditText.focus()



10

これはあなたが望むものを達成できると思います。

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

私の観察が正しい場合、これは各ウィジェットのandroid.widget.TextView $ IClipboardDataPasteEventImplのインスタンスを生成します。私はそれらのトンで終わった。どうやらそれらは最終的にクリーンアップされますが、メモリ消費量を増加させるようです。私は1つのダイアログの12のインスタンスを持っていました、それは上記のインスタンスである支配者(それを生き続けるもの)だけです。
AgentKnopf 2013年

そのコードをコード内の適切な位置に配置します(テキストをETextに直接追加します)。ありがとう!
sud007 2017

9

質問は古くて答えられていますが、新しくリリースされたAndroidのDataBindingツールを使用する場合は、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-|はカーソルです)。私のソリューションでは、EditTextでタッチが発生するたびに、常にカーソルを文字列の最後に置きます。

究極のソリューションは次のとおりです。

// 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"/>

@ string / amount = "0.00" @ string / zero_value = "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は、が新しい値を出力し、カーソルが再びテキストの最後にジャンプして、ユーザーが途中でテキストを編集できないために発生しました。

これを解決するために、フラグを使用して1回だけMediatorLiveDataの長さを割り当てStringます。これにより、LiveDataは値を1回だけ読み取ります。つまり、ユーザーがフラグメントに移動したときです。その後、ユーザーはカーソルをテキストを編集したい場所に置くことができます。

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バインディングアダプターを使用してEditTextにバインドします。

XML

テキストの表示とテキスト入力の受け入れに双方向データバインディングを使用します。

<!-- 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ここのクラスは、GoogleのJoseAlcérrecaが作成したSingleLiveEventのようなものです。ここでは、画面の回転を処理するために使用します。シングル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

@Anh Duyの答えに似ていますが、私にはうまくいきませんでした。また、ユーザーが編集テキストをタップしたときにのみカーソルが最後に移動する必要があり、その後もカーソルの位置を選択できるようになりました。これが私のために機能した唯一のコードです

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

上記の答えは私にはうまくいきませんでした。だから私は新しい解決策を見つけました。これは誰かに役立つかもしれません。現在のところ、Android Studioの最新バージョン、つまり3.5を使用しています。おそらくそれが、上記の回答が効果を示さなかった理由かもしれません。

コード:

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

ここで、1番目の引数は、再生するスパンニング可能なテキスト値ですが、2番目の引数はインデックス値です。カーソルをテキストの最後に置きたいので、テキストの長さを返すgetText()。length()を取得しました


1
どういたしまして!ハッピーコーディング!
Prajwal W

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) {

    }
}

このCustomEditTextをXMLファイルで使用してください。これは機能します。私はこれをテストしました、そしてそれは私のために働いています。


1

EditTextビューでテキストの最後にカーソルを置きたい場合

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.