I am trying to draw line in android.But i am not satisfy with that because it doesn't draw full line it draws a dotted line when i move object fastly and it draws a complete line when i move object slowly.Plaese help me why this happenes.I want just complete line not dotted line.My code is here:
On Touch event of view:
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
_xDelta = X - lParams.leftMargin;
Log.e("ACTION DOWN X", "" + Y + "---" + lParams.leftMargin);
_yDelta = Y - lParams.topMargin;
Log.e("ACTION DOWN Y", "" + Y + "---" + lParams.leftMargin);
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
Log.e("ACTION Move left margin", "" + (X - _xDelta));
layoutParams.topMargin = Y - _yDelta;
Log.e("ACTION Move top margin", "" + (Y - _yDelta));
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setBackgroundColor(random.nextInt());
view.setLayoutParams(layoutParams);
draw = new DrawLine(MainActivity.this, X - _xDelta, Y - _yDelta);
root.addView(draw);
break;
}
root.invalidate();
return true;
}
And my draw method is like this:
#Override
protected void onDraw(final Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// paint.setColor(random.nextInt());
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(4);
canvas.drawPoint(startX, startY, paint);
}
And i also want to know how to clear all the drawing.
Please help me to solve this.
Thank you.
So how do you expect that a line should be drawn when you only draw dots? The touch event registration/handling is not fast enough to get fired on each new pixel your finger touched. Use a path to store your points and draw a line/path using the points in your path.
Related
I need to click on particular item on the canvas while zooming and moving functionalities also enable for canvas. I can calculate the rectangle position while moving the canvas. There I just calculate the touch movement distance by (CurrenTouchXPosition - StartXPosition).
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
float moveOffsetX = (event.getX() - start.x);
float moveOffsetY = (event.getY() - start.y);
Then,
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "action up");
secondRectUpperX = secondRectUpperX + moveOffsetX;
secondRectBottomX = secondRectBottomX + moveOffsetX;
secondRectUpperY = secondRectUpperY + moveOffsetY;
secondRectBottomY = secondRectBottomY + moveOffsetY;
This can identify the new canvas position of the rectangle. This works perfectly. I can identify the touch event of particular item while moving the canvas by this logic.
But now i need to calculate the rectangle position relative to the canvas, after zoom the canvas. Whats the maths behind the zooming. If anyone knows please help in this.
Thank you.
Finally I come up with a solution.
I translate my touch position screen coordinates to canvas coordinates.
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
...
break;
case MotionEvent.ACTION_POINTER_DOWN:
...
break;
case MotionEvent.ACTION_UP:
float []m = new float[9];
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X] * -1;
float transY = m[Matrix.MTRANS_Y] * -1;
float scaleX = m[Matrix.MSCALE_X];
float scaleY = m[Matrix.MSCALE_Y];
lastTouchX = (int) ((event.getX() + transX) / scaleX);
lastTouchY = (int) ((event.getY() + transY) / scaleY);
lastTouchX = Math.abs(lastTouchX);
lastTouchY = Math.abs(lastTouchY);
Thanks for Andres Cardenas Pardo's answer here
I could able to get the touch position coordinates according to the canvas coordinates. Since i know the coordinates of my drawn object, i check whether the touch position is within the range of drawn object.
if((lastTouchX>=firstRectUpperX && firstRectBottomX>=lastTouchX) && (lastTouchY>=firstRectUpperY && firstRectBottomY>=lastTouchY)) {
isbtn1Clicked = true;
}
I'm working with OpenGLES 2.0 in android. I need to move an OpenGL object with the taking the x and y axis from the touch event. But when I try to translate the object it acts weird. Same object gets displayed in two places with varying opacity.. and when the finger is lifted both the objects get disappeared.
My translation code is:
Matrix.setIdentityM(mtrxView, 0);
Matrix.translateM(mtrxView, 0, x, y, 0);
Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0);
I'm overriding onTouch() method to handle the ACTION_MOVE event:
public boolean onTouch(View v, MotionEvent ev) {
x = ev.getX();
y = ev.getY();
deltaX = x - downX;
deltaY = y - downY;
mScaleDetector.onTouchEvent(ev);
AppLog.v(TAG, "Screen xy cordinate is: " + x + " " + y + " ");
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
if(!isZoomInProcess){
glRender.requestRender(x, y,GlSurfaceView.this);
requestRender();
}
break;
}
return true;
}
Hi I want to do something like this
When user presses rotate icon, text contained in box should gradually rotate and using scale icon, text should be resized.
Right now I am using this code for moving the textview everywhere on the screen
private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
break;
}
elementslayout.invalidate();
return true;
}
It is working fine.
On long press of textview I want to show the layout with rotate and scale icon.
My question is,
How to create this type of layout for textview and do rotate and scale accordingly?
I have seen many codes for rotate and scale using matrix like
http://judepereira.com/blog/multi-touch-in-android-translate-scale-and-rotate/
But don't know how to use it here.
I also want to do the same thing, Rotate,Scale as well as move textview all together. I found a link for text rotation here.
Android Two finger rotation
This works totally fine for the text rotation. You just need to add
txt.setRotation(-angle);
In the onRotation Method. May be that helps you.
I am try to implement the vertical slider of image control. The image is inside the ScrollView. When it comes to vertical dragging of ImageView, the top margin of relative layout always provide different reading.
If it is greater than 600 something while dragging down, the background image of the relative layout stretch vertically together with the image position I have dragged.
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:fillViewport="true" >
...
<RelativeLayout
android:id="#+id/relativeLayouyt6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/rTop"
android:background="#drawable/plain" >
<ImageView
android:id="#+id/dragImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow_one"
android:visibility="gone" />
</RelativeLayout>
Would you please tell me how to
get the offset I have scrolled in my scrollview ?
I know it is get touch position minus scrolled position and plus image Y position, how to implement this parameter after finishing dragging ?
How to set relative boundary for imageview inside the relative layout ? is it wiser to take this background image out as the imageview?
If I programmatically repositioning of 6 relativelayouts but coming up to the same width , would it affect the scrolling position and the scollview total Height ? If so , How to calculate the offset Y for the repositioning ?
The below is my code as of February 11:
dragImage.setOnTouchListener(new OnTouchListener(){
//private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//_yDelta = Y - lParams.topMargin;
mOldY2 = y;
break;
case MotionEvent.ACTION_UP:
mViewPager.setPagingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
btn4.setBackgroundResource(R.drawable.fbl02);
final float dy = y - mOldY2;
mNewY2 += dy;
mOldY2 = y;
System.out.println(mNewY2);
while(mNewY2 > 224){
mNewY2 -= 224;
}
while(mNewY2 < 157){
mNewY2 += 157;
}
if(mNewY2 < 157 || mNewY2 > 224)
break;
v.setTranslationY((int)mNewY2);
v.invalidate();
float power = (float) ( 51.5/67 -(0.2/67) * mNewY2) ;
System.out.println(power);
Float roundF = new Float( Math.round(power));
midBandStick = roundF;
btn4.setText(String.valueOf(midBandStick) );
//}
//break;
}
return true;
}
The below is my code :
public static void setRLBelowAnother(RelativeLayout rA , RelativeLayout rB ){
RelativeLayout.LayoutParams rparam4 =
(android.widget.RelativeLayout.LayoutParams) rB.getLayoutParams();
rparam4.addRule(RelativeLayout.BELOW, rA.getId());
rB.setLayoutParams(rparam4);
}
setRLBelowAnother(rTop , r1);
setRLBelowAnother(r1 , r2);
setRLBelowAnother(r2 , r6 );
setRLBelowAnother(r6 , r3 );
setRLBelowAnother(r3 , r4 );
setRLBelowAnother(r4 , r5 );
dragImage.setVisibility(View.VISIBLE);
dragImage.setImageResource(R.drawable.slide_lshort);
dragImage.setX((float) (0.15*screenWidth));
dragImage.setY((float) (0.05*screenHeight));
dragImage.setOnTouchListener(new OnTouchListener(){
//private int _xDelta;
private int _yDelta;
#Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
final int X = (int) event.getX();
final int Y = (int) event.getY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) dragImage
.getLayoutParams();
//_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
mViewPager.setPagingEnabled(true);
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
midStick = 0.2f;
btn4.setBackgroundResource(R.drawable.fbl02);
RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) dragImage
.getLayoutParams();
//ParamsA.leftMargin = X - _xDelta;
ParamsA.topMargin = Y - _yDelta;
//ParamsA.rightMargin = -250;
ParamsA.bottomMargin = -250;
mViewPager.setPagingEnabled(false);
int offYb = 0;
int pos = ParamsA.topMargin + offYb ;
if(pos > -52 && pos < 582 ){
dragImage.setLayoutParams(ParamsA);
System.out.println(ParamsA.topMargin);
float power = (float) (100 + (900/634) * ParamsA.topMargin) ;
Float roundF = new Float( Math.round(power));
midStick = roundF;
btn4.setText(String.valueOf(midStick));
}
break;
}
return true;
}
});
Call the getScrollY() method from the ScrollView to get the Y index (scrolled index)
If I understood (otherwise please correct me) you could get a frame (boundary) between the ImageView and the RelativeLayout adding padding or margin to the ImageView. You just need to call android:padding="" or android:margin=""
The height of the ScrollView will change and also the scrollY if the new added RelativeLayout/ImageView doesn't completely fit on the available space. When you finish adding the new layout you could get the scrollY from the ScrollView and see where the ScrollView has scrolled to.
Can you improve the questions 2, 3 and 4? It's quite confusing.
I had 2 views in an activity. One full screen (View1) and other small (View2), half the size of View1.
I can move View2, over View1 by catching onTouch listeners (ACTION_UP/ACTION_DOWN). But i want to show animation/dragging image of View2 while moving on View1. Any suggestion on how to implement this, will be appreciated.
Currently, for moving the View2 in four corner, i'm setting the Layout params in ACTION_UP.
Code::
public boolean onTouch(View view, MotionEvent motionEvent) {
RelativeLayout.LayoutParams layoutParams =(RelativeLayout.LayoutParams)view.getLayoutParams();
int dx=0,dy=0;
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
int x = (int) motionEvent.getX();
int y = (int) motionEvent.getY();
dx = (int) motionEvent.getRawX() - layoutParams.leftMargin;
dy = (int)motionEvent.getRawY() - layoutParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
layoutParams.leftMargin = (int) ((int) motionEvent.getRawX()-dx);
layoutParams.topMargin = (int) ((int)motionEvent.getRawY()- dy);
view.setLayoutParams(layoutParams);
break;
case MotionEvent.ACTION_UP:
view.setLayoutParams(layoutParams);
break;
}
return true;
}
Use ACTION_MOVE and calculate the offset by checking a pointer's x or y value. After that set weight or height/width parameter of the floating View.