2

I create a simple ListView where each row is an EditText. Here is my R.layout.item:

<?xml version="1.0" encoding="utf-8"?>

<EditText xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:inputType="textMultiLine">

</EditText>

Notice how the EditText allows multi-line input through the android:inputType="textMultiLine" flag. By means of an ArrayAdapter I populate the ListView with a number of rows such that the ListView can be scrolled. In my case the items are 40. Here is my MainActivity.java:

public class MainActivity extends ListActivity {

    final int NUM_ITEMS = 40;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] items = new String[NUM_ITEMS];
        for (int i = 0; i < NUM_ITEMS; i++) {
            items[i] = Integer.toString(i);
        }
        setListAdapter(new ArrayAdapter<String>(this, R.layout.item, items));
    }

}

I scroll down to row 20 and start typing text, but when I reach the end of the line and the EditText changes its size to accommodate for the second row, suddenly the ListView automatically scrolls all the way to the top.

I consider the described behaviour a horrible user experience and I struggle to understand why it should be the default. The behaviour I look for is for the rows above to stay put and for the rows below to shift of the necessary amount to leave room for the expanded EditText. How can I achieve it?

Some additional info, I run this code on the emulator against Android 4.2.2, the device is a 3.2" HVGA slider (ADP1). I've chosen that particular device to reproduce a bug experienced by a user.

Matteo Danieli
  • 223
  • 3
  • 7
  • I'd suggest not mixing EditTexts and ListViews, because of the focus and the recycling, it's all a huge pain in the butt. If you don't plan to have that many EditTexts, I'd suggest just using a ScrollView. – dmon Jul 05 '13 at 02:19
  • Unfortunately I have built the whole app concept around EditTexts within a ListView. You can check out [my app](https://play.google.com/store/apps/details?id=dk.bendingspoons.fontsy) to understand why I cannot really change that :) But you're right, it is a huge pain in the butt. – Matteo Danieli Jul 05 '13 at 10:54

1 Answers1

0

Indeed a weird default behavior. But instead of struggling with the cause of the problem, you can fix it with a few simple steps:

  • Keep track of the scrolling state whenever the user changed it, using AbsListView.OnScrollListener's onScroll callback. Save the value of firstVisibleItem.
  • It might be a bit of a hassle, but subclass EditText and override onSizeChanged. In this method, notify your list view (And dont forget to call super.onSizeChanged).
  • When your list view is notified that an EditText has changed, you should call smoothScrollToPosition with the last value of firstVisibleItem you have saved.
Jong
  • 9,045
  • 3
  • 34
  • 66
  • Thanks for the suggestion! Eventually I've found out that the problem only occurs with hardware keyboard. If you try to run it with soft keyboard instead the list doesn't move around when the size changes. I've given up trying to solve it for the time being, but your answer points to the right direction. – Matteo Danieli Jul 05 '13 at 10:58