เหตุการณ์สำคัญของ Android EditText ลบ (backspace)


123

ฉันจะตรวจจับเหตุการณ์สำคัญลบ (backspace) สำหรับ editText ได้อย่างไร ฉันได้ลองใช้ TextWatcher แล้ว แต่เมื่อ editText ว่างเปล่าเมื่อฉันกดปุ่มลบไม่มีอะไรเกิดขึ้น ฉันต้องการตรวจจับปุ่มลบกดศัตรูแก้ไขข้อความแม้ว่าจะไม่มีข้อความก็ตาม

คำตอบ:


174

หมายเหตุ: ใช้onKeyListenerไม่ได้กับคีย์บอร์ดแบบนิ่ม

คุณสามารถตั้งค่าOnKeyListenerสำหรับคุณeditTextเพื่อให้คุณสามารถตรวจสอบใด ๆ กดปุ่ม
แก้ไข: ข้อผิดพลาดทั่วไปที่เรากำลังตรวจสอบKeyEvent.KEYCODE_BACKสำหรับbackspaceแต่จริงๆมันเป็นKeyEvent.KEYCODE_DEL(จริงเหรอว่าชื่อจะทำให้เกิดความสับสนมาก!)

editText.setOnKeyListener(new OnKeyListener() {                 
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        //You can identify which key pressed buy checking keyCode value with KeyEvent.KEYCODE_
        if(keyCode == KeyEvent.KEYCODE_DEL) {  
            //this is for backspace
        }
        return false;       
    }
});

9
ฉันเพิ่งลองใช้ แต่ดูเหมือนว่า onKeyListeners ไม่ได้ลงทะเบียน backspaces
stefs

3
จะใช้ไม่ได้กับคีย์บอร์ดแบบนิ่ม สิ่งนี้จะใช้ได้กับอินพุตฮาร์ดแวร์เท่านั้น
Varundroid

6
เมื่อวันที่ฉัน (หุ้นวิ่ง KitKat) Nexus4 นี้ไม่ทำงานสำหรับแป้นพิมพ์ซอฟต์แวร์
Matthias

10
ดังนั้นถ้ามันใช้ไม่ได้กับปุ่มซอฟต์คีย์ทำไมคำตอบนี้จึงถูกยอมรับใน / ภายใต้แพลตฟอร์ม Android ..
DJphy

33
ใช้event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_DELถ้าคุณไม่ต้องการให้เหตุการณ์ยิงสองครั้งต่อการกด backspace
Fonix

83

เป็นเวลานานแล้วที่คุณถาม แต่ฉันเพิ่งมีปัญหาเดียวกัน ดังที่ได้กล่าวไปแล้วโดย Estel ปัญหาเกี่ยวกับผู้ฟังหลักคือใช้งานได้กับแป้นพิมพ์ฮาร์ดแวร์เท่านั้น หากต้องการทำสิ่งนี้ด้วยIME (แป้นพิมพ์แบบอ่อน)วิธีแก้ปัญหานั้นซับซ้อนกว่าเล็กน้อย

วิธีเดียวที่เราต้องการจริงแทนที่เป็นsendKeyEventในEditText's InputConnectionระดับ วิธีนี้เรียกว่าเมื่อเหตุการณ์สำคัญเกิดขึ้นใน IME แต่เพื่อที่จะลบล้างสิ่งนี้เราจำเป็นต้องใช้แบบกำหนดเองEditTextซึ่งจะแทนที่onCreateInputConnectionเมธอดโดยการตัดInputConnectionอ็อบเจ็กต์เริ่มต้นในคลาสพร็อกซี! : |

ฟังดูซับซ้อน แต่นี่เป็นตัวอย่างที่ง่ายที่สุดที่ฉันสามารถทำได้:

public class ZanyEditText extends EditText {

    private Random r = new Random();

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

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

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

    public void setRandomBackgroundColor() {
        setBackgroundColor(Color.rgb(r.nextInt(256), r.nextInt(256), r
                .nextInt(256)));
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new ZanyInputConnection(super.onCreateInputConnection(outAttrs),
                true);
    }

    private class ZanyInputConnection extends InputConnectionWrapper {

