如何拖动覆盖在“相机预览”顶部的图像

时间:2016-01-28 09:05:40

标签: android canvas android-camera surfaceview ontouchevent

我在相机预览的顶部覆盖了一个图像。单击按钮时,相机预览在FrameLayout内部开始。单击另一个按钮时,图像也会叠加在相机预览上。

以下代码 -

MainActivity:

public class MainActivity extends AppCompatActivity {

public Camera mCamera;
public CameraPreview mCameraPreView;
Bitmap bitmap;
FrameLayout frameLayout;
DrawOnTop drawOnTop;
FrameLayout.LayoutParams layoutParams;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    frameLayout = (FrameLayout)findViewById(R.id.camera_preview);
    drawOnTop = null;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public void onCamViewButtonClicked (View view)
{
    mCamera = getCameraInstance();
    mCameraPreView = new CameraPreview(this,mCamera);
    frameLayout.addView(mCameraPreView);
}

public Camera getCameraInstance()
{
    Camera camera = null;
    try
    {
        camera = Camera.open();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return camera;
}

public void onOverlayImageButtonClicked(View view)
{
    if(mCameraPreView == null)
    {
        Toast.makeText(getApplicationContext(),"Preview is not available now!",Toast.LENGTH_LONG).show();
        return;
    }
    else {
        if(drawOnTop != null)
        {
            frameLayout.removeView(drawOnTop);
            drawOnTop = null;
        }
        else
        {
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.internetothings);
            drawOnTop = new DrawOnTop(this, bitmap);
            layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
            frameLayout.addView(drawOnTop, layoutParams);
            Toast.makeText(getApplicationContext(),"Click again to remove!",Toast.LENGTH_LONG).show();
        }
    }
}
}

CameraPreview.java:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private SurfaceHolder surfaceHolder;
private android.hardware.Camera camera;

public CameraPreview (Context context, android.hardware.Camera cam)
{
    super(context);
    camera = cam;

    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
}

public void surfaceCreated(SurfaceHolder holder)
{
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (IOException ioe)
    {
        ioe.printStackTrace();
    }
}

public void surfaceDestroyed(SurfaceHolder holder)
{
    camera.stopPreview();
    camera.release();
    camera = null;
}

public void surfaceChanged(SurfaceHolder holder,int format,int w,int h)
{
    if(surfaceHolder.getSurface() == null)
    {
        return;
    }

    camera.stopPreview();

    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (IOException ioe)
    {
        ioe.printStackTrace();
    }
}
}

DrawOnTop.java:

public class DrawOnTop extends View {

Bitmap bitmap;
private int mActivePointerId = 9999;
public static float mLastTouchX,mLastTouchY,mPosX,mPosY;
ImageView view = null;

public DrawOnTop (Context context, Bitmap bmp)
{
    super(context);
    bitmap = bmp;
}

protected void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
    canvas.drawBitmap(bitmap, canvas.getWidth() / 2, canvas.getHeight() / 2, null);
}
}

我已经使用下面的代码进行拖动,但即使我触摸相机预览也会被触发,这是我不想要的。

public boolean onTouchEvent(MotionEvent event)
{

    int action = event.getActionMasked();

    switch (action)
    {
        case MotionEvent.ACTION_DOWN:
        {
            int pointerIndex = event.getActionIndex();
            final float x = MotionEventCompat.getX(event, pointerIndex);
            final float y = MotionEventCompat.getY(event, pointerIndex);
            mLastTouchX = x;
            mLastTouchY = y;
            mActivePointerId = event.getPointerId(pointerIndex);
            break;
        }

        case MotionEvent.ACTION_MOVE:
        {
            final int pointerIndex =
                    MotionEventCompat.findPointerIndex(event, mActivePointerId);

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

            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            invalidate();

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

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

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

        case MotionEvent.ACTION_POINTER_UP:
        {

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

            if (pointerId == mActivePointerId) {
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = MotionEventCompat.getX(event, newPointerIndex);
                mLastTouchY = MotionEventCompat.getY(event, newPointerIndex);
                mActivePointerId = MotionEventCompat.getPointerId(event, newPointerIndex);
            }
            break;
        }
    }
    return true;
}

我的问题是:如何在触摸时拖动此特定图像?触摸相机预览应该什么都不做,只有触摸图像我才能拖动它。

提前致谢!

1 个答案:

答案 0 :(得分:0)

经过几次试验和敲打我的脑袋后,我终于解决了这个问题,并且正常工作!我可以将图像拖到相机预览上。 :)

现在我不打算使用 DrawOnTop.java 。取而代之的是,我在 FrameLayout 下创建了一个 ImageView ,并使用所需的图像填充了相同的 ImageView 。然后我在 ImageView 上添加了 OnTouchListener

以下代码 -

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

public Camera mCamera;
public CameraPreview mCameraPreView;
FrameLayout frameLayout;
ImageView imageView;
float mLastTouchX,mLastTouchY,mPosX,mPosY;
Boolean clicked;
Bitmap bitmap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    frameLayout = (FrameLayout)findViewById(R.id.camera_preview);
    imageView = new ImageView(this);
    ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,ActionBar.LayoutParams.WRAP_CONTENT);
    layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
    imageView.setLayoutParams(layoutParams);
    clicked = false;
}

public void onCamViewButtonClicked (View view)
{
    mCamera = getCameraInstance();
    mCameraPreView = new CameraPreview(this,mCamera);
    frameLayout.addView(mCameraPreView);
}

public Camera getCameraInstance()
{
    Camera camera = null;
    try
    {
        camera = Camera.open();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return camera;
}

public void onOverlayImageButtonClicked(View view)
{
    if(mCameraPreView == null)
    {
        Toast.makeText(getApplicationContext(),"Preview is not available now!",Toast.LENGTH_LONG).show();
        return;
    }
    else
    {
        if(clicked)
        {
            imageView.setImageDrawable(null);
            clicked = false;
        }
        else
        {
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.internetothings);
            imageView.setImageBitmap(bitmap);
            frameLayout.addView(imageView);
            Toast.makeText(getApplicationContext(),"Click again to remove!",Toast.LENGTH_LONG).show();
            imageView.setOnTouchListener(this);
            clicked = true;
        }
    }
}

public boolean onTouch(View view, MotionEvent event)
{
    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            final float x = event.getX();
            final float y = event.getY();

            // Remember where we started
            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final float x = event.getX();
            final float y = event.getY();

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

            // Move the object
            mPosX += dx;
            mPosY += dy;

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

            imageView.setTranslationX(mPosX);
            imageView.setTranslationY(mPosY);

            break;
        }

        default:
            break;
    }
    return true;
}
}