RecyclerView textChangeListener或数据绑定

时间:2017-12-12 11:08:48

标签: android data-binding android-recyclerview android-databinding

我有一个RecylerView,其中每一行都有一个EditText。此EditText用于输入播放器名称。当用户输入名称时,我需要以Adapter正在查看的列表以某种方式更新。

首先我想我会在textChangedListener上加EditText,这部分有效。 问题是当用户添加新行或删除行时,在EditText上调用notifyDataSetChanged()时,似乎每个Adapter的侦听器都会被调用。 notifyDataSetChanged()也会从textChangedListener调用,给出错误

Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView.

另一个选项是不使用textChangedListener,而只是在用户添加行,删除行或开始游戏时更新适配器列表。但为此我需要从RecyclerView中的所有editText中获取信息,而我还没有找到方法。如果可以的话,我可以简单地清除适配器列表,并在每次调用notifyDataSetChanged()时替换用户放入recyclerView的内容。

第三个选项将使用data binding。我一直试图跟随导游,但还没有让它发挥作用。绑定必须使editTexts直接更新适配器列表,并且最好在列表更改时更新EditText,但这并不重要。

关于如何最好地实现这一点的任何想法?

public class ReviewAdapter extends RecyclerView.Adapter<ReviewAdapter.MyViewHolder> {

private ArrayList<String> data;

public ReviewAdapter(ArrayList<String> data) {

    this.data = data;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context c = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(c);
    View view = inflater.inflate(R.layout.custom_row, parent, false);
    MyViewHolder holder = new MyViewHolder(view);

    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    holder.txtPlayerName.setText(data.get(position));
    holder.txtRowNumber.setText(position+1 + "");
    holder.btnRemoveRow.setOnClickListener(new MyClickListener(position, holder.btnRemoveRow));
    holder.txtPlayerName.addTextChangedListener(new MyTextWatcher(position));

}

@Override
public int getItemCount() {
    return data.size();
}

class MyClickListener implements View.OnClickListener {

    private int pos;
    Button button;


    public MyClickListener(int _pos, Button _button) {
        super();
        pos = _pos;
        button = _button;


    }

    @Override
    public void onClick(View view) {
        data.remove(pos);
        System.out.println("MyClickListener.onClick.pos: " + pos);
        MainActivity.txtPlayers.setText(data.size() + " players");
        ReviewAdapter.this.notifyDataSetChanged();
    }
}

class MyTextWatcher implements TextWatcher {

    int pos;

    public MyTextWatcher(int pos) {
        this.pos = pos;
    }

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

    @Override
    public void onTextChanged(CharSequence s, int i, int i1, int i2) {
        data.set(pos, s.toString());
        notifyDataSetChanged();

    }

    @Override
    public void afterTextChanged(Editable editable) {
    }
}


class MyViewHolder extends RecyclerView.ViewHolder {

    EditText txtPlayerName;
    TextView txtRowNumber;
    Button btnRemoveRow;

    public MyViewHolder(View view) {
        super(view);

        txtPlayerName = itemView.findViewById(R.id.listText);
        txtRowNumber = itemView.findViewById(R.id.listIcon);
        btnRemoveRow = itemView.findViewById(R.id.btnRemove);
    }
}
}

2 个答案:

答案 0 :(得分:1)

修改并缩小Adapter类。永远不要在Get-WmiObject -Class Win32_OperatingSystem | % Buildnumber内分配onClickListener而不是那个可以使用此类的课程,这可以解决您的问题。

onBindViewHolder

答案 1 :(得分:0)

适配器中的

实现View.OnFocusChangeListener

@Override
public void onBindViewHolder(Viewholder holder, int position) {
editText.setText(model.getValue());
editText.setOnFocusChangeListener(this);
editText.setTag(position);
}

@Override
public void onFocusChange(View v, boolean hasFocus) {
if (v.getTag() == null)
    return;
int position = (int) v.getTag();
if (!hasFocus && v instanceof EditText)
    mValues.get(position).setValue(((EditText) v).getText().toString());
}