Отдельные onTouchListeners для представления и его родителя - PullRequest
2 голосов
/ 05 января 2012

У меня есть ListView в Android, и я хотел бы иметь onTouchListeners для представлений строк и самого родительского ListView. Я хотел бы реагировать на отдельные нажатия и длительные нажатия на строки по отдельности, но на броски на ListView в целом. (Я могу установить метод onFling для каждой строки по отдельности, но он не является надежным, поскольку пользователь может перемещать палец по строкам.) Я могу успешно установить onTouchListener для строк и ListView отдельно, но когда я установите оба, слушатель ListView никогда не сработает - только слушатели строки. Это тот случай, когда я возвращаю true или false в методах слушателя строки. Кто-нибудь знает, как вызвать onTouchListeners как для представления, так и для его родителя, учитывая, что они занимают одинаковые пиксели на экране?

Соответствующий код для ListView:

В действии onCreate метод:

mListViewDetector = new GestureDetector(new ListViewGestureListener());  
mListViewListener = new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        return mListViewDetector.onTouchEvent(event);
    }
};

mListView = getListView();
mListView.setOnTouchListener(mListViewListener);

И пользовательский класс GestureListener (определяется как вложенный класс в упражнении):

class ListViewGestureListener extends SimpleOnGestureListener {

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.i("ListViewGestureDetector","onFling");
        return false;
    }

}

Соответствующий код для отдельных строк в ListView:

В методе bindView класса адаптера:

TextView textView;
textView.setOnTouchListener(new ListsTextViewOnTouchListener());

И пользовательский класс onTouchListener (определенный как вложенный класс в классе адаптера):

class ItemsTextViewOnTouchListener implements OnTouchListener {

    public boolean onTouch (View v, MotionEvent event){
        switch(event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            //stuff
            return false;
        case MotionEvent.ACTION_CANCEL:
            //stuff
            return false;
        default:
            break;
        }
        return false;
    }

}

1 Ответ

1 голос
/ 06 января 2012

Pvans,

Ответ немного хитрый, но эта возможность встроена. onTouchEvent() обрабатывает TouchEvent для любого объекта (объектов), для которого он является слушателем. Тогда есть два варианта выполнения того, что вы хотели бы.

1) Вы можете переопределить onInterceptTouchEvent() в родительском представлении и обработать ваш переход туда. Я считаю, что это прекрасно работает для больших представлений с меньшими дочерними представлениями. Я не предпочитаю этот метод для списков (чтобы быть откровенным). onInterceptTouchEvent() потрясающе - отнимать Touch от детей, но если вы сделаете это, вам придется справиться как с броском влево / вправо, так и с горизонтальной прокруткой.

2) Вы также можете создать GestureDetector, который на самом деле является невидимым наложением (вроде). Если вы перенаправите на него свои onTouchEvents, вы все равно получите желаемое поведение, и вам не придется беспокоиться об обработке прокрутки вручную. В этом случае вы просто отправляете TouchEvent в Детектор, и если он возвращает true, ваш Список ничего не делает, а ваш OnFling выполняет свою работу. Если он возвращает false, он не был обработан, поэтому он должен принадлежать списку или одному из его дочерних элементов.

Надеюсь, это поможет, FuzzicalLogic

...