如何拖动覆盖在相机预览顶部的图像
How to drag an image overlaid on top of a Camera Preview
我在相机预览上叠加了一张图像。单击按钮后,相机预览在 FrameLayout 内开始。单击另一个按钮时,图像也会叠加在相机预览上。
这是下面的代码 --
主要活动:
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;
}
我的问题是: 如何在触摸时拖动这个特定的图像?触摸相机预览应该什么都不做,只有触摸图像我才能拖动它。
提前致谢!
经过多次尝试和敲打我的脑袋,我终于解决了这个问题并开始工作!我可以将图像拖到相机预览上。 :)
现在我不打算使用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;
}
}
我在相机预览上叠加了一张图像。单击按钮后,相机预览在 FrameLayout 内开始。单击另一个按钮时,图像也会叠加在相机预览上。
这是下面的代码 --
主要活动:
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;
}
我的问题是: 如何在触摸时拖动这个特定的图像?触摸相机预览应该什么都不做,只有触摸图像我才能拖动它。
提前致谢!
经过多次尝试和敲打我的脑袋,我终于解决了这个问题并开始工作!我可以将图像拖到相机预览上。 :)
现在我不打算使用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;
}
}