Listview - onClickListener onClick вызывается при повторном использовании представления

У меня есть представление списка, и каждая строка имеет несколько интерактивных областей. В bindView (я использую CursorAdapter) я устанавливаю onClickListener для каждой кликабельной области, и все работает нормально.

Проблема возникает, когда я нажимаю на просмотр, и в то же время вызывается notifyDataSetChanged (или курсор изменяется)

Кажется, что когда я нажимаю первый элемент, но до вызова OnClickListener представление повторно используется (вызывается bindView) для второго элемента, а onClickListener вызывается для второго элемента. Моя единственная идея заключается в том, что представление повторно используется после запуска касания, но до вызова onClickListener. Любая идея, как это исправить или что может быть не так?

РЕДАКТИРОВАТЬ: Если представление по клику внутри прокручивается, между onTouch и onClick есть задержка 180 мс, чтобы узнать, происходит ли щелчок или прокрутка. Поэтому, если представление повторно используется между onTouch и onClick, onClick вызывается для повторно используемой (неправильной) строки.

Почти то же самое можно легко воспроизвести с помощью OnLongClickListener.

@Override
  public void bindView(View view, Context context, Cursor cursor) {
         View clickableView = view.findViewById(R.id.clickable_view);
         clickableView.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 final int position = getListView().getPositionForView(v);
                 if (position != ListView.INVALID_POSITION) {
                      //it display position 2 even when I clicked at position 1
                     Toast.makeText(getContext(), "Position " + position, Toast.LENGTH_SHORT).show();
                 }
         });
  }

person Martin Vandzura    schedule 19.02.2014    source источник


Ответы (1)


Возможно, вы захотите сделать свой onClickListener приватным.

    public View newView(Context context, Cursor cursor, ViewGroup parent) {
    ViewHolder holder = new ViewHolder();
    View view = inflater.inflate(R.layout.yourrow, parent, false);


    holder.your_textview = (TextView) view.findViewById(R.id.tv_your_textviewfield);
    holder.your_textview.setOnClickListener(mMoves_OnClickListener);
    holder.position = cursor.getPosition();
    bindView(view, context, cursor);
    view.setTag(holder);
    return view;
}

private OnClickListener mMoves_OnClickListener = new OnClickListener() {
    public void onClick(View v) {

        ViewHolder holder = (ViewHolder) ((View) v.getParent()).getTag();

        switch (v.getId()) {
        case R.id.tv_your_textviewfield:
            ((OnMoveScoreSelectedListener) context).onMoveScoreClickSelected();
            break;
        case ...
        }
    }
};
person Peter Birdsall    schedule 19.02.2014
comment
Спасибо, но это не помогает - person Martin Vandzura; 20.02.2014