        public ZanyInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN
                    && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                ZanyEditText.this.setRandomBackgroundColor();
                // Un-comment if you wish to cancel the backspace:
                // return false;
            }
            return super.sendKeyEvent(event);
        }

    }

}

บรรทัดที่มีการเรียกไปที่setRandomBackgroundColorคือที่ที่การกระทำ backspace พิเศษของฉันเกิดขึ้น ในกรณีนี้ให้เปลี่ยนEditTextสีพื้นหลัง

หากคุณกำลังขยายสิ่งนี้จาก XML อย่าลืมใช้ชื่อแพ็กเกจแบบเต็มเป็นแท็ก:

<cc.buttfu.test.ZanyEditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/somefield"
></cc.buttfu.test.ZanyEditText>

27
ฉันเพิ่งพบปัญหาเดียวกันใน Jelly Bean ฉันพบว่าโซลูชันนี้ใช้งานได้เป็นส่วนใหญ่ยกเว้นว่าฉันต้องแทนที่ deleteSurroundingText (... ) แทน sendKeyEvent (... ) (ซึ่งไม่ได้ถูกเรียกเลย) หวังว่านี่จะช่วยคนอื่นได้!
Brandon

คำตอบนี้รวมกับความคิดเห็นของ @Brandon ด้านบนทำให้ฉันได้ผล สิ่งที่ฉันสงสัยตอนนี้คือวิธีการทำงานบนอุปกรณ์ก่อน JellyBean
Christopher Perry

มันใช้งานได้กับคำตอบที่ยอมรับบนอุปกรณ์ 2.2 และ 2.3 สำหรับฉัน
Christoph

ดูเหมือนว่าจะเริ่มต้นเหตุการณ์สำคัญสำหรับ backspace สองครั้งในวันที่ 2.3 ... : /
เจฟฟ์

25
สิ่งนี้ใช้ไม่ได้เมื่อ edittext ว่างเปล่ามีแนวคิดเกี่ยวกับวิธีรับเหตุการณ์สำหรับคีย์ลบเมื่อ edittext ว่างเปล่าและไม่มีข้อความ? 4.2
Rickster

69

นี่เป็นเพียงส่วนเสริมของคำตอบของ Idris โดยเพิ่มในการแทนที่เพื่อ deleteSurroundingText ด้วย ฉันพบข้อมูลเพิ่มเติมที่นี่: Android: Backspace ใน WebView / BaseInputConnection

package com.elavon.virtualmerchantmobile.utils;

import java.util.Random;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
import android.widget.EditText;

public class ZanyEditText extends EditText {

    private Random r = new Random();

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

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

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

    public void setRandomBackgroundColor() {
        setBackgroundColor(Color.rgb(r.nextInt(256), r.nextInt(256), r
                .nextInt(256)));
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new ZanyInputConnection(super.onCreateInputConnection(outAttrs),
                true);
    }

    private class ZanyInputConnection extends InputConnectionWrapper {

        public ZanyInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN
                    && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                ZanyEditText.this.setRandomBackgroundColor();
                // Un-comment if you wish to cancel the backspace:
                // return false;
            }
            return super.sendKeyEvent(event);
        }


        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
            // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
            if (beforeLength == 1 && afterLength == 0) {
                // backspace
                return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                    && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
            }

            return super.deleteSurroundingText(beforeLength, afterLength);
        }

    }

}

3
ขอบคุณ! deleteSurroundingTextบิตได้รับสิ่งที่ฉันต้องการหลังจากที่พยายามแก้ปัญหาอื่น ๆ นับไม่ถ้วน
Adam Rosenfield

5
โซลูชันนี้ใช้งานได้ดีสำหรับฉันใน Android เวอร์ชันก่อนหน้า แต่น่าเสียดายที่ DeleteSurroundingText จะถูกเรียกเมื่อลบช่องว่างบน 4.4 (KitKat) เท่านั้น ฉันได้ทดสอบทั้ง Nexus4 และ 7
คณบดี

1
ดูเหมือนว่าต้องใช้ deleteSurroundingText เมื่อ EditText เป็นแบบหลายบรรทัด แปลก
Alex Sorokoletov

7
ขอบคุณคนตันไม่ได้ผลกับการลบ deleteSurroundText Android เป็นแบบสุ่มมากจนควรเปลี่ยนชื่อเป็น androm
Torsten Ojaperv

