Проблемы, связанные с EditTexts в ListView (Android)
У меня есть ListView с несколькими EditTexts в каждом элементе. У меня нет проблем с аппаратной клавиатурой, но что-то удручает с помощью мягкой клавиатуры. У меня есть два вопроса.
- Когда я сначала нажимаю на EditText, он, как представляется, имеет фокус, но затем теряет фокус после показа клавиатуры. Затем я должен нажать EditText, чтобы получить фокус.
- Когда EditText с фокусом прокручивается вне поля зрения, фокус идет... ну... см. скриншот. Я не уверен, что происходит.
Подробнее о # 1:
- Когда экран загружается первым, фокус находится в поле "Масштаб средней школы", но клавиатура не отображается.
- Если я сразу же нажимаю на желаемый EditText, его
OnFocusChangeListener
сообщает мне, что он получает фокус, а затем теряет фокус. Визуально, я вижу, что курсор появляется в поле, но когда клавиатура загружается, курсор отскакивает (как на скриншоте), и я не знаю, куда ушел фокус.
Я немного поиграл с атрибутами Focusable и DescendantFocusability в ListView, но безрезультатно. Любой совет?
Каждый раз, когда EditText с фокусом получает прокрутку вне поля зрения, появляется другой пьяный курсор:
ОБНОВЛЕНИЕ: Релевантный код.
Макет действий с 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 и дайте мне знать, если это поможет.. спасибо за ожидание