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

标签 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;
}

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

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

最佳答案

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

对于 ViewHolder 模式,创建一个扩展 RecyclerView.ViewHolder 的类并在那里找到你所有的 View

 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());
        }
    };

关于android - Custom ArrayAdapter 中的 EditText TextChangedListener 没有给出列表项的正确位置。返回的位置值始终为 0。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40113815/

相关文章:

android - 使用 WebView 进行 OAuth2 授权

android - 如何在android中集成google plus并获取个人资料信息?

android - 多个图像进度条加载就像在 Whats App 中一样

Android 自定义微调适配器不显示内容

无法识别的 JavaScriptInterface 方法(Android webview)

java - Failed to notify project evaluation listener 错误在 Android Studio

listview - Xamarin.Forms:获取 ListView 的所有单元格/项目

android - 自定义 ListView 适配器 Android

Android 自定义微调器未填充

Android 更新在自定义 ArrayAdapter 中设置的进度条