2
มันใช้ได้สำหรับฉัน แต่ฉันไม่สามารถลบเครื่องหมายวรรคตอนหรือช่องว่างได้อีกต่อไป!
jaytj95

29

นี่คือวิธีง่ายๆของฉันซึ่งใช้ได้กับ API ทั้งหมด:

private int previousLength;
private boolean backSpace;

// ...

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    previousLength = s.length();
}

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

@Override
public void afterTextChanged(Editable s) {
    backSpace = previousLength > s.length();

    if (backSpace) {

        // do your stuff ...

    } 
}

อัพเดท 17.04.18 .
ตามที่ระบุไว้ในความคิดเห็นโซลูชันนี้จะไม่ติดตามการกด backspace หาก EditText ว่างเปล่า (เช่นเดียวกับโซลูชันอื่น ๆ ส่วนใหญ่)
อย่างไรก็ตามก็เพียงพอสำหรับกรณีการใช้งานส่วนใหญ่
ปล. ถ้าวันนี้ต้องสร้างสิ่งที่คล้ายกันฉันจะทำ:

public abstract class TextWatcherExtended implements TextWatcher {

    private int lastLength;

    public abstract void afterTextChanged(Editable s, boolean backSpace);

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        lastLength = s.length();
    }

    @Override
    public void afterTextChanged(Editable s) {
        afterTextChanged(s, lastLength > s.length());
    }  
}

จากนั้นใช้เป็น TextWatcher ปกติ:

 editText.addTextChangedListener(new TextWatcherExtended() {
        @Override
        public void afterTextChanged(Editable s, boolean backSpace) {
           // Here you are! You got missing "backSpace" flag
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Do something useful if you wish.
            // Or override it in TextWatcherExtended class if want to avoid it here 
        }
    });

สิ่งที่ฉันต้องการ! ขอบคุณ!
DH28

9
TextWatcher ไม่ทริกเกอร์บน EditText ที่ว่างเปล่า
Dan Neacșu

@Leo Droidcoder ฉันใช้ในโซลูชันที่คล้ายกัน ชัดเจนกระชับและทำงานได้อย่างสมบูรณ์ ... ไชโย
AJW

อัลกอริทึมนี้มีข้อบกพร่องราวกับว่าคุณคลิกเว้นวรรคหลังจากพิมพ์แล้วความยาวก่อนหน้านี้มากกว่าความยาว s
Marcin S.

2
ใช้งานได้ตราบเท่าที่คุณไม่ใช้การเลือก (การเติมข้อความอัตโนมัติ)
Javatar

13

ฉันส่ง 2 วันเพื่อค้นหาวิธีแก้ปัญหาและฉันพบวิธีที่ใช้งานได้ :) (บนซอฟต์คีย์)

public TextWatcher textWatcher = 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) {
        if (count == 0) {
        //Put your code here.
        //Runs when delete/backspace pressed on soft key (tested on htc m8)
        //You can use EditText.getText().length() to make if statements here
        }
    }

@Override
    public void afterTextChanged(Editable s) {
    }
}

หลังจากเพิ่ม textwatcher ใน EditText ของคุณ:

yourEditText.addTextChangedListener(textWatcher);

ฉันหวังว่ามันจะใช้งานได้กับอุปกรณ์ Android อื่น ๆ เช่นกัน (samsung, LG ฯลฯ )


ความปรารถนาของอุปกรณ์ HTC (HTC เป็นเรื่องธรรมดาแม้ว่า :-P)
Junaid

ถ้าพิมพ์เป็นช่องว่างก็ให้นับ == 0
Bincy Baby

Brilliant no 1 answer ครับ :)
Gundu Bandgar

6
นั่นไม่ได้ผลอย่างสมบูรณ์ count == 0 จะเป็นก็ต่อเมื่อ edittext ว่างเปล่า!
Leo Droidcoder

@MarcAlexander ฉันไม่แน่ใจเกี่ยวกับคำตอบนี้ แต่คุณสามารถตรวจสอบวิธีแก้ปัญหาของฉันได้ในคำตอบด้านบน
Leo Droidcoder

6

วิธีง่ายๆของฉันที่ทำงานได้อย่างสมบูรณ์ คุณควรเพิ่มธง ข้อมูลโค้ดของฉัน:

editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            if (after < count) {
                isBackspaceClicked = true;
            } else {
                isBackspaceClicked = false;
            }
        }

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

        @Override
        public void afterTextChanged(Editable s) {
            if (!isBackspaceClicked) {
                // Your current code
            } else {
                // Your "backspace" handling
            }
        }

textChangeListner ไม่เคยเรียกใช้ emptTextview
Janardhan R

3

ตัวอย่างการสร้าง EditText ด้วย TextWatcher

EditText someEdit=new EditText(this);
//create TextWatcher for our EditText
TextWatcher1 TW1 = new TextWatcher1(someEdit);
//apply our TextWatcher to EditText
        someEdit.addTextChangedListener(TW1);

TextWatcher ที่กำหนดเอง

public class TextWatcher1 implements TextWatcher {
        public EditText editText;
//constructor
        public TextWatcher1(EditText et){
            super();
            editText = et;
//Code for monitoring keystrokes
            editText.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if(keyCode == KeyEvent.KEYCODE_DEL){
                        editText.setText("");
                    }
                        return false;
                }
            });
        }
//Some manipulation with text
        public void afterTextChanged(Editable s) {
            if(editText.getText().length() == 12){
                editText.setText(editText.getText().delete(editText.getText().length() - 1, editText.getText().length()));
                editText.setSelection(editText.getText().toString().length());
            }
            if (editText.getText().length()==2||editText.getText().length()==5||editText.getText().length()==8){
                editText.setText(editText.getText()+"/");
                editText.setSelection(editText.getText().toString().length());
            }
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }
        public void onTextChanged(CharSequence s, int start, int before, int count) {



        }
    }

1

สำหรับบางคนที่ใช้ Kotlin

addOnTextChanged ไม่มีความยืดหยุ่นเพียงพอที่จะจัดการกับบางกรณี (เช่นตรวจสอบว่าผู้ใช้กดลบเมื่อแก้ไขข้อความว่างเปล่า)

setOnkeyListenerทำงานได้แม้กระทั่งแป้นพิมพ์ที่อ่อนนุ่มหรือแป้นพิมพ์ยาก! แต่เพียงบนอุปกรณ์บางอย่าง ในกรณีของฉันมันใช้งานได้กับ Samsung s8 แต่ใช้กับ Xiaomi mi8 se ไม่ได้

หากคุณใช้ kotlin คุณสามารถใช้ฟังก์ชัน crossline doOnTextChangedได้เช่นเดียวกับaddOnTextChangedแต่การเรียกกลับจะถูกทริกเกอร์แม้ข้อความแก้ไขจะว่างเปล่า

หมายเหตุ: doOnTextChanged เป็นส่วนหนึ่งของไลบรารี Android KTX


2
คุณอาจอาจระบุได้ว่าdoOnTextChanged ฟังก์ชั่นการขยายสามารถเข้าถึงได้ในห้องสมุด Android KTX
หิน

2
แต่ดูเหมือนว่าการโทรกลับจะไม่ "ทริกเกอร์แม้ข้อความแก้ไขจะว่างเปล่า" คุณช่วยระบุตัวอย่างที่มีการสกัดกั้นการลบ (backspace) ให้ว่างได้EditTextไหม ขอบคุณล่วงหน้า
stone

1
อาฉันได้ทดสอบแล้วเมื่อฉันพัฒนาโครงการ ในกรณีของฉันคือใน xiaomi mi8se เมื่อแก้ไขข้อความว่างเปล่าและคุณกดลบไม่มีการโทรกลับ ฉันจะค้นหาตัวอย่างประโยคนี้
Huynh

0

มีคำถามที่คล้ายกันใน Stackoverflow คุณต้องลบล้างEditTextเพื่อเข้าถึงInputConnectionวัตถุที่มีdeleteSurroundingTextเมธอด จะช่วยให้คุณตรวจจับเหตุการณ์การลบ (backspace) โปรดดูวิธีแก้ปัญหาที่ฉันให้ไว้ที่Android - ไม่สามารถจับภาพ backspace / ลบกดแบบซอฟต์ แป้นพิมพ์


0

ดูเหมือนว่าจะได้ผลสำหรับฉัน:

