Задать вопрос

Прекращение движения MotionEvent.ACTION_MOVE по оси У (получаю ACTION_CANCEL). Почему?

В Activity есть текст и изображения. Если нажать на любое изображение, откроется DialogFragment (с одним элементом из ListView), в котором находится большое изображение, которое можно перемещать и масштабировать (пинч). По оси Х проблем нет, но при перемещении по оси У - движение "обрывается", т.е. продвигается только на короткое расстояние и срабатывает ACTION_CANCEL. Почему так? Буду рад любым идеям и предположениям, ибо сам зашел в многодневный тупик...

public class MyBaseAdapter_pic extends BaseAdapter implements View.OnTouchListener {
    private ArrayList<OneCoin_pic> arr_nominals;
    private Context ctx;
    LayoutInflater layoutInflater;
    ImageView imageView;
    final String LOG_TAG = "myLogs";
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;
    private PointF startPoint = new PointF();
    private PointF midPoint = new PointF();
    private float oldDist = 1f;

    public MyBaseAdapter_pic(ArrayList<OneCoin_pic> arr_nominals, Context ctx) {
        this.arr_nominals = arr_nominals;
        this.ctx = ctx;
        layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return arr_nominals.size();
    }

    @Override
    public Object getItem(int position) {
        return arr_nominals.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View my_view = convertView;
        if (my_view == null){
            my_view = layoutInflater.inflate(R.layout.list_item_zoom, parent, false);
            imageView  = (ImageView) my_view.findViewById(R.id.big_pic);
            imageView.setOnTouchListener(this);

            final View view = my_view.findViewById(R.id.hint);
            Animation a = new AlphaAnimation(1.00f, 0.00f);
            a.setDuration(2000);                                            
            a.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    // TODO Auto-generated method stub
                }
                public void onAnimationRepeat(Animation animation) {
                    // TODO Auto-generated method stub
                }
                public void onAnimationEnd(Animation animation) {
                    view.setVisibility(View.GONE);
                }
            });
            view.startAnimation(a);
        }
        OneCoin_pic coin = get_one_coin_object(position);

        int resID = ctx.getResources().getIdentifier(coin.getBigPic(), "drawable", ctx.getPackageName());
        imageView.setImageResource(resID);

        return my_view;
    }

    private OneCoin_pic get_one_coin_object(int position){
        OneCoin_pic obj = arr_nominals.get(position);
        return obj;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        ImageView view = (ImageView) v;
        dumpEvent(event);
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                startPoint.set(event.getX(), event.getY());
                Log.d(LOG_TAG, "mode=DRAG");
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                Log.d(LOG_TAG, "oldDist=" + oldDist);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(midPoint, event);
                    mode = ZOOM;
                    Log.d(LOG_TAG, "mode=ZOOM");
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                Log.d(LOG_TAG, "mode=NONE");
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - startPoint.x, event.getY()
                            - startPoint.y);
                } else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    Log.d(LOG_TAG, "newDist=" + newDist);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }
                }
                break;
        }

        view.setImageMatrix(matrix);
        return true;
    }

    private void dumpEvent(MotionEvent event) {
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
        StringBuilder sb = new StringBuilder();
        int action = event.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        sb.append("event ACTION_").append(names[actionCode]);
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                || actionCode == MotionEvent.ACTION_POINTER_UP) {
            sb.append("(pid ").append(
                    action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
            sb.append(")");
        }
        sb.append("[");
        for (int i = 0; i < event.getPointerCount(); i++) {
            sb.append("#").append(i);
            sb.append("(pid ").append(event.getPointerId(i));
            sb.append(")=").append((int) event.getX(i));
            sb.append(",").append((int) event.getY(i));
            if (i + 1 < event.getPointerCount())
                sb.append(";");
        }
        sb.append("]");
        Log.d(LOG_TAG, sb.toString());
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float)Math.sqrt(x * x + y * y);
    }

    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
}


dialog_zoom.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:layout_gravity="center"
              android:background="@drawable/zz_bg_oval_blue_light"
              android:padding="5dp">
    <ListView
        android:id="@+id/zoom_listview"
        android:layout_width="300dp"
        android:layout_height="300dp">
    </ListView>
</LinearLayout>


list_item_zoom:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="300dp"
                android:layout_height="300dp"
                android:layout_gravity="center"
                android:orientation="vertical">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/big_pic"
            android:layout_centerInParent="true"
            android:scaleType="matrix"/>
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/hint"
            android:src="@drawable/z_a_zooming"
            android:visibility="visible"
            android:layout_centerInParent="true"/>
</RelativeLayout>


Log (перемещение по оси Х):
D/myLogs: mode=DRAG
D/myLogs: event ACTION_MOVE[#0(pid 0)=125,288]
D/myLogs: event ACTION_MOVE[#0(pid 0)=125,286]
D/myLogs: event ACTION_MOVE[#0(pid 0)=128,287]
D/myLogs: event ACTION_MOVE[#0(pid 0)=129,289]
D/myLogs: event ACTION_UP[#0(pid 0)=129,289]
D/myLogs: mode=NONE


Log (перемещение по оси У):
D/myLogs: mode=DRAG
D/myLogs: event ACTION_MOVE[#0(pid 0)=277,338]
D/myLogs: event ACTION_CANCEL[#0(pid 0)=280,328]
  • Вопрос задан
  • 517 просмотров
Подписаться 1 Оценить 2 комментария
Решения вопроса 1
@xox_ua Автор вопроса
Дотумкал. Проблема была в перехватывании касания родителем. Решение проблемы:
1. Добавить в case MotionEvent.ACTION_DOWN:
v.getParent().requestDisallowInterceptTouchEvent(true);
2. Добавить в case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы