programing

소프트 키보드가 나타나면 EditText 필드가 포커스를 잃게됩니다.

minecode 2021. 1. 17. 10:47
반응형

소프트 키보드가 나타나면 EditText 필드가 포커스를 잃게됩니다.


ListView에 몇 가지 EditText 필드가 있습니다. EditText 필드 중 하나를 탭하면 키보드가보기로 슬라이드되지만 탭한 EditText 필드는 포커스를 잃습니다. 다양한 InputMethodManager 메서드를 사용하여 키보드를보기에서 시작하도록 시도했지만 (문제를 진정으로 해결하기보다는 해결하기 위해) 작동하지 않았습니다. 활동이 나타날 때 키보드가 보이지 않았습니다.

EditText의 유형은 number이고 키보드가 안으로 들어가면 숫자 키보드이지만 슬라이딩이 끝나고 EditText가 포커스를 잃으면 알파벳 키보드로 변경됩니다 (EditText에 더 이상 포커스가 없다는 생각을 강화함).

내 질문은 다음과 같습니다.

1) 어떻게 글고 필드의 선택을하고, 이후는 소프트 키보드의 슬라이딩 할 수 없는 내 글고 잃게 초점을?

... 실패 ...

2) 키보드를보기에서 시작하여 밀어 넣을 필요가 없도록하려면 어떻게해야합니까?

내 매니페스트에는이 포함 android:windowSoftInputMode="stateAlwaysVisible"되어 있지만 EditText를 탭할 때까지 키보드가 나타나지 않습니다. 'stateAlwaysVisible'속성을 무시하는 것은 에뮬레이터에서만 발생하는 것 같습니다. 프로비저닝 된 장치에서 위의 질문 번호 2가 장치에서 작동하지만 에뮬레이터에서는 작동하지 않습니다.

도움을 주셔서 감사합니다!


내가 한 방법은 다음과 같습니다. onFocusChangeListener()당신이를 터치하면 여러 번 호출 EditText그것으로 텍스트를 입력 할 수 있습니다. 순서는 다음과 같습니다.

  1. 초점이 다른 뷰에있는 경우 해당 뷰는 초점을 잃습니다.
  2. 목표가 초점을 얻습니다.
  3. 소프트 키보드가 나타납니다.
  4. 이로 인해 대상이 초점을 잃게됩니다.
  5. 코드는이 상황을 감지하고 target.requestFocus ()를 호출합니다.
  6. Android 말도 안되는 소리로 인해 가장 왼쪽의 맨 위 뷰에 초점이 맞춰집니다.
  7. requestFocus가 호출되어 가장 왼쪽 뷰가 포커스를 잃습니다.
  8. 목표는 마침내 초점을 얻습니다

    //////////////////////////////////////////////////////////////////
    private final int minDelta = 300;           // threshold in ms
    private long focusTime = 0;                 // time of last touch
    private View focusTarget = null;
    
    View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            long t = System.currentTimeMillis();
            long delta = t - focusTime;
            if (hasFocus) {     // gained focus
                if (delta > minDelta) {
                    focusTime = t;
                    focusTarget = view;
                }
            }
            else {              // lost focus
                if (delta <= minDelta  &&  view == focusTarget) {
                    focusTarget.post(new Runnable() {   // reset focus to target
                        public void run() {
                            focusTarget.requestFocus();
                        }
                    });
                }
            }
        }
    };
    

위의 코드는 키보드 팝업에 잘 작동합니다. 그러나 음성-텍스트 팝업은 감지하지 못합니다.


AndroidManifest.xml에서 변경해야합니다.

목록보기를 보유하는 활동에 android : windowSoftInputMode = "adjustPan"을 추가하십시오. 이것은 당신의 문제를 해결할 것입니다.

    <activity android:name=".MyEditTextInListView"
              android:label="@string/app_name"
              android:windowSoftInputMode="adjustPan">

문안 인사


제 경우에는 ListView의 크기가 조정될 때 모든 목록 항목을 다시 생성하기 때문에 이런 일이 발생합니다 (즉, 각 표시 목록 항목에 대해 getView ()를 다시 호출).

EditText는 getView ()에서 반환하는 레이아웃 내에 있기 때문에 이전에 포커스가 있었던 것과 다른 EditText 인스턴스임을 의미합니다. 두 번째 결과는 소프트 키보드가 나타나거나 사라지면 EditText의 내용을 잃어버린다는 것을 알게되었습니다.

내 뷰를 완전히 액세스 할 수 있기를 원했기 때문에 (즉, 일부 부분에 액세스 할 수없는 키보드 창 뒤에 숨기는 대신 크기를 조정하고 싶었 기 때문에) Frank의 대답을 사용할 수 없었습니다. 그렇지 않으면 최상의 접근 방식처럼 보입니다.

