Android-панель поиска - PullRequest
11 голосов
/ 20 марта 2012

Возможно ли перемещение панели поиска только при перемещении большого пальца. Сейчас панель поиска движется даже при касании пальцем в progressdrawable. Как отключить движение поисковой панели на прикосновение пальца к прогрессирующему элементу?

Спасибо.

Ответы [ 4 ]

8 голосов
/ 18 декабря 2013

Я обнаружил, что проблема с решением Рави в том, что касание и выход за пределы текущей позиции большого пальца все равно приведет к прыжку.

Класс, приведенный ниже, решает эту проблему и заменяет переход на касание с небольшим приращением, аналогичным тому, который можно получить с помощью клавиш со стрелками.


import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.SeekBar;

/**
 * A NoSkipSeekBar is an extension of {@link SeekBar} that prevents jumps in position
 * by touching outside the current thumb position. Such touches are replaced by
 * an increment or decrement the same as would be achieved using a DPAD's Left or
 * Right arrow keys.
 */
public class NoSkipSeekBar extends SeekBar {

    public NoSkipSeekBar(Context context) {
        super(context);
    }

    public NoSkipSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoSkipSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private boolean isDragging;

    private boolean isWithinThumb(MotionEvent event) {
        return getThumb().getBounds().contains((int)event.getX(), (int)event.getY());
    }

    private void increment(int direction) {
        if (direction != 0) {
            final KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, 
                    direction < 0 ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT);
            onKeyDown(key.getKeyCode(), key);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled() || getThumb() == null) return super.onTouchEvent(event);

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (isWithinThumb(event)) {
                isDragging = true;
                return super.onTouchEvent(event);
            } else {
                return true;
            }

        case MotionEvent.ACTION_UP:
            isDragging = false;
            if (isWithinThumb(event)) {
                return super.onTouchEvent(event);
            } else {
                final Rect r = getThumb().getBounds();
                increment((int)event.getX() - (r.left + r.right) / 2);
                return true;
            }

        case MotionEvent.ACTION_MOVE:
            if (!isDragging) return true;
            break;

        case MotionEvent.ACTION_CANCEL:
            isDragging = false;
            break;
        }

        return super.onTouchEvent(event);
    }
}
4 голосов
/ 20 марта 2012

Переопределить OnTouchListener для панели поиска и обрабатывать движение на большом пальце только тогда, когда MotionEvent является событием перемещения.

event.getAction() == MotionEvent.ACTION_MOVE

Обновление: 1

Нечто подобное будет работать, но суть в том, что даже если пользователь перемещает большой палец на 2 единицы, перемещается панель поиска.И вы действительно не должны останавливать это поведение, так как это испортит панель поиска.

seekBar.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    Log.d(TAG, "Moved , process data, Moved to :" + seekBar.getProgress());
                    seekBar.setProgress(seekBar.getProgress());
                    return false;
                }
                Log.d(TAG, "Touched , Progress :" + seekBar.getProgress());
                return true;
            }
        });
0 голосов
/ 08 августа 2016

Решение Рави великолепно, я провел рефакторинг ниже:

Две цели:

  1. разрешить функцию getThumb(), которая может использоваться только над проблемами API 16.
  2. нажатие на панель поиска не вызовет onStopTrackingTouch(), а только перетянет большой палец

Это мой код:

public class NoSkipSeekBar extends SeekBar {

    Drawable mThumb;
    @Override
    public void setThumb(Drawable thumb) {
        super.setThumb(thumb);
        mThumb = thumb;
    }
    public Drawable getSeekBarThumb() {
        return mThumb;
    }

    public NoSkipSeekBar(Context context) {
        super(context);
    }

    public NoSkipSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoSkipSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private boolean isDragging;
    private boolean isStart = false;
    private boolean isWithinThumb(MotionEvent event) {
        Rect rect = getSeekBarThumb().getBounds();//increate the thumb invoke area
        Rect rect1 = new Rect();
        rect1.left = rect.left - 50;
        rect1.right = rect.right + 50;
        rect1.bottom = rect.bottom + 50;
        return rect1.contains((int)event.getX(), (int)event.getY());
    }

    private void increment(int direction) {
        if (direction != 0) {
            final KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN,
                    direction < 0 ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT);
            onKeyDown(key.getKeyCode(), key);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled() || getSeekBarThumb() == null) return super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (isWithinThumb(event)) {
                    isDragging = true;
                    isStart = true;
                    return super.onTouchEvent(event);
                } else {
                    return true;
                }

            case MotionEvent.ACTION_UP:
                isDragging = false;
                if(isStart){
                    isStart = false;
                    return super.onTouchEvent(event);
                }
                if (isWithinThumb(event)) {
                    return super.onTouchEvent(event);
                } else {
                    //final Rect r = getThumb().getBounds();
                    //increment((int)event.getX() - (r.left + r.right) / 2);
                    return true;
                }
            case MotionEvent.ACTION_MOVE:
                if (!isDragging) return true;
                break;

            case MotionEvent.ACTION_CANCEL:
                isDragging = false;
                break;
        }

        return super.onTouchEvent(event);
    }
}
0 голосов
/ 20 марта 2012

Вы смотрели на это:

Действительно похожая тема, которая должна помочь вам решить ваш вопрос:

Большой палец SeekBar появляется только при касании

Удачи

...