android - 自定义View不随手势移动

标签 android android-view android-gesture

我最近实现了 Android 开发者网站上提供的拖动和缩放代码 FOUND HERE

我遇到的问题是关于将 View 添加到布局后移动 View 的能力。图像可通过手势缩放,但不可移动。

如果有帮助,这个 View 将被添加到 Fragment 中的 FrameLayout。

有没有人遇到过在自定义 View 中实现这个 Android 示例的类似问题?或者有人可以告诉我我错过了什么,我无法移动我正在添加的 View 。

public class CustomImageView extends View {

private static final int INVALID_POINTER_ID = 0;
Drawable _drawable;
// private static readonly int InvalidPointerId = -1;
// private int _activePointerId = InvalidPointerId;

private float _posX;
private float _posY;
private float mScaleFactor = 1.0f;
private int mActivePointerId = INVALID_POINTER_ID;

// gesture listeners
private ScaleGestureDetector mScaleDetector;
private float mLastTouchX;
private float mLastTouchY;
private float mPosY;
private float mPosX;

public CustomImageView(Context context, int resourceId) {
    super(context, null, 0);

    _drawable = getResources().getDrawable(resourceId);
    _drawable.setBounds(0, 0, 200, 200);
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    // TODO Auto-generated constructor stub
}

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    canvas.translate(_posX, _posY);
    canvas.scale(mScaleFactor, mScaleFactor);
    _drawable.draw(canvas);
    canvas.restore();
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Let the ScaleGestureDetector inspect all events.
    mScaleDetector.onTouchEvent(ev);

    final int action = MotionEventCompat.getActionMasked(ev);

    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        final int pointerIndex = MotionEventCompat.getActionIndex(ev);
        final float x = MotionEventCompat.getX(ev, pointerIndex);
        final float y = MotionEventCompat.getY(ev, pointerIndex);

        // Remember where we started (for dragging)
        mLastTouchX = x;
        mLastTouchY = y;
        // Save the ID of this pointer (for dragging)
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        // Find the index of the active pointer and fetch its position
        final int pointerIndex = MotionEventCompat.findPointerIndex(ev,
                mActivePointerId);

        final float x = MotionEventCompat.getX(ev, pointerIndex);
        final float y = MotionEventCompat.getY(ev, pointerIndex);

        // Calculate the distance moved
        final float dx = x - mLastTouchX;
        final float dy = y - mLastTouchY;

        mPosX += dx;
        mPosY += dy;

        invalidate();

        // Remember this touch position for the next move event
        mLastTouchX = x;
        mLastTouchY = y;

        break;
    }

    case MotionEvent.ACTION_UP: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {

        final int pointerIndex = MotionEventCompat.getActionIndex(ev);
        final int pointerId = MotionEventCompat.getPointerId(ev,
                pointerIndex);

        if (pointerId == mActivePointerId) {
            // This was our active pointer going up. Choose a new
            // active pointer and adjust accordingly.
            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
            mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
            mActivePointerId = MotionEventCompat.getPointerId(ev,
                    newPointerIndex);
        }
        break;
    }
    }
    return true;
}

private class ScaleListener extends
        ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));

        invalidate();
        return true;
    }
}