EditText에서 OnFocusChangeListener를 사용하여 포커스를 잃었을 때 타임 스탬프를 기록한 다음 목록 항목을 다시 만들 때 getView ()에서 현재 시간이 포커스를 잃은 시점부터 임계 값 내에 있으면 requestFocus ( )를 사용하여 문제의 EditText에 다시 제공합니다.

그 시점에서 EditText의 이전 인스턴스에서 텍스트를 가져 와서 새 인스턴스로 전송할 수도 있습니다.

private class MyAdapter<Type> extends ArrayAdapter<String>
    implements OnFocusChangeListener
{
    private EditText mText;
    private long mTextLostFocusTimestamp;
    private LayoutInflater mLayoutInflater;

    public MyAdapter(Context context, int resource, int textResourceId, ArrayList<String> data, LayoutInflater li) {
        super(context, resource, textResourceId, data);
        mLayoutInflater = li;
        mTextLostFocusTimestamp = -1;
    }

    private void reclaimFocus(View v, long timestamp) {
        if (timestamp == -1)
            return;
        if ((System.currentTimeMillis() - timestamp) < 250)
            v.requestFocus();
    }

    @Override public View getView (int position, View convertView, ViewGroup parent)
    {
        View v = mLayoutInflater.inflate(R.layout.mylayout, parent, false);

        EditText newText = (EditText) v.findViewById(R.id.email);
        if (mText != null)
            newText.setText(mText.getText());
        mText = newText;
        mText.setOnFocusChangeListener(this);
        reclaimFocus(mText, mTextLostFocusTimestamp);

        return v;
    }

    @Override public void onFocusChange(View v, boolean hasFocus) {
        if ((v == mText) && !hasFocus)
            mTextLostFocusTimestamp = System.currentTimeMillis();
    }
}

하드웨어 키보드가 항상 표시되는 장치에서이 코드를 테스트해야합니다. 여기에서도 동작이 발생할 수 있습니다.

이를 방지하기 위해 키보드를 항상 표시 할 수 있습니다.하지만이 스레드에서 볼 수있는 것처럼 쉽지는 않습니다.

https://groups.google.com/forum/#!topic/android-developers/FyENeEdmYC0

Theoretically you may have to create your own Android keyboard (although using as base the stock Android keyboard) as described here: Android: How to make the keypad always visible?


In AndroidManifest.xml use adjustNothing in the activity that contain the views

<activity
            android:name=".ActivityName"
            android:windowSoftInputMode="adjustNothing">

If the editText inside the listView just make sure that you inflate the View in the getView method with this way.


        if (convertView == null)
        convertView = LayoutInflater.from(context).inflate(R.layout.yourItemListLayout,
                parent, false);   

Edit: this work for some mobiles not all I use the answer from Mr.Frank above.


This guy had the same problem and more besides. He solved it by using a ScrollView and a LinearLayout instead of a ListView.


Add android:windowSoftInputMode="adjustResize" in the activity holding the listview or EditText. This will solve your problem.

<activity android:name=".MainActivity"
        android:windowSoftInputMode="adjustResize">
</activity>

For those who come here with Xamarin or Xamarin.Forms:

I had the same issue as well but only with Android 5.x - all newer Versions including 8.1 worked well.

Obviously sheltond was right by saying:

In my case, this is happening because when the ListView resizes, it re-creates all of the list items (i.e. it calls getView() again for each visible list item).

My listview was resizing as well and no, Franks solution to set windowSoftInputMode="adjustPan" was no option for me because that means that the keyboard moves the listview partly off the screen.

All I had to do after hours of focus-debugging was setting the cell caching strategy of the Xamarin Forms ListView:

From

CachingStrategy="RecycleElement"

To

CachingStrategy="RetainElement"

This will stop the cells from being recreated. However, this might result in bad performance and high memory consumption for huge lists. Be aware.


In my case, I had called root_scrollview.fullScroll(View.FOCUS_DOWN) on my root ScrollView when Keyboard appears. I replaced it with

login_scrollview.post(new Runnable() { 
    @Override
    public void run() {
        root_scrollview.scrollTo(0,root_container.bottom)
    }
});

where root_container is the immediate child of root_scrollview. This solved the problem for me.

Note: Directly calling root_scrollview.scrollTo(0,root_container.bottom) was not working.

ReferenceURL : https://stackoverflow.com/questions/5615436/when-the-soft-keyboard-appears-it-makes-my-edittext-field-lose-focus

반응형