Android несколько полей EditText в ListAdapter - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть экран (см. Рисунок), который заполняется GridView с использованием собственного расширения BaseAdapter.

Когда пользователь вводит какой-либо текст в поля EditText, введенный им текст может сместиться или полностью исчезнуть. Я предполагаю, что это связано с переработкой представлений, но мое понимание listadapters плохое.

Поля ведут себя нормально изначально благодаря записи Manifest android: windowSoftInputMode = "AdjustPan", но они перемещаются, если вы прокручиваете хаотично.

Все, что я хочу сделать, это получить некоторые строковые данные от пользователя. Строки хранятся в глобальном массиве строк «strings []». Массив строк обновляется MyTextWatcher, который является просто расширением TextWatcher.

Код (пытается) обеспечить, чтобы TextWatchers всегда знали положение своего поля EditText в сетке. Таким образом, TextWatchers всегда должны обновлять строки [] с правильным индексом.

shows an example of the carnage

У меня есть все основания полагать, что проблема связана с моим методом 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);
}

1 Ответ

2 голосов
/ 15 ноября 2011

Я бы еще раз предвосхитил это, как и в другом ответе, сказав, что не буду реализовывать это таким образом. Вы делаете страшные вещи. Проведение много ссылок вокруг. Тем не менее, я думаю, что это должно помочь:

Map<EditText, MyTextWatcher> watchers = new HashMap<EditText, MyTextWatcher>();

public View getView(int position, View convertView, ViewGroup parent)
{
    View MyView = convertView;
    if (MyView == null)
    {
        LayoutInflater li = getLayoutInflater();
        MyView = li.inflate(R.layout.shape, null);
    }

    EditText textbox = (EditText) MyView.findViewById(R.id.shape_edittext);

    textbox.setText(strings[position]);
    MyTextWatcher myTextWatcher = watchers.get(textbox);

    if(myTextWatcher == null)
    {
        myTextWatcher = new MyTextWatcher(position, textbox);
        watchers.put(textbox, myTextWatcher);
    }

    myTextWatcher.setIndex(position);

    ImageView image = (ImageView) MyView.findViewById(R.id.shape_image);
    image.setBackgroundResource(images[position]);

    TextView text = (TextView) MyView.findViewById(R.id.shape_text);
    text.setText("Seq:");

    return MyView;
}

Проблема здесь в том, что вы создали TextWatcher, добавили его в EditText, но затем сохранили ссылку на него в списке по позициям, поэтому ссылки между EditText и TextWatcher были нарушены.

В этом решении предполагается, что значение «равно» для EditText будет выполнять сравнение экземпляров объекта, а не сравнение значений. Если это НЕ тот случай, вам нужно сохранить ссылку на все экземпляры EditText и выполнить сравнение «==» с каждым и найти совпадение.

Я думаю, что есть более безопасные способы сделать это, но попробуйте.

...