convertview listview 适配器 EditText 混淆

Posted

技术标签:

【中文标题】convertview listview 适配器 EditText 混淆【英文标题】:convertview listview adapter EditText confuse 【发布时间】:2016-01-14 23:10:27 【问题描述】:

我有一个 listView 填充了一个自定义类扩展 BaseAdapter

 private List<Bundle> allTipologiaInsetti = ....;
 listView.setAdapter(new CustumAdapter(getBaseContext(), allTipologiaInsetti, this));

然后在我的适配器上..

public class CustumAdapter extends BaseAdapter 

public CustumAdapter (Context context, List<Bundle> items, RaccoltaDatiQuestions activity) 
    // TODO Auto-generated constructor stub
    this.context = context;
    this.items = items;
    //update
    map = new HashMap<Number, String>();


...
public View getView(final int position, View convertView, ViewGroup parent) 
    Bundle myObj = items.get(position);
    ViewHolder holder;
    view = convertView;
    if (view == null ) 
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.tipologia_insetti_item, null);
        holder.campoNum = (EditText) view.findViewById(R.id.numField);
        view.setTag(holder);
     else 
        holder = (ViewHolder) view.getTag();
    
    //UPDATE
    String num = map.get(position);
    if(num!=null && !num.equals(""))
        holder.campoNum.setText(num + "");
    else 
        holder.campoNum.setText(myObj.getInt("num") + "");
    


    holder.campoNum.addTextChangedListener(new GenericTextWatcher(holder.campoNum, position));



        public GenericTextWatcher(EditText campNum, int position) 
        this.position = position;
        this.campoNum = campNum;
    

    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)  

    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)   

    public void afterTextChanged(Editable s) 
        if (campoNum.getText().length() > 0) 
            if (campoNum.getText().hashCode() == s.hashCode()) 
                Bundle myObj = items.get(position);
                myObj.putInt("num", Integer.parseInt(s.toString()));
               //UPDATE
                map.put(position, s.toString());

            
        

    

“campoNum”是一个编辑文本:

我在列表的第一项上更改了“campoNum”的值(并且效果很好),但是如果我向下滚动,列表的其他一些项,保持第一项的值相同....

我尝试分析它,我发现:

如果我在列表中有 3 项可见,并且我更改了第一项,则第 5 项将采用与第一项相同的值,如果我有 4 项可见,如果我更改第一项,也会更改第 6 项......等等..

如果我删除 "if (view == null )" 并让我们每次都给视图充气,问题就解决了!

如果我很好理解:每次隐藏列表中的一项(第一项)时,它将用于新出现的项(第五项),并且第五项传递的 convertVIew 与第一项相同

有什么建议吗?

【问题讨论】:

【参考方案1】:

是的,这就是列表视图的工作方式。当您向上/向下滚动时,项目会重新打印为其原始布局和数据。我在更改项目图标颜色时遇到了完全相同的问题。

解决方法是对所有列表视图项使用数组,例如数组项 myText= ""。数组项的位置与列表视图中项的位置相同。

在您的 getView 中,当您将文本添加到 editText 时,将其存储到数组中的 myText 中。

你需要做的,还是在getView中说

if myText is not emptyadd myText to the items editText。这一切都由代码完成。

当您向上/向下滚动时,它将使用存储的文本(例如 myText)填充任何项目 editText 的文本

您可以使用此方法对列表视图中的项目进行任何更改。图标、文字等。

所以在数组中存储一些东西来表示一个项目的状态或数据变化,然后在滚动时设置它。

这一切都在getView内部完成

【讨论】:

也许我不明白......(你的建议几乎是我已经做过的?!......我从 Bundle myObj = items.get(position); 中读取了值并设置何时值变化:myObj.putInt("num", Integer.parseInt(s.toString())); @Crifano Stefano。你在这里做(afterTextChanged),我认为这不会奏效。您需要将文本存储在一个数组中,然后将存储的数组文本添加到项目【参考方案2】:

当您在编辑文本中输入值时,将该值与位置(作为值的键)一起放入哈希图中,并且每次显示编辑文本时,您都应该从位置键上的哈希图中获取值, 如果存在。

public CustumAdapter (Context context, List<Bundle> items, RaccoltaDatiQuestions activity) 
    // TODO Auto-generated constructor stub
    this.context = context;
    this.items = items;
    //update
    map = new HashMap<Number, String>();


...
public View getView(final int position, View convertView, ViewGroup parent) 
    Bundle myObj = items.get(position);
    ViewHolder holder;
    view = convertView;
    if (view == null ) 
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.tipologia_insetti_item, null);
        holder.campoNum = (EditText) view.findViewById(R.id.numField);
        view.setTag(holder);
     else 
        holder = (ViewHolder) view.getTag();
    
    //UPDATE
    String num = map.get(position);
    if(num!=null && !num.equals(""))
        holder.campoNum.setText(num + "");
    else 
        holder.campoNum.setText(myObj.getInt("num") + "");
    
if (map.containsKey(position))

        holder.campoNum.setText(map.get(position));


    holder.campoNum.addTextChangedListener(new GenericTextWatcher(holder.campoNum, position));



        public GenericTextWatcher(EditText campNum, int position) 
        this.position = position;
        this.campoNum = campNum;
    

    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2)  

    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2)   

    public void afterTextChanged(Editable s) 
        if (campoNum.getText().length() > 0) 

                map.put(position, campoNum.getText().toString());


        

    

【讨论】:

谢谢,我需要在哪里初始化HashMap?在构造函数上? 我仍然缺少一些东西。我认为这两个答案都很好,我用地图编辑了我的问题,但仍然无效!也许我需要将地图存储在我的 custumAdapter 之外?而且我没有看到使用地图而不是 Bundle myObj = items.get(position) 的不同之处

以上是关于convertview listview 适配器 EditText 混淆的主要内容,如果未能解决你的问题,请参考以下文章

普通的listview适配器

Listview、自定义适配器和复选框

ListView

Android ListView 和带有 ViewHolder 的自定义适配器

Android学习笔记01

ListView性能优化——convertView&viewHolder