Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues focusing EditTexts in a ListView (Android)

I have a ListView with a few EditTexts in each item. I have no issues with a hardware keyboard, but things freak out a bit with the soft keyboard. I have two issues.

  1. When I first click on an EditText, it briefly appears to have focus but then loses focus once the keyboard has shown. I must then click the EditText again to get focus.
  2. When an EditText with focus is scrolled out of view, focus goes to... well... see the screenshot. I'm not sure what's happening.

More details on #1:

  • When the screen first loads, focus is in the "Gr High School Scale" field, but the keyboard is not shown.
  • If I immediately click on a desired EditText, its OnFocusChangeListener tells me that it receives focus and then loses focus. Visually, I see the cursor appear in the field, but when the keyboard loads the cursor jumps away (like in the screenshot) and I don't know where focus has gone.

I've played around a bit the Focusable and DescendantFocusability attributes of the ListView, but to no avail. Any advice?

Each time an EditText with focus gets scrolled out of view, another drunk cursor shows up: enter image description here

UPDATE: Relevant code.
Activity layout with ListView XML:

<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>

List Items 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" />

Setting the view in my adapter:

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);

I'm not sure what else to post. I have focus and textChange listeners, but the problem exists even if those are commented out. Let me know if anything else is needed. Thank you.

More detail about how focus is behaving when the EditText is touched:

  1. The EditText is clicked (touched)
  2. EditText Receives focus
  3. EditText loses focus
  4. ListView gains focus (and tries to set child focus view requestChildFocus... doesn't seem to succeed).
  5. ListView loses focus
  6. ListView gains focus (and tries to set child focus again).

The above is based on having listeners for both the EditText and the ListView. Note: with a hardware keyboard, the EditText gets focus and that's that. I think the soft keyboard appearing affects the focus.

FINAL UPDATE: In the end, working with the ListView was too difficult, especially because I wanted to update multiple rows based on changes to an EditText in one row. That's hard to do when the keyboard is up and the ListView only considers a few of the rows to exist at any one time.

I instead made nested LinearLayouts. Each horizontal layout was a "row" and I put them inside of an ArrayList in order to manage them and it was a piece of cake, comparatively (still not easy).

like image 205
NSouth Avatar asked Oct 23 '14 00:10

NSouth


1 Answers

You are facing ListView recycling issue. When you scroll up or down or when keyboard appears ListView again refreshes and lost your EditText's focus. So, first of all read this answer to understand ListView Recycling mechanism and then follow the suggestion from my side the solution of your current scenario in my mind.

I suggest you should use a Button on ListView Item and text of this button should be generic like Enter Student Info or what ever you'd like. After clicking on this Button open AlertDialog and set your xml view (currently your all edittexts like et_gpa, et_min, et_max etc on listview items)

For Example:

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's 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();
    }
like image 65
Zubair Ahmed Avatar answered Oct 11 '22 15:10

Zubair Ahmed