Проблемы, связанные с EditTexts в ListView (Android)

У меня есть ListView с несколькими EditTexts в каждом элементе. У меня нет проблем с аппаратной клавиатурой, но что-то удручает с помощью мягкой клавиатуры. У меня есть два вопроса.

  • Когда я сначала нажимаю на EditText, он, как представляется, имеет фокус, но затем теряет фокус после показа клавиатуры. Затем я должен нажать EditText, чтобы получить фокус.
  • Когда EditText с фокусом прокручивается вне поля зрения, фокус идет... ну... см. скриншот. Я не уверен, что происходит.

Подробнее о # 1:

  • Когда экран загружается первым, фокус находится в поле "Масштаб средней школы", но клавиатура не отображается.
  • Если я сразу же нажимаю на желаемый EditText, его OnFocusChangeListener сообщает мне, что он получает фокус, а затем теряет фокус. Визуально, я вижу, что курсор появляется в поле, но когда клавиатура загружается, курсор отскакивает (как на скриншоте), и я не знаю, куда ушел фокус.

Я немного поиграл с атрибутами Focusable и DescendantFocusability в ListView, но безрезультатно. Любой совет?

Каждый раз, когда EditText с фокусом получает прокрутку вне поля зрения, появляется другой пьяный курсор: enter image description here

ОБНОВЛЕНИЕ: Релевантный код.
Макет действий с XML-списком ListView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/com.NsouthProductions.gradetrackerpro"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.NsouthProductions.gradetrackerpro.Activity_EditCourseGPA" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="34dp"
    android:text="Define the GPA and Percent scale for this course." />

<RadioGroup
    android:id="@+id/radioGroup1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/textView1"
    android:layout_marginLeft="5dp" >

    <LinearLayout
        android:id="@+id/linlay_rad_group_existing_scale"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <RadioButton
            android:id="@+id/radio0_existing_scale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:checked="true"
            android:text="Existing Scale" />

        <Spinner
            android:id="@+id/spinner_existing_scales"
            android:layout_width="wrap_content"
            android:layout_height="33dp"
            android:layout_gravity="right"
            android:layout_weight="1" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linlay_rad_group_new_scale"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <RadioButton
            android:id="@+id/radio1_new_scale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:text="New Scale" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:lines="1"
            android:maxLines="1"
            android:text=" " />

        <EditText
            android:id="@+id/editText1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:inputType="textPersonName"
            android:maxLines="1"
            android:scrollHorizontally="true"
            android:text="Gr High School Scale" >

            <requestFocus />
        </EditText>

    </LinearLayout>
</RadioGroup>


 <LinearLayout
    android:id="@+id/linlay_scale_save_buttons"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true" >

    <Button
        android:id="@+id/btn_gpa_cancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <Button
        android:id="@+id/btn_gpa_save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>

 <ListView
     android:id="@+id/listview_scale"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_above="@id/linlay_scale_save_buttons"
     android:layout_alignParentLeft="true"
     android:layout_below="@id/radioGroup1"
     android:focusable="true"
     android:focusableInTouchMode="true"
     android:headerDividersEnabled="true"
     android:scrollingCache="true" >

 </ListView>

Элементы списка XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linlay_scale_list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

        <CheckBox
                android:id="@+id/checkbox_scale_item"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="A-" />

            <EditText
                android:id="@+id/et_gpa"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:enabled="true"
                android:inputType="numberDecimal"
                android:maxLength="6"
                android:text="4.000" />

            <EditText
                android:id="@+id/et_min"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:enabled="true"
                android:inputType="numberDecimal"
                android:maxLength="6"
                android:text="94.75" />

            <EditText
                android:id="@+id/et_max"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:inputType="numberDecimal"
                android:maxLength="6"
                android:text="100.0" />

Настройка представления в моем адаптере:

