Custom ArrayAdapter中的EditText TextChangedListener没有给出列表项的正确位置。返回的位置值始终为0。

时间:2016-10-18 16:46:45

标签: android listview android-arrayadapter

我有一个自定义ArrayAdapter实现,如下所示:

private final LayoutInflater inflater;
private final Context mContext;
private final int resource;
private ListObject item;

public CheckListAdapter(Context cx, int res, List<ListObject> list){
    super(cx,res,list);
    resource=res;
    mContext=cx;
    inflater=LayoutInflater.from(cx);
}

@Override
public View getView(int position, View convertView, ViewGroup container) {
    convertView = (LinearLayout) inflater.inflate(resource, null);

    item = getItem(position);

    TextView slotNoView = (TextView)convertView.findViewById(R.id.itemSlotNo);
    TextView itemNameView = (TextView)convertView.findViewById(R.id.itemnameview);
    TextView itemIdView = (TextView)convertView.findViewById(R.id.itemIdView);

    String slotNo = item.getSlotNo();
    String itemName = item.getItemName();

    slotNoView.setText(slotNo+".");
    itemNameView.setText(itemName);
    itemIdView.setText(item.getId());

    EditText value = (EditText)convertView.findViewById(R.id.value);
    value.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        }

        @Override
        public void afterTextChanged(Editable editable) {
            String new6amVal = value.getText().toString();

            Log.d("ListView Position",Integer.toString(position));

            Log.d("Item ID: ",item.getId());
            Log.d("Item value: ",value.getText().tostring());
        }
    });


    return convertView;
}

创建适配器并将其发送到列表视图时,所有TextView都会正确填充。但是当我在任何列表项的EditText中进行更改时,更改仅反映在第一个列表项EditText中。当我从TextChangeListener中记录getView方法中获得的位置变量时,我可以看到position的值始终为0.如何从getView方法中获取每个列表项的正确位置值?

我还尝试使用OnFocusChangeListener来检查位置的值,但返回的值始终是第一个位置。

1 个答案:

答案 0 :(得分:2)

您应该为适配器使用推荐的ViewHolder模式,并将您的位置设置为final。如果这不起作用,那么我建议您创建一个自定义TextWatcher类来跟踪位置本身。这是一些示例代码。

对于ViewHolder模式,创建一个扩展RecyclerView.ViewHolder并在那里查找所有视图的类

 public class MyViewHolder extends RecyclerView.ViewHolder {

    TextView slotNoView;
    TextView itemNameView;
    TextView itemIdView;
    EditText value;

    public MyViewHolder(View itemView) {
        super(itemView);
        slotNoView = (TextView) itemView.findViewById(R.id.itemSlotNo);
        itemNameView = (TextView)itemView.findViewById(R.id.itemnameview);
        itemIdView = (TextView) itemView.findViewById(R.id.itemIdView);
        value = (EditText) itemView.findViewById(R.id.value);
    }
}

然后在getView适配器方法中,仅当convertview为null时才创建ViewHolder的新实例。像这样(记得要position final

@Override
public View getView(final int position, View convertView, ViewGroup container) {
    MyViewHolder viewHolder;
    if(convertView == null){
        convertView =  inflater.inflate(resource, container, false);

    }
    viewHolder = new MyViewHolder(convertView);

    item = getItem(position);
    String slotNo = item.getSlotNo();
    String itemName = item.getItemName();
    viewHolder.slotNoView.setText(slotNo+".");
    viewHolder.itemNameView.setText(itemName);
    viewHolder.itemIdView.setText(item.getId());

    viewHolder.value.addTextChangedListener(new TextWatcher() {
        //implement your stuff
        ...
    }

}

如果这不起作用,请创建一个实现TextWatcher的自定义抽象类,该类将知道该位置,然后在其中实现一个方法getPosition(),以便在你需要它。您可以在构造函数中传递位置。例如:

private abstract class PositionAwareTextWatcher implements TextWatcher{

    private int position;

    public PositionAwareTextWatcher(int position){
        this.position = position;
    }

    public int getPosition(){
        return this.position;
    }

}

然后在您设置TextWatcher的getView中,按照这样使用

viewHolder.value.addTextChangedListener(new PositionAwareTextWatcher(position) {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String new6amVal = value.getText().toString();

            Log.d("ListView Position",Integer.toString(getPosition()));

            Log.d("Item ID: ",item.getId());
        Log.d("Item value: ",value.getText().tostring());
        }
    };
相关问题