ListAdapter中的Android Multiple EditText字段

时间:2011-11-15 00:57:29

标签: android gridview android-edittext listadapter

我有一个使用BaseAdapter自定义扩展程序由GridView填充的屏幕(参见图片)。

当用户在EditText字段中输入一些文本时,他们输入的文本可能会移动或完全消失。我假设这与回收视图有关,但我对listadapters的理解很差。

由于Manifest条目android:windowSoftInputMode =“adjustPan”,这些字段的行为很好,但如果你滚动混乱,它们就会移动。

我要做的就是从用户那里获取一些String数据。字符串存储在全局字符串数组“strings []”中。字符串数组由MyTextWatcher更新,它只是TextWatcher的扩展。

代码(尝试)确保TextWatchers始终知道网格中EditText字段的位置。这样,TextWatchers应该始终使用正确的索引更新strings []。

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 个答案:

答案 0 :(得分:2)

我会再次提到这个,就像在另一个答案中一样,说我不会这样实现它。你做的很可怕。附带了很多参考资料。但是,我认为这应该有所帮助:

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的'equals'将执行对象实例比较,而不是值比较。如果不是这种情况,则需要保留对所有EditText实例的引用,并对每个实例进行“==”比较并找到匹配项。

我认为有更安全的方法可以做到这一点,但请试一试。