I have a problem.
I am trying to create an element in the recycle view, which, when you click and hold an item, expands the element and displays some of the data.
I do this using onLongClickListener, but when the user stops touching the button, the element is further expanded
What do I have to do to collapse an item when the user stops holding the item?
onTouchEvent does what you want:
public boolean onTouchEvent(MotionEvent event) {
int eventAction = event.getAction();
// you may need the x/y location
int x = (int)event.getX();
int y = (int)event.getY();
// put your code in here to handle the event
switch (eventAction) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
break;
}
// tell the View to redraw the Canvas
invalidate();
// tell the View that we handled the event
return true;
}
If you want to read more you can check this and this link.
Related
I have a project which i'm required to develop Android game that display a 5*5 table and and image for each player which each one of them can move the image in place inside the 5*5 table.
ex:
Note : I need to know the exact coordinates (or anything relative) so i can save the position in array and move the image to that new place (eg : re-draw it on the new position).
Any ideas ?
Thanks in advance.
Just use a RelativeLayout with 5x5 ImageViews (set to not visible).
And on the images that the user can move to the place, use Drag and Drop.
In onDrag you set the visibility of the image to Gone.
For all ImageView (5x5 Table), you set the onDragListener.
After that, in the overwritten method OnDrop, you can receive the view that is dropped and can determine which drawable to show.
edit:
Oh well, in this case I would use GridView as said in the comments. And make usage of drag and drop. You don't need to attach a DragListener to every image then. You can simply let the GridView listen to the drop events and determine by the x and y where to drop.
Little example (just as a hint)
gameStoneView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
DragShadowBuilder shadowBuilder = new DragShadowBuilder(gameStoneView);
gameStoneView.startDrag(null, shadowBuilder, gameStoneView, 0);
if (dragListener != null) {
dragListener.onDragStart();
}
break;
default:
LOG.v("Motion event reorderIcon: DEFAULT - not action down");
}
return true;
}
});
gridView.setOnDragListener(new OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_LOCATION:
currentY = event.getY();
currentX = event.getX();
break;
case DragEvent.ACTION_DROP:
final Point position = getPositionOfItem(currentX, currentY);
dropItemAt(position);
break;
case DragEvent.ACTION_DRAG_EXITED:
//BORDER DRAGEVENT: ACTION_DRAG_EXITED
viewDraggedOutSide = true;
break;
case DragEvent.ACTION_DRAG_ENDED:
//BORDER DRAGEVENT: ACTION_DRAG_ENDED
if (viewDraggedOutSideList) {
reinsertDraggedItem();
update();
}
viewDraggedOutSideList = false;
return true;
default:
return true;
}
}
});
In a Custom ListView extending Cursoradapter, I need both Listview and image button to get focussed. How to do it?
Implement your own OnTouchListener for ListView which conditional return values. If you return TRUE from onTouch, the system will assume that the onTouch was handled and it won't handle it by itself. If you return FALSE from onTouch, system will assume that the OnTouchListener did not handle the touch events and will do further processing. This way you can manage how the touch / click should work with ImageButton in a ListView.
I don't know what exactly your implementation is. But it may give you a little idea...
boolean pressedImageButton = false;
myListView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(action)
{
case MotionEvent.ACTION_DOWN:
float positionX = event.getRawX();
float positionY = event.getRawY();
if(some conditions with positionX and positionY)
pressedImageButton = true;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if(pressedImageButton)
myImageButton.performClick(); // or whatever action you want to perform on that ImageButton
pressedImageButton = false;
break;
}
}
});
I hope this helps. :)
I have on my activity several ImageView's that the user can move around the screen. How can I identify which ImageView is actually selected by the user? In Xcode I can assign a unique Tag to each ImageView and than onTouch get the Tag number. Is there a similar way on Android?
this is Xcode:
UITouch *touch = [[event allTouches] anyObject];
if ([touch view].tag == 901)
{
iTouchObject = 901;
[self.view bringSubviewToFront:imgRojo1];
}
In Android Activity I have so far done: in onCreate I can assign an ID to each ImageView
ImageView selImage = (ImageView)findViewById(R.id.i904);
selImage.setId(904);
and in onTouch.MOVED I can use the ImageView with a directly assigned ID. In this case the image moves smooth below the finger on the screen.
iID = 904;
ImageView selImage = (ImageView)findViewById(iID);
BUT, how can I get the ID from the ImageView that the user has touched?
I have tried to use setOnTouchListener:
ImageView selImage = (ImageView)findViewById(R.id.i904);
selImage.setId(904);
selImage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
iID = v.getId();
ImageView selImage = (ImageView)findViewById(iID);
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on a ball
break;
case MotionEvent.ACTION_MOVE: // touch drag with the ball
// move the balls the same as the finger
selImage.setX(X-25);
selImage.setY(Y-25);
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
return true;
}});
By this I can select each ImageView and it moves, BUT, it doesn't move smooth and also the ImageView is duplicated on the screen.
Is it possible to get in the first case in the onTouch.MOVED the View and use it to get the ID with: iID = v.getId();
You can check what id your current view has and compare it with the actual resource Id.
For example:
switch (v.getId()) {
case R.id.image1:
// Do this
break;
case R.id.image2:
// ..
break;
case R.id.image3:
// ..
break;
}
You may also check out this page to read a bit more about drag-and-drop with the ChoiceDragListener instead.
UPDATE:
I have found a solution, maybe not the best optimized, but great working. Hope that it helps others of you in similar situations:
For each ImageView I am assigning an ID (setID) and setOnTouchListener. Only thing I am doing in setOnTouchListener is to assign to an integer the same number as I have used for the ID. Important is to put RETURN FALSE, this will stop the setOnTouchListener.
ImageView selImage = (ImageView)findViewById(R.id.i904);
selImage.setId(904);
selImage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
iID = 904;
return false;
}
});
I have put added the following onTouchEvent(). First thing here is to select the ImageView with the ID that was set in the integer before.
public boolean onTouchEvent(MotionEvent event) {
ImageView selImage = (ImageView)findViewById(iID);
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
selImage.setX(X-25);
selImage.setY(Y-25);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Now I can touch any of the ImageView's and move them around on the screen. Hope it helps!
I have a view in my Android app that should be updated constantly when the screen is being pressed. Most listeners I found only invalidate the view once when the user touches the screen for the first time, or when the user removes his hand from the screen.
Is there such a thing as a listener that is constantly triggered as long as the screen is touched ? Or is there any other way to do this ? I know, that sounds like something really simple, but I haven't found a way to do it.
Override onTouch() and set a flag in ACTION_DOWN. As long as ACTION_UP isn't called after that, the user is touching the screen.
boolean pressed = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
//int action = event.getAction();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
pressed = true;
break;
case MotionEvent.ACTION_MOVE:
//User is moving around on the screen
break;
case MotionEvent.ACTION_UP:
pressed = false;
break;
}
return pressed;
}
I have a custom ListView in which I have set an OnTouchListener for each list item. When the user touches the item, I use TransitionDrawable to change the background color of the item during MotionEvent.ACTION_DOWN and bring it back to normal during MotionEvent.ACTION_UP.
Now when I scroll this list, the item which is touched at the start of the scroll action changes background color. I want to avoid this behavior. So while scrolling I want to disable any change in background color. Is there a way to do this? Please see the code below:
public class ListItemOnTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
Context mContext = getActivity().getApplicationContext();
Resources res = mContext.getResources();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
TransitionDrawable transitionDown = (TransitionDrawable) res
.getDrawable(R.drawable.row_background_transition_down);
v.setBackgroundDrawable(transitionDown);
transitionDown.startTransition(350);
Log.d(TAG, "ACTION_DOWN");
return true;
case MotionEvent.ACTION_UP:
TransitionDrawable transitionUp = (TransitionDrawable) res
.getDrawable(R.drawable.row_background_transition_up);
v.setBackgroundDrawable(transitionUp);
transitionUp.startTransition(1000);
// Get list view
ListView listView = getListView();
int position = listView.getPositionForView((LinearLayout) v.getParent());
listView.performItemClick(v, position, 0);
Log.d(TAG, "ACTION_UP");
return true;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "ACTION_MOVE");
break;
case MotionEvent.ACTION_CANCEL:
Log.d(TAG, "ACTION_CANCEL");
v.setBackgroundResource(R.drawable.row_background_normal);
break;
}
return false;
}
}
When the user starts scrolling you should get an ACTION_CANCEL. Catch this and change the color back.
Instead of implementing on touch, u can implement onListItemClick(will work same as on touch) and then on that method u can write the code to change the color of the list item touched/clicked.