【问题标题】:values of EditTexts in ListView are duplicated randomlyListView 中 EditTexts 的值是随机重复的
【发布时间】:2016-07-23 20:31:52
【问题描述】:

我的列表视图在每一行都有一个 Edittext 和 Button。当我在第一行的 Edittext 中插入值然后我向下滚动列表时,我发现 ListView 中的其他一些 EditText 填充了相同的值。我怎样才能防止这种情况。请帮帮我。

这是我的代码

public class ItemsAdapter extends ArrayAdapter<Items>{


Double Price;
Double Quantity;
String  _Quantity;
private int resource;
private LayoutInflater inflater;
private Context context;
Items items;
List<Items> objects;

private ArrayList<String> externalArray = new ArrayList<String>();

public ItemsAdapter(Context ctx, int resourceId, List<Items> objects){

    super( ctx, resourceId, objects );
    resource = resourceId;
    inflater = LayoutInflater.from( ctx );
    context=ctx;
    this.objects=objects;


    for(int i =0; i< objects.size();i ++ )
    {
       externalArray.add(i,"");
    }
}



@Override
public int getCount() {
    return objects.size();
}

@Override
public Items getItem(int position) {
    return objects.get(position);
}


@Override
public long getItemId(int position) {
    return 0;
}
@Override
public View getView (final int position, View convertView, ViewGroup parent ) {


 final   ItemViewHolder viewHolder;
    items = getItem( position );

    if (convertView == null) {


        convertView=( RelativeLayout ) inflater.inflate( resource,null);

        viewHolder=new ItemViewHolder();

      //  LayoutInflater.from(context).inflate(R.layout.list_items, parent, false);

        viewHolder.btnAddToCart=(Button)convertView.findViewById(R.id.btnAddToCart);
        viewHolder.lblItemsName=(TextView) convertView.findViewById(R.id.lblItemName);
        viewHolder.lblPrice = (TextView) convertView.findViewById(R.id.lblPrice);
        viewHolder.btnPlus=(ImageButton)convertView.findViewById(R.id.btnPlus);
        viewHolder.btnMinus=(ImageButton)convertView.findViewById(R.id.btnMinus);
        viewHolder.txtQuantity  =(EditText)convertView.findViewById(R.id.txtQuantity);

        convertView.setTag(viewHolder);



    } else {

       viewHolder = (ItemViewHolder) convertView.getTag();
    }




  viewHolder.txtQuantity.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {



        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

            externalArray.set(position,viewHolder.txtQuantity.getText().toString());

        }
    });



    viewHolder.btnAddToCart.setTag(convertView);
    viewHolder.btnPlus.setTag(convertView);
    viewHolder.btnMinus.setTag(convertView);

    viewHolder.lblItemsName.setText(items.getItemName());
    String p=items.getPrice().toString();
    viewHolder.lblPrice.setText(p+" $" );





   if (externalArray.get(position) == "")
            viewHolder.txtQuantity.setText("");
        else
            viewHolder.txtQuantity.setText(externalArray.get(position));



        viewHolder.btnAddToCart.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {



               _Quantity=viewHolder.txtQuantity.getText().toString();

                Quantity = new Double(Double.parseDouble(_Quantity));

                Double Total =Price*Quantity;



            }
        });




        return convertView;
    }


  public class ItemViewHolder {

    public EditText txtQuantity ;
    public Button btnAddToCart ;
    public   TextView lblItemsName;
   public  TextView lblPrice;

    }
}

【问题讨论】:

  • LayoutInflater.from(context).inflate(R.layout.your_layout, parent, false);
  • CALL convertView = null; then if if (convertView == null) {
  • 正确遵循 ViewHolder 模式

标签: android


【解决方案1】:

你可以看看我的回答here。尽管问题不一样,但是是的,这是您在这里遇到的类似情况。

因此,在您的情况下,您可以通过多种方式解决问题。不过我可以给你推荐一个。您可能会保留一个外部数组,该数组最初将包含所有空字符串。数组大小需要等于RecyclerView 的大小。在getView() 中添加TextWatcherEditText。因此,想法是当您在EditText 字段中添加一些文本时,将文本存储在外部数组中。将文本放在数组的特定索引中,以跟踪列表中的哪个项目被修改。

现在在您的 getView() 方法中

if(externalArray[pos].equals("")) 
    txtQuantity.setText("");
else 
    txtQuantity.setText(externalArray[pos]);

是的,在您初始化列表项的其他视图的onClickListener 之外声明EditText

所以根据您更新的代码,我可以建议您进行一些修改

// Declare an String array
private String[] externalArray = new String[objects.size()];

现在你的TextChangedListener 应该是这样的

viewHolder.txtQuantity.addTextChangedListener(new TextWatcher() {
  @Override
  public void onTextChanged(CharSequence s, int start, int before, int count) {
    externalArray[position] = viewHolder.txtQuantity.getText().toString();
  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    // Do nothing
  }

  @Override
  public void afterTextChanged(Editable s) {
    // Do nothing
  }
});

现在像这样设置txtQuantity

//if (externalArray.get(position).equals(""))
//  viewHolder.txtQuantity.setText("");
//else
//  viewHolder.txtQuantity.setText(externalArray.get(position));

// OR you can put a single line. I added the else part
// to make you understand the scenario actually. 
viewHolder.txtQuantity.setText(externalArray.get(position));

【讨论】:

  • 请查看更新后的代码。使用equals() 匹配字符串。
【解决方案2】:

这条线正在制造麻烦

EditText   txtQuantity=(EditText)((View)v.getTag()).findViewById(R.id.txtQuantity);

您需要直接从查看器中获取 EditText。 只需使用:

viewHolder.txtQuantity.getText().toString()

并且您需要初始化txtQuantity 以及其他viewholder 视图。

【讨论】:

  • 即使我按照你说的做了,也解决不了问题。
【解决方案3】:

这完全是因为您的 List 项目正在被回收,如果 convertView 不是 null 那么它会被 convertView.getTag(); 回收。

为了防止这种情况,您可以通过删除来防止回收convertView 代码

  if (convertView == null) {

还有匹配的 else 子句。

但是在那之后你可能会遇到滚动滞后问题,所以我可以建议尝试优化你的列表项,这意味着尝试减少列表项的数量,因为它会导致 CPU 消耗高。

【讨论】:

  • 这给我带来了另一个问题,每次我向下滚动列表时,EditText 的值都会变为空。
  • 哪个 EditText ?您是在说您在上面输入了一些文本的 editText 吗?
  • 是的,我在谈论 txtQuantity
  • 删除 ((View)v.getTag()) 并使用 convertView.findViewById
  • ok 那么你的意思是说,你在顶部的edittext中输入了一些东西,然后你滚动到底部或底部,当你再次回滚到顶部时,你发现edittext在你已经输入的地方是空的。是怎么回事吗?
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 2016-01-28
  • 2011-06-19
  • 2020-05-13
  • 2011-06-10
  • 2013-02-21
  • 2012-01-16
  • 2023-03-19
相关资源
最近更新 更多