I am developing an android app after image view is rotated
image view not fitting the entire screen how can I fit the entire
screen so that ImageView covers the entire screen
`
below my MainActivity.java where I have implemented image rotation logic in my java class
below my MainActivity.java where I have implemented image rotation logic in my java class
public class MainActivity extends AppCompatActivity {
float scaleDiff;
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
private float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;
#BindView(R.id.show_image)
ImageView mImageView;
private boolean mMoved = false;
private PhotoViewAttacher mViewAttacher;
private float mScaleX = 0, mScaleY = 0;
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mScaleX = mImageView.getScaleX();
mScaleY = mImageView.getScaleY();
final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(getScreenWidth(), getScreenHeight());
mImageView.setLayoutParams(layoutParams);
mImageView.setOnTouchListener(new View.OnTouchListener() {
RelativeLayout.LayoutParams params;
int startWidth;
int startHeight;
float dx = 0, dy = 0, x = 0, y = 0;
float angle = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
final ImageView view = (ImageView) v;
((BitmapDrawable) view.getDrawable()).setAntiAlias(true);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
params = (RelativeLayout.LayoutParams) view.getLayoutParams();
startWidth = params.width;
startHeight = params.height;
dx = event.getRawX() - params.leftMargin;
dy = event.getRawY() - params.topMargin;
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
mode = ZOOM;
}
d = rotation(event);
break;
case MotionEvent.ACTION_UP:
if (view.getScaleX() <= mScaleX || view.getScaleY() <= mScaleY) {
view.setScaleX(mScaleX);
view.setScaleY(mScaleY);
params.leftMargin = 0;
params.topMargin = 0;
params.rightMargin = 0;
params.bottomMargin = 0;
}
if (mMoved || view.getWidth() != getScreenWidth() || view.getHeight() != getScreenHeight()) {
params.leftMargin = 0;
params.topMargin = 0;
params.rightMargin = 0;
params.bottomMargin = 0;
mMoved = false;
}
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
view.setLayoutParams(params);
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
mMoved = true;
x = event.getRawX();
y = event.getRawY();
params.leftMargin = (int) (x - dx);
params.topMargin = (int) (y - dy);
params.rightMargin = 0;
params.bottomMargin = 0;
params.rightMargin = params.leftMargin + (5 * params.width);
params.bottomMargin = params.topMargin + (10 * params.height);
view.setLayoutParams(params);
}
else if (mode == ZOOM) {
if (event.getPointerCount() == 2) {
newRot = rotation(event);
float r = newRot - d;
angle = r;
x = event.getRawX();
y = event.getRawY();
float newDist = spacing(event);
if (newDist > 10f) {
float scale = newDist / oldDist * view.getScaleX();
if (scale > 0.6) {
scaleDiff = scale;
view.setScaleX(scale);
view.setScaleY(scale);
}
}
view.animate().rotationBy(angle).setDuration(0).setInterpolator(new LinearInterpolator()).start();
x = event.getRawX();
y = event.getRawY();
params.leftMargin = (int) ((x - dx) + scaleDiff);
params.topMargin = (int) ((y - dy) + scaleDiff);
params.rightMargin = 0;
params.bottomMargin = 0;
params.rightMargin = params.leftMargin + (5 * params.width);
params.bottomMargin = params.topMargin + (10 * params.height);
view.setLayoutParams(params);
}
}
break;
}
return true;
}
});
}
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 float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
public static int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
public static int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
}
below activity_main.xml
<?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="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<ImageView
android:id="#+id/show_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="#drawable/abstract_image"
android:transitionName="image_transition" />
</RelativeLayout>
Use this in imageView
<ImageView
android:id="#+id/show_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:src="#drawable/abstract_image"
android:transitionName="image_transition" />
java file
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap myImg = BitmapFactory.decodeResource(getResources(),
R.drawable.abstract_image);
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0,
myImg.getWidth(), myImg.getHeight(),
matrix, true);
imageView.setImageBitmap(rotated);
}
});
using this code image is rotate properly now you can adjust in your code according to your need
I am developing an android application, in my application I dynamically create some ImageViews and set that ImageViews in to a LinearLayout.So I want to drag each image in the layout independently. I wrote a code to drag images. But it is not working properly, when i drag one image all other images in the layout are also moved. I wanted to move each image independently. So any one know it please help me.
Here is my setCanvasImage() method
public void setCanvasImage() {
final int imgCount = dbobj.getFromTemp();
canvasImage = new ImageView[imgCount];
imglayout = (LinearLayout) findViewById(R.id.canvas);
final String[] strImage = dbobj.getdImage();
imglayout.removeAllViews();
for (int i = 0; i < imgCount; i++) {
int posLeft = 50;
int posTop = 50;
canvasImage[i] = new ImageView(this);
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
int imgWidth = 150;
int imgHeight = 150;
LinearLayout.LayoutParams paramss = new LinearLayout.LayoutParams(imgWidth, imgHeight);
canvasImage[i].setLayoutParams(paramss);
canvasImage[i].setScaleType(ScaleType.FIT_XY);
canvasImage[i].setPadding(posLeft, posTop, 0, 0);
canvasImage[i].setTag(strImage[i]);
setImage(strImage[i], canvasImage[i]);
imglayout.addView(canvasImage[i]);
} else {
int imgWidth = 100;
int imgHeight = 100;
LinearLayout.LayoutParams paramss = new LinearLayout.LayoutParams(imgWidth, imgHeight);
canvasImage[i].setLayoutParams(paramss);
canvasImage[i].setPadding(posLeft, posTop, 0, 0);
canvasImage[i].setTag(strImage[i]);
setImage(strImage[i], canvasImage[i]);
imglayout.addView(canvasImage[i]);
}
}
//}
for (int i = 0; i < imgCount; i++) {
canvasImage[i].setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
final int x = (int) motionEvent.getRawX();
final int y = (int) motionEvent.getRawY();
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
LinearLayout.LayoutParams lparams = (LinearLayout.LayoutParams) view.getLayoutParams();
xDelta = x - lparams.leftMargin;
yDelta = y - lparams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = x - xDelta;
layoutParams.topMargin = y - yDelta;
layoutParams.rightMargin = 0;
layoutParams.bottomMargin = 0;
view.setLayoutParams(layoutParams);
break;
}
mainLayout.invalidate();
return true;
}
});
}
}
I'm trying to make a view invisible when it's dragged to a certain Y coordinate on the screen.
This is what I got now:
private final class dragTouchListener implements View.OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
ContentFrameLayout.LayoutParams lParams = (ContentFrameLayout.LayoutParams) v.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
trash_image.setVisibility(View.INVISIBLE);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
trash_image.setVisibility(View.VISIBLE);
ContentFrameLayout.LayoutParams layoutParams = (ContentFrameLayout.LayoutParams) v.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
v.setLayoutParams(layoutParams);
if(v.getY() > trash_image.getY()){
v.setVisibility(View.INVISIBLE);
}
break;
}
contentView.invalidate();
return true;
}
}
So basically what I've tried here is simply an if statement to check if the Y position of the view has "passed" that of another ImageView placed on the upper part of the screen. This however result in becoming invisible as soon as I touch the view to be dragged, no matter where on the screen it's located. So it's far from accurate, or wrong all together.
As requested in comment, a suggestion (do note I had to change it, since this is for a client program, so I didnt test it again):
First, discover SCREEN_DENSITY
private static float SCREEN_DENSITY = getResources().getDisplayMetrics().density;
The onTouch function:
public boolean onTouch(final View v, MotionEvent event) {
case MotionEvent.ACTION_DOWN:
mainFinger = new Point(
(int) (event.getRawX() / SCREEN_DENSITY),
(int) (event.getRawY() / SCREEN_DENSITY)
);
break;
case MotionEvent.ACTION_MOVE:
movFrame(
(FrameLayout) v,
(int) (event.getRawX() / SCREEN_DENSITY),
(int) (event.getRawY() / SCREEN_DENSITY)
);
}
movFrame function:
private void movFrame(FrameLayout v, int movX, int movY) {
MyObject p = (MyObject ) v.getTag();
int[] x, y, h, w;
x = p.x;
y = p.y;
h = p.h;
w = p.w;
x = p.x + movX - mainFinger.x;
mainFinger.x = movX;
if (x + w > p.parent.w) {
x = p.parent.w - w;
}
if (x < 0) {
x = 0;
}
y = p.y + movY - mainFinger.y;
mainFinger.y = movY;
if (y + h > p.parent.h) {
y = p.parent.h - h;
}
if (y < 0) {
y = 0;
}
p.updateMyObject(x, y, h, w);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
(int) ((p.w * SCREEN_DENSITY) + 0.5),
(int) ((p.h * SCREEN_DENSITY) + 0.5)
);
params.leftMargin = (int) ((p.x * SCREEN_DENSITY) + 0.5);
params.topMargin = (int) ((p.y * SCREEN_DENSITY) + 0.5);
v.setLayoutParams(params);
}
I have an app where I draw text on bitmap using the position specified by the user. When I ask canvas to draw the text using the x,y coordinates , the text draws in wrong place.
Where I position text Where it draws after I save
My code to save the image
private void drawText(Bitmap bitmap, TextView mText) {
try {
Resources resources = getResources();
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setTextSize(text.getTextSize());
Rect bounds = new Rect();
paint.getTextBounds(mText.getText().toString(), 0, mText.length(), bounds);
canvas.drawText(mText.getText().toString(), text.getX() , text.getY(), paint);
ImageView im = (ImageView) findViewById(R.id.imageView);
im.setImageBitmap(bitmap);
saveBitmap(bitmap);
} catch (Exception e) {
// TODO: handle exception
}
}
Code to drag textview
textView.setOnTouchListener(new View.OnTouchListener() {
int initialX = 0;
int initialY = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
initialX = (int) event.getX();
initialY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int currentX = (int) event.getX();
int currentY = (int) event.getY();
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) textView.getLayoutParams();
int left = lp.leftMargin + (currentX - initialX);
int top = lp.topMargin + (currentY - initialY);
int right = lp.rightMargin - (currentX - initialX);
int bottom = lp.bottomMargin - (currentY - initialY);
lp.rightMargin = right;
lp.leftMargin = left;
lp.bottomMargin = bottom;
lp.topMargin = top;
textView.setLayoutParams(lp);
break;
default:
break;
}
return true;
}
});
findViewById(R.id.save).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawText(getBitmap(), textView);
}
});
I am developing an app which has feature that resizing and rotating the imageview by dragging its bottom right corner button.
I saw one app which has feature that if we drag the bottom right corner button diagonally imageview size had resized or else if we drag the button left or right side direction imageview had rotated as per direction. I wish to implement this feature in my app
I am struggling to implement single finger rotation as well as resizing the imageview.
Please guide me in right way.
I am trying this code, and try to apply zoom and rotate but not able to do please help me.
belove code to do zoom and rotate finger base action.
public class ScaleActivity extends Activity {
ViewGroup lLayout;
static ImageView img, backgrndImg;
Canvas mCanvas;
float d;
private float mAspectQuotient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lLayout = (FrameLayout) findViewById(R.id.lLayout);
final CropView cv = new CropView(this);
lLayout.addView(cv);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class CropView extends ImageView {
private static final int SELECTION_RECT_PAINT_COLOR = 0xFF000000;
private static final int SELECTION_RECT_FILL_COLOR = 0x70FFFFFF;
private static final int TOUCH_TOLERANCE = 25;
private static final int xInc = 25;
private static final int yInc = 25;
Paint paint = new Paint();
private int initial_size = 200;
private Point leftTop, rightBottom, center, previous, currentPoint,
rectPos;
private Paint fillPaint;
private Paint rectPaint;
protected Rect selection, dest;
private boolean isAffectedBottom = false;
Bitmap bitmap, backgroundBitmap;
Rect rectf;
Rect knobRect;
private Context mContext;
int width, height;
private Matrix matrix = new Matrix();
Bitmap resizedBitmap;
// Adding parent class constructors
public CropView(Context context) {
super(context);
mContext = context;
backgroundBitmap = BitmapFactory.decodeResource(getContext()
.getResources(), R.drawable.toast_bkgrd);
bitmap = BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.aviary_adjust_knob);
rectPaint = new Paint();
rectPaint.setStyle(Style.STROKE);
rectPaint.setColor(SELECTION_RECT_PAINT_COLOR);
fillPaint = new Paint();
fillPaint.setStyle(Style.FILL);
fillPaint.setColor(SELECTION_RECT_FILL_COLOR);
currentPoint = new Point(getWidth() / 2, getHeight() / 2);
width = backgroundBitmap.getWidth();
height = backgroundBitmap.getHeight();
initCropView();
}
public CropView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initCropView();
}
public CropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initCropView();
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCanvas = canvas;
if (leftTop.equals(0, 0))
resetPoints();
mCanvas.save();
resizedBitmap = Bitmap.createBitmap(backgroundBitmap, 0, 0,
backgroundBitmap.getWidth(), backgroundBitmap.getHeight(),
matrix, true);
// mCanvas.drawBitmap(backgroundBitmap, matrix, rectPaint);
mCanvas.drawBitmap(resizedBitmap, null, selection, rectPaint);
mCanvas.drawBitmap(bitmap, selection.right - 25,
selection.bottom - 25, null);
rectPos.set(selection.left, selection.top);
mCanvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
touchDown((int) event.getX(), (int) event.getY());
previous.set((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_MOVE:
touchMove((int) event.getX(), (int) event.getY());
if (isActionInsideRectangle(event.getX(), event.getY())
&& !isAffectedBottom) {
drag((int) event.getX(), (int) event.getY());
invalidate(); // redraw rectangle
previous.set((int) event.getX(), (int) event.getY());
}
previous.set((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_UP:
touchUp((int) event.getX(), (int) event.getY());
previous = new Point();
break;
}
return true;
}
private void initCropView() {
paint.setColor(Color.WHITE);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(5);
leftTop = new Point();
rightBottom = new Point();
center = new Point();
previous = new Point();
rectPos = new Point();
}
public void resetPoints() {
center.set(getWidth() / 2, getHeight() / 2);
leftTop.set((getWidth() - initial_size) / 2,
(getHeight() - initial_size) / 2);
rightBottom.set(leftTop.x + initial_size, leftTop.y + initial_size);
selection = new Rect(leftTop.x, leftTop.y, rightBottom.x,
rightBottom.y);
knobRect = new Rect(selection.right, selection.bottom,
bitmap.getWidth(), bitmap.getHeight());
dest = selection;
}
private boolean isActionInsideRectangle(float x, float y) {
int buffer = 10;
return (x >= (selection.left) && x <= (selection.right)
&& y >= (selection.top) && y <= (selection.bottom)) ? true
: false;
}
void touchDown(int x, int y) {
System.out.println("selection " + selection);
int dx = (previous.x - x) / 2;
int dy = (previous.y - y) / 2;
// d= rotation(dx,dy);
currentPoint.set(x, y);
if (pointsAreClose(x, y, selection.right, selection.bottom)) {
isAffectedBottom = true;
System.out.println("isAffectedBottom " + isAffectedBottom);
}
}
void touchMove(int x, int y) {
currentPoint.set(x, y);
if (isAffectedBottom) {
int dx = (previous.x - x) / 2;
int dy = (previous.y - y) / 2;
double startAngle = getAngle(previous.x, previous.y);
double currentAngle = getAngle(x, y);
matrix.postRotate((float) (startAngle - currentAngle),
selection.width() / 2.0f, selection.height() / 2.0f);
// selection.inset(dx, dy);
invalidate();
}
}
void touchUp(int x, int y) {
currentPoint.set(x, y);
isAffectedBottom = false;
}
private boolean pointsAreClose(float x1, float y1, float x2, float y2) {
return Math.hypot(x1 - x2, y1 - y2) < TOUCH_TOLERANCE;
}
private void drag(int x, int y) {
int movement;
movement = x - previous.x;
int movementY = y - previous.y;
selection.set(selection.left + movement, selection.top + movementY,
selection.right + movement, selection.bottom + movementY);
selection.sort();
invalidate();
}
/**
* Calculate the degree to be rotated by.
*
* #param event
* #return Degrees
*/
// private float rotation(float dx, float dy) {
//
// // double delta_x = (dx);
// // double delta_y = (dy);
// double radians = Math.atan2((selection.left) - (previous.y),
// (selection.top) - (previous.x));
// double radians2 = Math.atan2((selection.left) - (dy),
// (selection.top) - (dx));
//
// System.out.println("radians" + radians);
// System.out.println("" + radians2);
// System.out.println("radians2-radians" + (radians2 - radians));
// System.out.println(Math.toDegrees(radians2 - radians));
// return (float) Math.toDegrees(radians2 - radians);
//
// }
private double getAngle(double xTouch, double yTouch) {
double x = xTouch - (getWidth() / 2d);
double y = getHeight() - yTouch - (getHeight() / 2d);
switch (getQuadrant(x, y)) {
case 1:
System.out.println("1");
return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
case 2:
case 3:
System.out.println("32");
return 180 - (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
case 4:
System.out.println("4");
return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
default:
// ignore, does not happen
return 0;
}
}
/**
* #return The selected quadrant.
*/
private int getQuadrant(double x, double y) {
if (x >= 0) {
return y >= 0 ? 1 : 4;
} else {
return y >= 0 ? 2 : 3;
}
}
}
}
I have Design A Layout that may work as your need.
Download Demo here
Java File
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class ClipArt extends RelativeLayout {
int baseh;
int basew;
int basex;
int basey;
ImageButton btndel;
ImageButton btnrot;
ImageButton btnscl;
RelativeLayout clip;
Context cntx;
boolean freeze = false;
int h;
int i;
ImageView image;
String imageUri;
boolean isShadow;
int iv;
RelativeLayout layBg;
RelativeLayout layGroup;
RelativeLayout.LayoutParams layoutParams;
public LayoutInflater mInflater;
int margl;
int margt;
float opacity = 1.0F;
Bitmap originalBitmap;
int pivx;
int pivy;
int pos;
Bitmap shadowBitmap;
float startDegree;
String[] v;
public ClipArt(Context paramContext) {
super(paramContext);
cntx = paramContext;
layGroup = this;
basex = 0;
basey = 0;
pivx = 0;
pivy = 0;
mInflater = ((LayoutInflater) paramContext.getSystemService("layout_inflater"));
mInflater.inflate(R.layout.clipart, this, true);
btndel = ((ImageButton) findViewById(R.id.del));
btnrot = ((ImageButton) findViewById(R.id.rotate));
btnscl = ((ImageButton) findViewById(R.id.sacle));
layoutParams = new RelativeLayout.LayoutParams(250, 250);
layGroup.setLayoutParams(layoutParams);
image = ((ImageView) findViewById(R.id.clipart));
image.setImageResource(R.drawable.ic_launcher);
setOnTouchListener(new View.OnTouchListener() {
final GestureDetector gestureDetector = new GestureDetector(ClipArt.this.cntx,
new GestureDetector.SimpleOnGestureListener() {
public boolean onDoubleTap(MotionEvent paramAnonymous2MotionEvent) {
return false;
}
});
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
layGroup.invalidate();
gestureDetector.onTouchEvent(event);
layGroup.performClick();
basex = ((int) (event.getRawX() - layoutParams.leftMargin));
basey = ((int) (event.getRawY() - layoutParams.topMargin));
break;
case MotionEvent.ACTION_MOVE:
int i = (int) event.getRawX();
int j = (int) event.getRawY();
layBg = ((RelativeLayout) getParent());
if ((i - basex > -(layGroup.getWidth() * 2 / 3))
&& (i - basex < layBg.getWidth() - layGroup.getWidth() / 3)) {
layoutParams.leftMargin = (i - basex);
}
if ((j - basey > -(layGroup.getHeight() * 2 / 3))
&& (j - basey < layBg.getHeight() - layGroup.getHeight() / 3)) {
layoutParams.topMargin = (j - basey);
}
layoutParams.rightMargin = -1000;
layoutParams.bottomMargin = -1000;
layGroup.setLayoutParams(layoutParams);
break;
}
return true;
}
return true;
}
});
this.btnscl.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint({ "NewApi" })
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
int j = (int) event.getRawX();
int i = (int) event.getRawY();
layoutParams = (RelativeLayout.LayoutParams) layGroup.getLayoutParams();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ClipArt.this.layGroup.invalidate();
ClipArt.this.basex = j;
ClipArt.this.basey = i;
ClipArt.this.basew = ClipArt.this.layGroup.getWidth();
ClipArt.this.baseh = ClipArt.this.layGroup.getHeight();
int[] loaction = new int[2];
layGroup.getLocationOnScreen(loaction);
margl = layoutParams.leftMargin;
margt = layoutParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
float f2 = (float) Math.toDegrees(Math.atan2(i - ClipArt.this.basey, j - ClipArt.this.basex));
float f1 = f2;
if (f2 < 0.0F) {
f1 = f2 + 360.0F;
}
j -= ClipArt.this.basex;
int k = i - ClipArt.this.basey;
i = (int) (Math.sqrt(j * j + k * k)
* Math.cos(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation())));
j = (int) (Math.sqrt(i * i + k * k)
* Math.sin(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation())));
k = i * 2 + ClipArt.this.basew;
int m = j * 2 + ClipArt.this.baseh;
if (k > 150) {
layoutParams.width = k;
layoutParams.leftMargin = (ClipArt.this.margl - i);
}
if (m > 150) {
layoutParams.height = m;
layoutParams.topMargin = (ClipArt.this.margt - j);
}
ClipArt.this.layGroup.setLayoutParams(layoutParams);
ClipArt.this.layGroup.performLongClick();
break;
}
return true;
}
return ClipArt.this.freeze;
}
});
this.btnrot.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint({ "NewApi" })
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
layoutParams = (RelativeLayout.LayoutParams) ClipArt.this.layGroup.getLayoutParams();
ClipArt.this.layBg = ((RelativeLayout) ClipArt.this.getParent());
int[] arrayOfInt = new int[2];
layBg.getLocationOnScreen(arrayOfInt);
int i = (int) event.getRawX() - arrayOfInt[0];
int j = (int) event.getRawY() - arrayOfInt[1];
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ClipArt.this.layGroup.invalidate();
ClipArt.this.startDegree = layGroup.getRotation();
ClipArt.this.pivx = (layoutParams.leftMargin + ClipArt.this.getWidth() / 2);
ClipArt.this.pivy = (layoutParams.topMargin + ClipArt.this.getHeight() / 2);
ClipArt.this.basex = (i - ClipArt.this.pivx);
ClipArt.this.basey = (ClipArt.this.pivy - j);
break;
case MotionEvent.ACTION_MOVE:
int k = ClipArt.this.pivx;
int m = ClipArt.this.pivy;
j = (int) (Math.toDegrees(Math.atan2(ClipArt.this.basey, ClipArt.this.basex))
- Math.toDegrees(Math.atan2(m - j, i - k)));
i = j;
if (j < 0) {
i = j + 360;
}
ClipArt.this.layGroup.setRotation((ClipArt.this.startDegree + i) % 360.0F);
break;
}
return true;
}
return ClipArt.this.freeze;
}
});
this.btndel.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView) {
if (!ClipArt.this.freeze) {
layBg = ((RelativeLayout) ClipArt.this.getParent());
layBg.performClick();
layBg.removeView(ClipArt.this.layGroup);
}
}
});
}
public void disableAll() {
this.btndel.setVisibility(4);
this.btnrot.setVisibility(4);
this.btnscl.setVisibility(4);
}
public ImageView getImageView() {
return this.image;
}
public void setFreeze(boolean paramBoolean) {
this.freeze = paramBoolean;
}
}
Layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<ImageButton android:id="#+id/rotate" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/rotation"/>
<ImageButton android:id="#+id/sacle" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/pointer"/>
<ImageButton android:id="#+id/del" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/close"/>
<ImageView android:id="#+id/clipart" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"/>
</RelativeLayout>
and images put in drawable
please check the repository in github i create it .
count the distance from center point in the rotate and zoom view to the push point.
just use :
private float getDistance(Point a, Point b) {
float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
return ((int) (Math.sqrt(v) * 100)) / 100f;
}
and count the OA/OB that value can count the view new height and width
count the angle AOB, the A is the first push point , the B is the last move point ,the O is the center of the View Point .
and then just set new height and width for view ,and count the left and top for view .
souce link : https://github.com/ryanch741/android-view-rotate-zoom-single-finger
the code:
Point pushPoint;
int lastImgWidth;
int lastImgHeight;
int lastImgLeft;
int lastImgTop;
int lastImgAngle;
double lastComAngle;
int pushImgWidth;
int pushImgHeight;
int lastPushBtnLeft;
int lastPushBtnTop;
private View mView;
private Point mViewCenter;
private static final double PI = 3.14159265359;
public PushBtnTouchListener(View mView) {
this.mView = mView;
}
private FrameLayout.LayoutParams pushBtnLP;
private FrameLayout.LayoutParams imgLP;
float lastX = -1;
float lastY = -1;
#Override
public boolean onTouch(View pushView, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 主点按下
case MotionEvent.ACTION_DOWN:
pushBtnLP = (FrameLayout.LayoutParams) pushView.getLayoutParams();
imgLP = (FrameLayout.LayoutParams) mView.getLayoutParams();
pushPoint = getPushPoint(pushBtnLP, event);
lastImgWidth = imgLP.width;
lastImgHeight = imgLP.height;
lastImgLeft = imgLP.leftMargin;
lastImgTop = imgLP.topMargin;
lastImgAngle = (int) mView.getRotation();
lastPushBtnLeft = pushBtnLP.leftMargin;
lastPushBtnTop = pushBtnLP.topMargin;
pushImgWidth = pushBtnLP.width;
pushImgHeight = pushBtnLP.height;
lastX = event.getRawX();
lastY = event.getRawY();
refreshImageCenter();
break;
// 副点按下
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_UP: {
break;
}
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
float rawX = event.getRawX();
float rawY = event.getRawY();
if (lastX != -1) {
if (Math.abs(rawX - lastX) < 5 && Math.abs(rawY - lastY) < 5) {
return false;
}
}
lastX = rawX;
lastY = rawY;
Point O = mViewCenter, A = pushPoint, B = getPushPoint(pushBtnLP, event);
float dOA = getDistance(O, A);
float dOB = getDistance(O, B);
float f = dOB / dOA;
int newWidth = (int) (lastImgWidth * f);
int newHeight = (int) (lastImgHeight * f);
imgLP.leftMargin = lastImgLeft - ((newWidth - lastImgWidth) / 2);
imgLP.topMargin = lastImgTop - ((newHeight - lastImgHeight) / 2);
imgLP.width = newWidth;
imgLP.height = newHeight;
mView.setLayoutParams(imgLP);
float fz = (((A.x - O.x) * (B.x - O.x)) + ((A.y - O.y) * (B.y - O.y)));
float fm = dOA * dOB;
double comAngle = (180 * Math.acos(fz / fm) / PI);
if (Double.isNaN(comAngle)) {
comAngle = (lastComAngle < 90 || lastComAngle > 270) ? 0 : 180;
} else if ((B.y - O.y) * (A.x - O.x) < (A.y - O.y) * (B.x - O.x)) {
comAngle = 360 - comAngle;
}
lastComAngle = comAngle;
float angle = (float) (lastImgAngle + comAngle);
angle = angle % 360;
mView.setRotation(angle);
Point imageRB = new Point(mView.getLeft() + mView.getWidth(), mView.getTop() + mView.getHeight());
Point anglePoint = getAnglePoint(O, imageRB, angle);
pushBtnLP.leftMargin = (int) (anglePoint.x - pushImgWidth / 2);
pushBtnLP.topMargin = (int) (anglePoint.y - pushImgHeight / 2);
pushView.setLayoutParams(pushBtnLP);
break;
}
return false;
}
private void refreshImageCenter() {
int x = mView.getLeft() + mView.getWidth() / 2;
int y = mView.getTop() + mView.getHeight() / 2;
mViewCenter = new Point(x, y);
}
private Point getPushPoint(FrameLayout.LayoutParams lp, MotionEvent event) {
return new Point(lp.leftMargin + (int) event.getX(), lp.topMargin + (int) event.getY());
}
private float getDistance(Point a, Point b) {
float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
return ((int) (Math.sqrt(v) * 100)) / 100f;
}
private Point getAnglePoint(Point O, Point A, float angle) {
int x, y;
float dOA = getDistance(O, A);
double p1 = angle * PI / 180f;
double p2 = Math.acos((A.x - O.x) / dOA);
x = (int) (O.x + dOA * Math.cos(p1 + p2));
double p3 = Math.acos((A.x - O.x) / dOA);
y = (int) (O.y + dOA * Math.sin(p1 + p3));
return new Point(x, y);
}
I'm assuming the rotation/scaling happens from the image center? In that case, it's simple trigonometry to find the rotation angle and the size:
Calculate dx and dy of the finger's coordinates minus the center coordinates. Math.atan2(dy, dx) is the rotation angle (in radians) and Math.hypot(dx,dy) can be used for the relative size, or just double the dx/dy and use directly.