这是 XML,我要将 View 添加到的 root_layout 是一个 FrameLayout

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="@dimen/ab_height"
        android:background="@color/red" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <ImageButton
                android:id="@+id/btn_Back"
                android:layout_width="@dimen/width"
                android:layout_height="fill_parent"
                android:background="@color/red"
                android:contentDescription="@string/desc"
                android:src="@drawable/ic_navigation_back" />

            <LinearLayout
                android:layout_width="@dimen/dim_1"
                android:layout_height="fill_parent"
                android:background="@color/red" >
            </LinearLayout>

            <TextView
                android:id="@+id/text_name"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="1"
                android:ellipsize="end"
                android:gravity="center"
                android:singleLine="true"
                android:tag="bold"
                android:text="Pixagram"
                android:textColor="@color/white"
                android:textSize="@dimen/tex_size_xxxlarge"
                android:textStyle="bold" />

            <LinearLayout
                android:layout_width="@dimen/dim_1"
                android:layout_height="fill_parent"
                android:background="@color/red" >
            </LinearLayout>

            <ImageButton
                android:id="@+id/btn_Accept"
                android:layout_width="@dimen/width"
                android:layout_height="fill_parent"
                android:background="@color/red"
                android:contentDescription="@string/desc"
                android:src="@drawable/ic_navigation_accept" />
        </LinearLayout>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="@dimen/dim_1"
        android:background="@color/red" >
    </LinearLayout>

    <FrameLayout
        android:id="@+id/root_layout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/imageViewEdit"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:src="@drawable/abc_ab_solid_dark_holo" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:background="@color/red"
        android:orientation="horizontal" >

        <HorizontalScrollView
            android:id="@+id/horizontalScrollView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="bottom"
            android:gravity="bottom"
            android:background="@color/transparent" >

            <LinearLayout
                android:id="@+id/linearLayout1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="horizontal"
                android:background="@color/transparent" >

                <ImageButton
                    android:id="@+id/imageButton1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_ic_clear" />

                <ImageButton
                    android:id="@+id/imageButton2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_tab_selected_pressed_holo" />

                <ImageButton
                    android:id="@+id/imageButton3"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_ic_clear" />

                <ImageButton
                    android:id="@+id/imageButton4"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_tab_selected_pressed_holo" />

                <ImageButton
                    android:id="@+id/imageButton5"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_ic_clear" />

                <ImageButton
                    android:id="@+id/imageButton6"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_tab_selected_pressed_holo" />

                <ImageButton
                    android:id="@+id/imageButton7"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_ic_clear" />

                <ImageButton
                    android:id="@+id/imageButton8"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_tab_selected_pressed_holo" />

                <ImageButton
                    android:id="@+id/imageButton9"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_ic_clear" />

                <ImageButton
                    android:id="@+id/imageButton10"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/abc_tab_selected_pressed_holo" />
            </LinearLayout>
        </HorizontalScrollView>
    </LinearLayout>
</LinearLayout>

这似乎表明 ACTION_MOVE 没有被调用

    09-23 23:14:46.310: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch Down
09-23 23:14:46.350: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch UP
09-23 23:14:47.300: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch Down
09-23 23:14:47.790: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch UP
09-23 23:14:48.000: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch Down
09-23 23:14:48.030: I/ViewRootImpl(24235): ViewRoot's Touch Event :261
09-23 23:14:48.670: I/ViewRootImpl(24235): ViewRoot's Touch Event :6
09-23 23:14:48.710: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch UP
09-23 23:14:48.980: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch Down
09-23 23:14:49.320: I/ViewRootImpl(24235): ViewRoot's Touch Event : Touch UP

最佳答案

虽然我没有仔细研究你的所有代码,但在你的 onDraw() 方法中,你似乎正在通过 _posX 进行翻译_posY,但您不会在手势处理的任何地方更改这些。尝试在 onDraw() 中使用 mPosXmPosY

关于android - 自定义View不随手势移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26001426/

相关文章:

Android 如何在没有 onDown true 的情况下在 LinearLayout 上添加滑动手势

android - 如何确定用户滑动是否从 Android 屏幕的底部边缘开始?

android - 具有 Google session 和帐户选择器的移动应用浏览器的行为

android - 未通知多个 BluetoothGattCharacteristic

android - Twitter 没有获得访问 token 和访问 token secret Android

java - setOnKeyListener onKey 不适用于 Eclipse/ADT Android 虚拟设备 - Nexus One

android - 如何在布局中滑动(推) subview ?

安卓自定义 View : Set canvas size to wrap bitmap

android - selectableItemBackgroundBorderless 小部件上的可选圆圈被截断

android - 在 Android Canvas 上应用缩放效果后缩放位置错误