Android의 EditText onClickListener


86

눌렀을 때 DatePicker를 만드는 EditText를 원합니다. 그래서 다음 코드를 작성합니다.

    mEditInit = (EditText) findViewById(R.id.date_init);
    mEditInit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showDialog(DATEINIT_DIALOG);
        }

    });

그러나 EditText를 누르면 일반적인 동작입니다. 텍스트 입력을 기다리는 커서가 원하는 대화 상자를 대신 표시합니다.


EditText 대화 상자 대신 스피너를 사용해야합니다.
라이언 R

답변:


129

EditText가 포커스를 받으면 키보드가 팝업되는 것 같습니다. 이를 방지하려면 focusable을 false로 설정하십시오.

<EditText
    ...
    android:focusable="false"
    ... />

이 동작은 제조업체의 Android OS 버전에 따라 다를 수 있지만 테스트 한 장치에서이 정도면 충분하다는 것을 알았습니다. 키보드가 여전히 팝업되면 텍스트 대신 힌트를 사용하는 것도 도움이되는 것 같습니다.

myEditText.setText("My text");    // instead of this...
myEditText.setHint("My text");    // try this

이 작업을 완료하면 클릭 리스너가 원하는대로 작동합니다.

myEditText.setOnClickListener(new OnClickListener() {...});

이것은 작동하는 것처럼 보이지만 필드에 입력하고 키보드에서 다음을 클릭하면 false에 포커스가있는 필드를 건너 뜁니다.
Sterling Diaz

60

일반적으로 EditText의 정상적인 동작 과 최대한의 호환성을 원합니다 .

그렇기 때문에보기가 더 이상 초점을 맞출 수 없어 보이는 것처럼 사용 해서는 안됩니다android:focusable="false" . 예를 들어 배경 드로어 블은 더 이상 "눌려진"상태를 표시하지 않습니다.

대신해야 할 일은 다음과 같습니다.

myEditText.setInputType(InputType.TYPE_NULL);
myEditText.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // showMyDialog();
    }
});
myEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            // showMyDialog();
        }
    }
});

입력 유형을로 설정하면 TYPE_NULL소프트웨어 키보드가 팝업되지 않습니다.

을 설정 OnClickListener하고 OnFocusChangeListener, 당신이 당신의 대화가 항상 열립니다 있는지 확인시에 사용자가 클릭 EditText필드, 둘 다 초점 (첫 번째 클릭) 및 후속 클릭에를 얻는 경우.

그냥 설정 android:inputType="none"하거나 setInputType(InputType.TYPE_NULL)항상 충분하지는 않습니다. 일부 장치의 경우 android:editable="false"더 이상 사용되지 않지만 XML로 설정해야합니다 . 더 이상 작동하지 않으면 무시됩니다 (지원되지 않는 모든 XML 속성).


이렇게하면 편집 텍스트가 다시 포커스를 받기 때문에 대화 상자가 닫힌 후 다시 열립니다. 이 방법은 없나요?
AdamMc331

@ McAdam331 그 EditText구성 요소가 레이아웃의 유일한 위젯입니까? android:focusable="true"부모 레이아웃에 추가해 볼 수 있습니까 ?
caw

1
@caw 응답 해 주셔서 감사합니다.하지만 결국 onTouch를 사용하여 작동하게되었습니다. 감사!
AdamMc331

그게 다야. 잘 작동합니다.
XueQing

31

나는 이와 같은 문제가 있었다. 코드는 괜찮지 만 EditText의 focusable 값을 false로 변경해야합니다.

<EditText
android:id="@+id/date"
android:focusable="false"/>

나는 이것이 비슷한 문제를 가진 모든 사람에게 도움이되기를 바랍니다!


4
또한 OnClickListener를 해제 할 = "false"를 사용 가능으로 설정하지 마십시오
OatsMantou

25

기본 작업 EditText: 첫 번째 클릭에서 초점을 맞추고 두 번째 클릭에서 처리 onClickListener하므로 초점을 비활성화해야합니다. 그런 다음 처음 클릭하면 onClickListenerwill 핸들이 처리됩니다.

그렇게하려면이 android:focusableInTouchMode="false"속성을 EditText. 그게 다야!

이 같은:

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusableInTouchMode="false"
        android:inputType="text" />

4
작동하지만 EditText편집 할 수 없게되고 커서가 나타나지 않습니다.
CoolMind

17

내가 구현 한 솔루션은 다음과 같습니다.

mPickDate.setOnKeyListener(new View.OnKeyListener() {

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        showDialog(DATE_DIALOG_ID);
        return false;
    }
});

또는

mPickDate.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        showDialog(DATE_DIALOG_ID);

    }
});

차이점을 직접 확인하십시오. 문제는 (RickNotFred가 말한 것처럼) TextView가 DatePicker를 통해 날짜를 표시하고 편집하기 때문입니다. 텍스트 편집기는 기본 목적으로 사용되지 않습니다. DatePicker가 다시 팝업되도록하려면 delete (첫 번째 경우) 또는 de focus (두 번째 경우)를 입력해야합니다.

레이


2
방금 onFocusChangeListener와 함께 한 onClickListener를 추가하지 않는 한. 작동합니다 :-)
neteinstein 2011

두 번째 솔루션이 저에게 효과적이었습니다. 감사합니다! :)
Celtik

9

EditText에서 OnClick 작업을 다음과 같이 사용하는 경우 :

자바:

mEditInit = (EditText) findViewById(R.id.date_init);
mEditInit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        showDialog(DATEINIT_DIALOG);
    }

});

또는 kotlin :

editTextChooseDate.setOnClickListener {
        showDialog(DATEINIT_DIALOG)
    }

그래서, 당신이 유입되면 완벽하게 작동합니다 xml당신의 EditText다음 줄 :

android : inputType = "none"
android : focusable = "false"
android : cursorVisible = "false"

예를 들면 :

<EditText
            android:id="@+id/date_init" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=""
            android:hint="Select Date"
            android:inputType="none"
            android:focusable="false"
            android:cursorVisible="false"/>

또는 MaterialDesign

<com.google.android.material.textfield.TextInputLayout
        android:id="@+id/layoutEditTextChooseDate"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

    <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/date_init" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=""
            android:hint="Select Date"
            android:inputType="none"
            android:focusable="false"                      
            android:cursorVisible="false"/>

</com.google.android.material.textfield.TextInputLayout>

8

IMHO 나는 RickNotFred의 진술에 동의하지 않습니다.

EditText가 포커스를받을 때 대화 상자를 표시하는 것은 비표준 인터페이스처럼 보입니다.

사용자가 EditText를 누를 때 날짜를 편집하는 대화 상자를 표시하는 것은 키보드 또는 숫자 키패드 를 표시하는 기본값과 매우 유사합니다 . 날짜가 EditText와 함께 표시된다는 사실은 날짜가 변경 될 수 있음을 사용자에게 알립니다. 날짜를 편집 할 수없는 TextView로 표시하면 날짜를 변경할 수 없음을 사용자에게 알립니다.


7

좋은 주제입니다. 글쎄, 나는 그렇게했다. XML 파일에서 :

<EditText
    ...
    android:editable="false"
    android:inputType="none" />

자바 코드에서 :

txtDay.setOnClickListener(onOnClickEvent);
txtDay.setOnFocusChangeListener(onFocusChangeEvent);

private View.OnClickListener onOnClickEvent = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        dpDialog.show();
    }
};
private View.OnFocusChangeListener onFocusChangeEvent = new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus)
            dpDialog.show();
    }
};

6

다음은 저에게 완벽하게 작동합니다.

먼저 날짜 선택기 위젯의 입력을 '없음'으로 설정하여 소프트 키보드가 팝업되지 않도록합니다.

<EditText android:inputType="none" ... ></EditText>

그런 다음 다음 이벤트 리스너를 추가하여 날짜 선택기가 포함 된 대화 상자를 표시합니다.

// Date picker
EditText dateEdit = (EditText) findViewById(R.id.date);
dateOfBirthEdit.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            showDialog(DIALOG_DATE_PICKER);
        }
        return false;
    }
});

dateEdit.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            showDialog(DIALOG_DATE_PICKER);
        } else {
            dismissDialog(DIALOG_DATE_PICKER);
        }
    }
});

마지막 한가지. 입력 한 일, 월 또는 연도가 날짜 선택기에서 올바르게 복사되었는지 확인하려면 datePicker.clearFocus()값을 검색하기 전에을 (를) 통해 호출 하십시오 getMonth().


간단한 수정 : 모든 showDialog 전에 dismissDialog를 실행하십시오.
Lukas Batteau 2012

5

이것은 나를 위해 작동합니다.

mEditInit = (EditText) findViewById(R.id.date_init);
mEditInit.setKeyListener(null);
mEditInit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus)
            {
                mEditInit.callOnClick();
            }
        }
    });
mEditInit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        showDialog(DATEINIT_DIALOG);
    }

});

3

다음은 나를 위해 일한 것입니다.

편집 가능을 false로 설정

<EditText android:id="@+id/dob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Date of Birth"
android:inputType="none"
android:editable="false"

/>

그런 다음 OnFocusChange에 대한 이벤트 리스너를 추가하십시오.

private  View.OnFocusChangeListener onFocusChangeDOB= new View.OnFocusChangeListener() {

@Override
 public void onFocusChange(View v, boolean hasFocus) {
   if (hasFocus){
     showDialog(DATE_DIALOG_ID);
   }
 }
};

3
Android 2.3.x를 실행하는 Motorola 휴대폰에주의하십시오. EditText가 스크롤 가능한 영역에있는 경우 Motorola는 스크롤 할 때 자동으로 초점을 이동합니다. 즉, 아래로 스크롤 할 수 있고 EditText가 포커스를 받으면 날짜 대화 상자가 팝업되어 놀랍고 나쁩니다.
Eric Burke

2

Dillon Kearns가 제안했듯이 focusable을 false로 설정하면 정상적으로 작동합니다. 그러나 목표가 EditText를 클릭 할 때 키보드를 취소하는 것이라면 다음을 사용할 수 있습니다.

mEditText.setInputType(0);

2

왜 아무도 언급하지 않았 setOnTouchListener습니까? 사용 setOnTouchListener은 쉽고 괜찮습니다. 리스너가 이벤트를 소비하면 true를 반환하고 그렇지 않으면 false를 반환합니다.


0

OnFocusChangeListener를 사용하는 솔루션의 문제점은 포커스 획득을 클릭으로 해석한다는 것입니다. 이것은 100 % 정확하지 않습니다. EditText는 클릭 이외의 다른 것에서 포커스를 얻을 수 있습니다.

당신이 경우 엄격 클릭 신경 과 (에 관계없이 초점) 지속적으로 클릭을 감지하려면, 당신은 사용할 수 있습니다 GestureDetector:

editText.setOnConsistentClickListener { /* do something */ }

fun EditText.setOnConsistentClickListener(doOnClick: (View) -> Unit) {
    val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(event: MotionEvent?): Boolean {
            doOnClick(this@setOnConsistentClickListener)
            return false
        }
    })

    this.setOnTouchListener { _, motionEvent -> gestureDetector.onTouchEvent(motionEvent) }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.