How to control the image not to move out from the imageView? - android

I use onTouch to move a image in the imageView, But unfortunately it will move out the screen .So Is there a better way to control that if the image bounds touch the border,then we can stop it move out?

I'm having a hard time understanding your question. But if I've interpreted your question correct, you currently have a draggable imageview and you want to make sure that the image´s borders don't go outside of the screen? The only way to stop that from happening is to check whether or not the image bounds go outside of the screen. Below code is NOT complete, it will just help you on the way. finalHeight and finalWidth will now hold your imageView´s actual size on screen (I.e The actual image´s size in the imageview).
int windowwidth = getWindowManager().getDefaultDisplay().getWidth();
int windowheight = getWindowManager().getDefaultDisplay().getHeight();
final ImageView mImage= (ImageView)findViewById(R.id.mImage);
int finalHeight, finalWidth;
ViewTreeObserver vto = mImage.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
finalHeight = mImage.getMeasuredHeight();
finalWidth = mImage.getMeasuredWidth();
return true;
}
});
mImage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) mImage.getLayoutParams();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int)event.getRawX();
int y_cord = (int)event.getRawY();
if(x_cord>windowwidth){x_cord=windowwidth;}
if(y_cord>windowheight){y_cord=windowheight;}
layoutParams.leftMargin = x_cord - 10; // Set these to co-responding values
layoutParams.topMargin = y_cord - 10; // Set these to co-responding values
mImage.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}
});
This may help you on the way =)

Related

How to know when one moving view (overlaps) is on the top of the over

(not sure about the Title. Please make it right)
Hi. I'm trying to create a small game, where player can move objects inside RalativeLayout. What I want is to check whether my moving object is inside FrameLayout or outside of it. For example I want to change the text of this object when it is inside FrameLayout.
So I create objects inside for loop this way:
Random random = new Random();
for (int i = 0; i < 3; i++) { //any number, not just 3
TextView textView = new TextView(getActivity());
textView.setX(random.nextInt(size.x - 200));
textView.setY(random.nextInt(size.y - 200)); //scattered all over the screen
textView.setText(i + "");
textView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
textView.setTextSize(50);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
textView.setLayoutParams(lp);
textView.setOnTouchListener(touchListener);
frameFor.addView(textView);
}
There is also a FrameLayout where eventually all my objects should be:
RelativeLayout.LayoutParams frameLP = new RelativeLayout.LayoutParams(300, 300);
frameLP.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
frameForLetters.setLayoutParams(frameLP);
As you can see, I also added a OnTouchListener to make objects movable:
View.OnTouchListener touchListener = new View.OnTouchListener() {
float dX, dY;
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
view.animate()
.x(event.getRawX() + dX)
.y(event.getRawY() + dY)
.setDuration(0)
.start();
break;
default:
return false;
}
return true;
}
};
in this pic you can see that one and two are inside FrameLayout and zero is outside.
I know it all can be done with huge amount of geometry and calculation the size of each object and FrameLayout itself. Maybe there is another way of doing this? Maybe there is a library or framework which can make my task much easier?
I'm not aware of libraries or frameworks, but you can use these two methods to determine if the objects are overlapping (the Rect.intersects method does most of the calculations):
private Rect getScreenBounds(View view)
{
int[] location = new int[2];
view.getLocationOnScreen(location);
return new Rect(location[0], location[1], location[0] + view.getWidth(), location[1] + view.getHeight());
}
private boolean doViewsIntersect(View target, View item)
{
Rect targetRect = getScreenBounds(target);
Rect itemRect = getScreenBounds(item);
return targetRect.intersects(itemRect);
}
If you're interested in knowing if the object is fully inside the other, targetRect becomes the Rect containing the intersection. Hence, you can do the following to see if the item is entirely inside the target bounds:
if(targetRect.intersects(itemRect)) {
return targetRect.width() == item.getWidth() && targetRect.height() == item.getHeight();
} else {
return false;
}

Move, rotate and scale text using custom layout in android

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.

Android stretch background image while dragging the imageview

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.

How to determine the end of a touch-events set?

I have a small app, which uses a fullscreen activity and where I can drag an ImageView.
Now my solution works like this: I change the position of the ImageView according to the drag of the finger, so basically I'm adding the delta x (previousX - currentX) to the position of the ImageView. Now the problem is determining the previousX. It works fine for the first time, since I'm testing whether it's 0, if it's null it means the app is just started and the previous x can become the new x, however the dragging movement becomes ugly as soon as you move the finger away after dragging and start dragging again by putting the finger in a different spot than you finished dragging the first time (because it's virtually impossible to put it in the same place. So the previousX is the one from the last drag, so when you start the second drag it jumps the x difference from the previous x to the new one. I either need to change a different way of calculating this, or determine when the finger gets away from screen and the series of drag events are finished.
This is what my code for the touch event looks like:
#Override
public boolean onTouch(View v, MotionEvent event) {
LayoutParams layoutParams = (LayoutParams) img
.getLayoutParams();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
if (x_cord > windowWidth) {
x_cord = windowWidth;
}
if (y_cord > windowHeight) {
y_cord = windowHeight;
}
if (previousX == 0) {
previousX = x_cord;
}
if (previousY == 0) {
previousY = y_cord;
}
layoutParams.leftMargin = layoutParams.leftMargin
+ (x_cord - previousX);
layoutParams.topMargin = layoutParams.topMargin
+ (y_cord - previousY);
img.setLayoutParams(layoutParams);
previousX = x_cord;
previousY = y_cord;
break;
default:
break;
}
return true;
}
});

View animation while moving on Screen in android?

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.

Categories

Resources