public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (before - count == 1) {
        onBackSpace();
    } else if (s.subSequence(start, start + count).toString().equals("\n")) {
        onNewLine();
    }
}

0

ฉันยังประสบปัญหาเดียวกันใน Dialog .. เพราะฉันใช้ setOnKeyListener .. แต่ฉันตั้งค่าผลตอบแทนเริ่มต้นเป็นจริง หลังจากการเปลี่ยนแปลงเช่นโค้ดด้านล่างมันใช้งานได้ดีสำหรับฉัน ..

    mDialog.setOnKeyListener(new Dialog.OnKeyListener() {

        @Override
        public boolean onKey(DialogInterface arg0, int keyCode,
                             KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                mDialog.dismiss();
                return true;
            }
            return false;//this line is important 

        }
    });

0

ขึ้นอยู่กับ @Jiff ZanyEditTextนี่คือWiseEditTextด้วยsetSoftKeyListener(OnKeyListener)

package com.locopixel.seagame.ui.custom;

import java.util.Random;

import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;

public class WiseEditText extends AppCompatEditText {

    private Random r = new Random();
    private OnKeyListener keyListener;

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

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

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

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new MyInputConnection(super.onCreateInputConnection(outAttrs),
                true);
    }

    private class MyInputConnection extends InputConnectionWrapper {

        public MyInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            if (keyListener != null) {
                keyListener.onKey(WiseEditText.this,event.getKeyCode(),event);
            }
            return super.sendKeyEvent(event);
        }

        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {       
            // magic: in latest Android, deleteSurroundingText(1, 0) will be called for backspace
            if (beforeLength == 1 && afterLength == 0) {
                // backspace
                return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
                    && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
            }

            return super.deleteSurroundingText(beforeLength, afterLength);
        }

    }

    public void setSoftKeyListener(OnKeyListener listener){
        keyListener = listener;
    }

}

จะถูกเรียกสองครั้งสำหรับเหตุการณ์สำคัญในการลบแต่ละครั้ง
Pankaj Kumar

0

ปัญหาของฉันเป็นที่ฉันมีกำหนดเองTextwatcherดังนั้นฉันไม่ต้องการที่จะเพิ่มOnKeyListenerไปยังเช่นเดียวกับฉันไม่ได้ต้องการที่จะสร้างที่กำหนดเองEditText EditTextฉันต้องการตรวจสอบว่ามีการกด Backspace หรือไม่ในafterTextChangedวิธีของฉันดังนั้นฉันจึงไม่ควรเรียกเหตุการณ์ของฉัน

นี่คือวิธีที่ฉันแก้ไขปัญหานี้ หวังว่าคงจะเป็นประโยชน์สำหรับใครบางคน

public class CustomTextWatcher extends AfterTextChangedTextWatcher {

private boolean backspacePressed;

@Override
public void afterTextChanged(Editable s) {
    if (!backspacePressed) {
        triggerYourEvent();
    }
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    super.onTextChanged(s, start, before, count);
    backspacePressed = count == 0; //if count == 0, backspace is pressed
}
}

0

ฉันได้ทดสอบโซลูชันของ @ Jeff ในเวอร์ชัน 4.2, 4.4, 6.0 แล้ว บน 4.2 และ 6.0 ทำงานได้ดี แต่ใน 4.4 มันไม่ทำงาน

