Android Campos múltiples de EditText en un ListAdapter

Tengo una pantalla (ver imagen) que se completa con un GridView usando una extensión personalizada de BaseAdapter.

Cuando el usuario ingresa algo de texto en los campos EditText, el texto que ingresó puede cambiar o desaparecer por completo. Supongo que esto tiene que ver con el reciclaje de las vistas, pero mi comprensión de los adaptadores de lista es deficiente.

Los campos se comportan bien inicialmente gracias a la entrada Manifiesto android: windowSoftInputMode = "ajustarPan", pero se desplazan si se desplaza caóticamente.

Todo lo que estoy buscando hacer es obtener algunos datos de String del usuario. Las cadenas se almacenan en una matriz global de cadenas "cadenas []". MyTextWatcher actualiza la matriz de cadenas, que es solo una extensión de TextWatcher.

El código (intentos) para garantizar que los TextWatchers siempre conozcan la posición de su campo EditText dentro de la cuadrícula. De esa manera, los TextWatchers siempre deben actualizar las cadenas [] con el índice correcto.

Tengo todas las razones para creer que el problema deriva de mi método getView ():

public void initList()
{
    ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.shape, strings)
    {
        @Override
        public View getView(final int position, View convertView, ViewGroup parent)  {
            final ViewHolder holder;

            if (convertView == null  || convertView.getTag() == null)  {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.shape, null);

                holder = new ViewHolder();
                holder.text = (TextView) convertView.findViewById(R.id.shape_text);
                holder.image = (ImageView) convertView.findViewById(R.id.shape_image);
                holder.editText = (EditText) convertView.findViewById(R.id.shape_edittext);

                holder.editText.addTextChangedListener(new TextWatcher() {                      
                    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2){}
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        if (gameType == SHAPES_ABSTRACT && before == 0 && count == 1) {
                            InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                            mgr.hideSoftInputFromWindow(holder.editText.getWindowToken(), 0);                               
                        }    
                    }
                    public void afterTextChanged(Editable s) {
                        strings[holder.ref]= s.toString(); 
                    }
                });

                convertView.setTag(holder);                    
            }
            else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.ref = position;
            holder.editText.setText(strings[position]);                             

            holder.image.setBackgroundResource(images[position]);

            if (gameType == SHAPES_ABSTRACT)
                holder.text.setText("Seq:");
            else
                holder.text.setVisibility(View.GONE);   

            return convertView;
        }
    };

    grid.setAdapter(listAdapter);
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta