i have relative parent layout and adding custom textview dynamically into it. when i drag(move) and scale my current textview it get weird jumps continuously in both pointer index. how can i solve this issue?
my custom textview as given below:
public class VideoTextView extends TextView implements View.OnTouchListener {
private final String TAG = this.getClass().getSimpleName();
private Context context;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private PointF start = new PointF();
private PointF mid = new PointF();
private float[] matrixValues = new float[9];
private Paint paint;
private Paint linePaint;
private VideoTextMovement videoTextMovement;
private OperationListener operationListener;
private int widthView, heightView;
private boolean isInEdit;
public VideoTextView(Context context, int widthView, int heightView) {
super(context);
this.context = context;
this.widthView = widthView;
this.heightView = heightView;
videoTextMovement = (VideoTextMovement) context;
init();
}
public void updateViewWidthHeight(int widthView, int heightView) {
this.widthView = widthView;
this.heightView = heightView;
}
private void init() {
paint = new Paint();
paint.setTextSize(8);
paint.setColor(context.getResources().getColor(R.color.white));
linePaint = new Paint();
linePaint.setColor(getResources().getColor(R.color.colorPrimary));
linePaint.setAntiAlias(true);
linePaint.setDither(true);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(3.0f);
// setTextSize(8f);
setTextColor(getResources().getColor(R.color.colorAccent));
setOnTouchListener(this);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int textWidth = getMeasuredWidth();
int textHeight = getMeasuredHeight();
int origWidth = textWidth;
int origHeight = textHeight;
matrix.getValues(matrixValues);
canvas.save();
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG & Paint.FILTER_BITMAP_FLAG));
float transX = matrixValues[Matrix.MTRANS_X];
float transY = matrixValues[Matrix.MTRANS_Y];
float scaleX = matrixValues[Matrix.MSCALE_X];
float scaleY = matrixValues[Matrix.MSCALE_Y];
float maxScale = widthView / textWidth;
Log.e(TAG + " ====", "matrix scale " + scaleX + " " + scaleY + " max scale " + maxScale);
scaleX = Math.max(0.5f, Math.min(scaleX, maxScale));
scaleY = Math.max(0.5f, Math.min(scaleY, maxScale));
if (scaleX > 1.0f) {
textWidth = (int) (textWidth + (textWidth * (scaleX - 1.0f)));
} else if (scaleX < 1.0f) {
textWidth = (int) (textWidth * scaleX);
}
if (scaleY > 1.0f) {
textHeight = (int) (textHeight + (textHeight * (scaleY - 1.0f)));
} else if (scaleY < 1.0f) {
textHeight = (int) (textHeight * scaleY);
}
Log.e(TAG + " ====", "original Tx-Ty " + transX + " - " + transY);
if (transX < 0) {
transX = 0;
}
if (transY < 0) {
transY = 0;
}
if (transX > (widthView - textWidth)) {
transX = widthView - textWidth;
}
if (transY > (heightView - textHeight)) {
transY = heightView - textHeight;
}
Log.e(TAG + " ====", "original w-h " + origWidth + " - " + origHeight + " " + " increased w-h " + textWidth + " - " + textHeight);
Log.e(TAG + " ====", "diff w-h " + Math.abs(origWidth - textWidth) + " - " + Math.abs(origHeight - textHeight));
matrixValues[Matrix.MTRANS_X] = transX;
matrixValues[Matrix.MTRANS_Y] = transY;
matrixValues[Matrix.MSCALE_X] = scaleX;
matrixValues[Matrix.MSCALE_Y] = scaleY;
matrix.setValues(matrixValues);
setX(transX + (textWidth - origWidth) / 2);
setY(transY + (textHeight - origHeight) / 2);
setScaleX(scaleX);
setScaleY(scaleY);
// setPivotX(mid.x);
// setPivotY(mid.y);
Log.e(TAG + " ====", "translateFactor " + transX + " - " + transY + " scaleFactor " + scaleX + " - " + scaleY);
videoTextMovement.translateText(getId(), transX, transY, textWidth, textHeight, getTextSize());
if (isInEdit) {
canvas.drawLine(0, origHeight, origWidth, origHeight, linePaint);
}
canvas.restore();
Log.e(TAG + " ===", TAG + " onDraw");
}
public void midPoint(MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
Log.e(TAG + " ====", "mid point x-y " + (x / 2) + " " + (y / 2));
mid.set(x / 2, y / 2);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
Log.e(TAG + " ====", "spacing x-y " + (x * x + y * y));
return (float) Math.sqrt(x * x + y * y);
}
float rawX0;
float rawY0;
float rawX1;
float rawY1;
private void getOriginalLocation(MotionEvent event) {
int[] location = {0, 0};
getLocationOnScreen(location);
rawX0 = event.getX(0) + location[0];
rawY0 = event.getY(0) + location[1];
float x = event.getRawX();
float y = event.getRawY();
Log.e(TAG + " ===", "actual raw co. " + x + "-" + y);
Log.e(TAG + " ===", "custom raw co. " + rawX0 + "-" + rawY0);
rawX1 = event.getX(1) + location[0];
rawY1 = event.getY(1) + location[1];
}
private float getRawX(MotionEvent event, int pointerIndex) {
float offset = event.getRawX() - event.getX();
return event.getX(pointerIndex) + offset;
}
private float getRawY(MotionEvent event, int pointerIndex) {
float offset = event.getRawY() - event.getY();
return event.getY(pointerIndex) + offset;
}
public void setInEdit(boolean isInEdit) {
this.isInEdit = isInEdit;
invalidate();
}
public void setOperationListener(OperationListener operationListener) {
this.operationListener = operationListener;
}
private float oldDist;
private final int NONE = -1;
private final int DRAG = 1;
private final int ZOOM = 2;
private int mode = NONE;
@Override
public boolean onTouch(View view, MotionEvent event) {
float downX, downY;
float moveX, moveY;
switch (event.getAction() & event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
savedMatrix.set(matrix);
start.set(downX, downY);
mode = DRAG;
Log.e(TAG + " ===", "Action down X=" + downX + " Y=" + downY);
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
savedMatrix.set(matrix);
midPoint(event);
mode = ZOOM;
Log.e(TAG + " ===", "Pointer down");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
moveX = event.getX();
moveY = event.getY();
float mdX = moveX - start.x;
float mdY = moveY - start.y;
matrix.set(savedMatrix);
matrix.postTranslate(mdX, mdY);
invalidate();
Log.e(TAG + " ===", "draging");
Log.e(TAG + " ===", "draging x-y rawx-rawy " + event.getX() + "-" + event.getY() + " " + event.getRawX() + "-" + event.getRawY());
} else if (mode == ZOOM) {
float newDist = spacing(event);
float scale = (newDist / oldDist);
matrix.set(savedMatrix);
Log.e(TAG + " ====", "Zoom scale " + scale);
matrix.postScale(scale, scale/*, mid.x, mid.y*/);
invalidate();
Log.e(TAG + " ===", "scaling");
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.e(TAG + " ===", "Action up, Pointer up");
break;
}
if (operationListener != null) {
operationListener.onEdit(this);
}
return true;
}
public interface OperationListener {
void onEdit(VideoTextView videoTextview);
}
}
I have added my touch listener and all necessary functions that i have used to perform drag and scale event in my code to solve this issue, but every time i get fail to solve.
My Layout XML:
<FrameLayout
android:id="@+id/videoEditorParent"
android:layout_width="match_parent"
android:layout_height="400dp">
<RelativeLayout
android:id="@+id/vidEditorWrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/colorAccent">
<VideoView
android:id="@+id/vidEditor"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</FrameLayout>
can somebody help to solve this kind to problem?
Thanks.