ฉันพบวิธีง่ายๆในการแก้ไขปัญหานี้ ประเด็นสำคัญคือการแทรกอักขระที่มองไม่เห็นลงในเนื้อหาของ EditText ตั้งแต่เริ่มต้นและอย่าให้ผู้ใช้เลื่อนเคอร์เซอร์ก่อนอักขระนี้ วิธีของฉันคือการแทรกอักขระเว้นวรรคสีขาวที่มี ImageSpan ของ Zero Width นี่คือรหัสของฉัน

                @Override
                public void afterTextChanged(Editable s) {
                    String ss = s.toString();
                    if (!ss.startsWith(" ")) {
                        int selection = holder.editText.getSelectionEnd();
                        s.insert(0, " ");
                        ss = s.toString();
                        holder.editText.setSelection(selection + 1);
                    }
                    if (ss.startsWith(" ")) {
                        ImageSpan[] spans = s.getSpans(0, 1, ImageSpan.class);
                        if (spans == null || spans.length == 0) {
                            s.setSpan(new ImageSpan(getResources().getDrawable(R.drawable.zero_wdith_drawable)), 0 , 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                    }
                }

และเราต้องการ EditText แบบกำหนดเองซึ่งมี SelectionChangeListener

public class EditTextSelectable extends android.support.v7.widget.AppCompatEditText {
public interface OnSelectChangeListener {
    void onSelectChange(int start, int end);
}

private OnSelectChangeListener mListener;

public void setListener(OnSelectChangeListener listener) {
    mListener = listener;
}

...constructors...

@Override
protected void onSelectionChanged(int selStart, int selEnd) {
    if (mListener != null) {
        mListener.onSelectChange(selStart, selEnd);
    }
    super.onSelectionChanged(selStart, selEnd);
}

}

และขั้นตอนสุดท้าย

holder.editText.setListener(new EditTextSelectable.OnSelectChangeListener() {
                @Override
                public void onSelectChange(int start, int end) {
                    if (start == 0 && holder.editText.getText().length() != 0) {
                        holder.editText.setSelection(1, Math.max(1, end));
                    }
                }
            });

และตอนนี้เราทำเสร็จแล้ว ~ เราสามารถตรวจจับเหตุการณ์สำคัญของ backspace ได้เมื่อ EditText ไม่มีเนื้อหาจริงและผู้ใช้จะไม่รู้อะไรเลยเกี่ยวกับกลอุบายของเรา


0

คำถามนี้อาจจะเก่า แต่คำตอบนั้นง่ายมากเมื่อใช้ TextWatcher

int lastSize=0;
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    //2. compare the old length of the text with the new one
    //3. if the length is shorter, then backspace was clicked
    if (lastSize > charSequence.length()) {
        //4. Backspace was clicked
        //5. perform action
    }
    //1. get the current length of of the text
    lastSize = charSequence.length();
}

เช่นเดียวกับโซลูชันก่อนหน้านี้สามารถเรียกใช้โดยการเติมข้อความอัตโนมัติ / คำแนะนำ
Stonz2

0

ฉันพบวิธีง่ายๆที่ใช้ได้กับคีย์บอร์ดนุ่ม ๆ

override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {
    text?.let { 
        if(count < before) {
            Toast.makeText(context, "backspace pressed", Toast.LENGTH_SHORT).show()
            // implement your own code
        }
    }
}

-3

คุณสามารถตั้งค่าตัวรับฟังคีย์สำหรับกิจกรรมและในวิธีการโทรกลับคุณสามารถตรวจจับได้ว่าผู้ใช้กดปุ่มใด โค้ดด้านล่างนี้ใช้สำหรับการอ้างอิงของคุณ หวังว่าจะช่วยได้

//after user hits keys, this method would be called.
public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (editText.isFocused()) {
            switch (keyCode) {
            case KeyEvent.KEYCODE_DEL:  //delete key
                Log.i("INFO", "delete key hit"); //you should see this log in ddms after you hit delete key
                break;
            }
        }
        return super.onKeyUp(keyCode, event);
    }

ตรวจสอบโซลูชันนี้แล้ว - KEYCODE_DEL จะถูกส่งไปที่กิจกรรมก็ต่อเมื่อข้อความแก้ไขจะไม่สามารถจัดการได้ด้วยตัวเอง ตัวอย่างเช่นเมื่อไม่มีข้อความใน editText หรือมีข้อความบางส่วน แต่เคอร์เซอร์อยู่ที่จุดเริ่มต้น เป็นเรื่องตลกที่ในกรณีของฉันฉันต้องการพฤติกรรมแบบนั้น
Anton Kizema

ในกิจกรรมของฉันไม่มี EditText และฉันแค่ทำให้แป้นพิมพ์ปรากฏโดยใช้โปรแกรม ฉันต้องจับแป้นคีย์บอร์ดทุกปุ่มและดูเหมือนว่าจะเป็นวิธีแก้ปัญหาที่ใช้งานได้เท่านั้น อีกอันกำลังแทนที่เมธอด dispatchKeyEvent น่าเสียดายที่เริ่มต้นจาก JellyBean IME ไม่ได้ส่ง KeyEvent สำหรับคีย์ DELETE developer.android.com/reference/android/view/KeyEvent.html
Bemipefe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.