View v = convertView;
ViewHolder holder;

    v = inflater.inflate(R.layout.scale_list_item, 
    holder = new ViewHolder();
    holder.cb = (CheckBox) v.findViewById(R.id.checkbox_scale_item);
    holder.et_gpa = (EditText) v.findViewById(R.id.et_gpa);
    holder.et_min = (EditText) v.findViewById(R.id.et_min);
    holder.et_max = (EditText) v.findViewById(R.id.et_max);

Я не уверен, что еще писать. У меня есть фокус и textChange слушателей, но проблема существует, даже если они закомментированы. Дайте мне знать, если что-то еще понадобится. Спасибо.

Подробнее о том, как фокус ведет себя при касании EditText:

  • Нажав кнопку EditText (коснулся)
  • EditText получает фокус
  • EditText теряет фокус
  • Фокусировка списка ListView (и попытка установить вид детальной фокусировки requestChildFocus... кажется, не преуспевает).
  • ListView теряет фокус
  • ListView получает фокус (и пытается снова установить дочерний фокус).

Вышеуказанное основано на наличии слушателей как для EditText, так и для ListView. Примечание: с аппаратной клавиатурой EditText получает фокус и что это. Я думаю, что появление мягкой клавиатуры влияет на фокус.

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ: В конце концов, работа с ListView была слишком сложной, особенно потому, что я хотел обновить несколько строк на основе изменений в EditText в одной строке. Это трудно сделать, когда клавиатура вставлена, и ListView рассматривает только несколько строк, которые могут существовать в любой момент времени.

Вместо этого я сделал вложенные LinearLayouts. Каждая горизонтальная компоновка была "строкой", и я помещал их в ArrayList, чтобы управлять ими, и это был кусок пирога, сравнительно (все еще не простой).

Ответы

Ответ 1

Вы столкнулись с проблемой утилизации ListView. При прокрутке вверх или вниз или при появлении клавиатуры ListView снова обновляется и теряется фокус EditText's. Итак, прежде всего прочитайте этот ответ, чтобы понять ListView Механизм рециркуляции, а затем следуйте предложению со своей стороны о решении вашего текущего сценария в моем сознании.

Я предлагаю вам использовать элемент Button on ListView, и текст этой кнопки должен быть общим, например "Введите информацию о студенте" или что угодно. После нажатия на Button откройте AlertDialog и установите представление xml (в настоящее время все ваши теги edittexts, такие как et_gpa, et_min, et_max и т.д. На ListView)

Пример:

btnInfo.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

                showStudentInfoAlert();

}

});

public void showStudentInfoAlert() 
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);

       LayoutInflater in = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View v = in.inflate(R.layout.your_xml_having_edittexts, null);

EditText et_gpa = (EditText) v.findViewById(R.id.et_gpa);

//add all edit texts like this and after that just set view on alert dialog

        builder.setTitle("Enter student info");

        builder.setView(v);

        builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

               //save all edittexts values and do what erver you want with those values 

            }
        });

        dialog.show();
    }

Ответ 2

Прежде всего, когда экран загружается, фокус находится в поле "Средняя школа", из-за этого <requestFocus /> в вашем xml. но это не гарантирует, что клавиатура может показать.. чтобы клавиатура отображала использование getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); также я думаю, что он сразу же теряет фокус, потому что listview отвлекся от edittext

<ListView
 android:id="@+id/listview_scale"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_above="@id/linlay_scale_save_buttons"
 android:layout_alignParentLeft="true"
 android:layout_below="@id/radioGroup1"
 android:focusable="true" //this
 android:focusableInTouchMode="true" // and that
 android:headerDividersEnabled="true"
 android:scrollingCache="true" >

и так как ни один из ваших списков edittext не запрашивает фокус, фокус остается только в списке, а не в редакторе. Вам нужно снова направить фокус обратно на edittext..также из документации android state По умолчанию пользователь не может перемещать фокус на просмотр;.., а также он указывает, что "если focusableInTouchMode является истинным для представления, это представление может получить фокус при нажатии, и может сохранять фокус, если на него нажимается другое представление, для которого этот атрибут не установлен" . в основном, когда вы сначала создаете edittext, он автоматически добавляет <requestFocus /> к нему, указывая, что ему нужно сфокусироваться или он может сфокусироваться. Но в вашем случае и с этим документом edittext никогда не будет держать фокус, потому что listview убирает его от него.. так что коротко попробуйте это во всех представлениях (включая ваш edittext), которые вы хотите сфокусировать, как в списке.

android:focusable="true" 
android:focusableInTouchMode="true" 

попробуйте это на edittext и дайте мне знать, если это поможет.. спасибо за ожидание