I need some tutorials on Drag and Drop a Button in Android. I mean, I have some buttons in a row and when I Long press any of the button than i can reposition the selected button in between my existing buttons and all other buttons moves aside.
Can anybody provide some nice tutorials or guides for this.
Thanks
Call below listener in button:
myOnTouchListener = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent me){
if (me.getAction() == MotionEvent.ACTION_DOWN){
oldXvalue = me.getX();
oldYvalue = me.getY();
}else if (me.getAction() == MotionEvent.ACTION_MOVE ){
LayoutParams params = new LayoutParams(v.getWidth(), v.getHeight(),(int)(me.getRawX() - (v.getWidth() / 2)), (int)(me.getRawY() - (v.getHeight())));
v.setLayoutParams(params);
}
return true;
}
};
Related
Is it possible? I like to drag the floating button across the screen anywhere the user want. Like make the floating button movable. For example if the user wants it on the top - right , he will drag the button to the top-right of the screen.
I wonder if it's possible. If so, how?
Yes, you can move views across the screen by setting its x and y coordinates.
So, in your case, as you want to move floating button on the screen according to users inputs(Drag and drop), you have to get the coordinates of user touch on the screen using MotionEvent.ACTION_MOVE action and set that coordinates to your button at the same time.
Try the following code:
yourFloatingButton.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent me){
if (me.getAction() == MotionEvent.ACTION_DOWN){
oldXvalue = me.getX();
oldYvalue = me.getY();
Log.i(myTag, "Action Down " + oldXvalue + "," + oldYvalue);
}else if (me.getAction() == MotionEvent.ACTION_MOVE ){
LayoutParams params = new LayoutParams(v.getWidth(), v.getHeight(),(int)(me.getRawX() - (v.getWidth() / 2)), (int)(me.getRawY() - (v.getHeight())));
v.setLayoutParams(params);
}
return true;
}
});
Hope it helps you!
I am trying to implement my own drag and drop with touch view events. I want to trigger dragging with long click, in onLongClick i create view shadow as bitmap and this bitmap is set to imageview. This imageview i want to drag. My problem is, that imageview is not responding to touch events immediately after that long click event. I have to stop touching screen and tap to imageview again and then my image is moving.
Some relevant code:
mCategoryNews.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
v.setVisibility(View.INVISIBLE);
ImageView shadow = (ImageView) getView().findViewById(R.id.imgViewShadow);
shadow.setLayoutParams(new FrameLayout.LayoutParams(v.getWidth(), v.getHeight()));
shadow.setImageBitmap(Utils.loadBitmapFromView(v));
shadow.bringToFront();
((FrameLayout.LayoutParams) shadow.getLayoutParams()).leftMargin = rowCategories1.getLeft();
((FrameLayout.LayoutParams) shadow.getLayoutParams()).topMargin = rowCategories1.getTop();
return true;
}
});
private View.OnTouchListener mDragShadowTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "onTouch");
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "action move");
int x = (int) event.getRawX();//- rowCategories1.getLeft() - v.getWidth() / 2;
int y = (int) event.getRawY();//- rowCategories1.getTop() - v.getHeight();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mRowWidth / 2, mRowHeight);
params.setMargins(x, y, 0, 0);
v.setLayoutParams(params);
break;
case MotionEvent.ACTION_DOWN:
break;
}
return true;
}
};
no log output is present while i am still holding finger on screen after long tap.
This is a late answer, but I had a similar problem and found this solution:
Pass the MotionEvent to the view that should take it over via the dispatchTouchEvent method.
View myView = findViewById(R.id.myView);
#Override
public boolean onTouchEvent(MotionEvent event) {
myView.dispatchTouchEvent(event);
}
After the MotionEvent is passed, myView takes over and responds to new touch events.
If you return true in onLongClick() it means the callback has consumed the event and thus it is not propagated further. If you return false, then it will reach down to the child views. (I assume the touch listener is set on the shadow ImageView).
I believe to delegate try returning false
I have a ViewPager of images, and I want to make it slide in the following way:
If I click on the right (left) side of the screen, go to previous (next) image. It's like the screen is two halves and each half moves to a direction on click.
How can I implement this?
You can get Disaplay width
Then you can override onTouchEvent in your viewpager.
When you get MotionEvent object - you can get 'tap' coordinates and you will be able to understand on wich side of screen user clicked and handle it.
Set on touch listener for your ViewPager or contentview of ViewPager item.
Take the half of the screen/view width, check if event.getX() is greater than the half value, if so, go to next, otherwise to the previous.
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_DOWN){
mDownX = ev.getX();
mDownY = ev.getY();
isOnClick = true;
}else if(ev.getAction() == MotionEvent.ACTION_UP ){
if (isOnClick ) {
if(ev.getX() > mViewPager.getWidth()/2) {
//go to next
}else{
//go to previous
}
return true;
}
}else if(ev.getAction() == MotionEvent.ACTION_MOVE){
if (isOnClick && (Math.abs(mDownX - ev.getX()) > DRAG_THRESHOLD || Math.abs(mDownY - ev.getY()) > DRAG_THRESHOLD)) {
isOnClick = false;
return false;
}
}
return false
}
I am using view pager to swipe between the views in Android.
Now I need to capture tap event for each of the views. when I override the touch listener to capture the tap event, the swipe action doesn't happen and the screen remains in the first page itself. How do I add touch listener to view pager?
Code:
viewPager.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event)
{
mDetector.onTouchEvent(event);
return true;
}});
For the above code I am able to capture tap event, but the swipe action becomes Impossible.
Here i leave you a snippet from my code to detect a "click" on the OnTouchListener, i hope it helps
mImagePager.setOnTouchListener(new OnTouchListener() {
private float pointX;
private float pointY;
private int tolerance = 50;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_MOVE:
return false; //This is important, if you return TRUE the action of swipe will not take place.
case MotionEvent.ACTION_DOWN:
pointX = event.getX();
pointY = event.getY();
break;
case MotionEvent.ACTION_UP:
boolean sameX = pointX + tolerance > event.getX() && pointX - tolerance < event.getX();
boolean sameY = pointY + tolerance > event.getY() && pointY - tolerance < event.getY();
if(sameX && sameY){
//The user "clicked" certain point in the screen or just returned to the same position an raised the finger
}
}
return false;
}
});
We can use Gestures (Link1, Link2):
public boolean onTouchEvent (MotionEvent ev)
Hope this helps!
Nancy, you don't need to manually override the Page swipes or the touch events. Just add the pages to the ViewPager and the ViewPager will automatically take care of swiping.
You do, however, have to attach touch listeners to the object in each page. So if Page 1 has a Linear Layout with many buttons and you need to find out when those buttons are clicked, you need to attach OnClickListeners for each of those buttons.
Do let me know your use case so we can better understand, why you need to find out when a page has been clicked!
Just to add to Jorge's great answer, you may just use distance instead of sameX and sameY, which is a bit more elegant. Sample:
// Ignore events that are swipes rather then touches
float distX = event.getX() - pointX;
float distY = event.getY() - pointX;
double dist = Math.sqrt(distX * distX + distY * distY);
if (dist > tolerance) {
return false;
}
Put the click event on the item view of the viewpager inside the viewPagerAdapter in the method instantiateItem like -
#Override
public Object instantiateItem(ViewGroup container, final int position) {
// Declare Variables
ImageView jive_image;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.list_item_viewpager, container,
false);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
// Add viewpager_item.xml to ViewPager
((ViewPager) container).addView(itemView);
return itemView;
}
I have to drag and i am not able to drag it perfectly:
The issues are:
1) I have to drag two to three times to bring that to desired position.Hence textview is not following the finger movement smoothly.
2)If i move textview in upward direction its only going downwards.
I am providing the code of textview on touch event.Please help.Thanks in advance.
final TextView t=(TextView)findViewById(R.id.textView4);
t.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent me) {
// TODO Auto-generated method stub
float x = me.getX();
float y = me.getY();
if (me.getAction() == MotionEvent.ACTION_DOWN) {
status = START_DRAGGING;
}
if (me.getAction() == MotionEvent.ACTION_UP) {
status = STOP_DRAGGING;
t.setPadding((int) me.getX(), (int) me.getY(), 10, 10);
Log.i("Drag", "Stopped Dragging");
} if (me.getAction() == MotionEvent.ACTION_MOVE) {
if (status == START_DRAGGING) {
System.out.println("Dragging");
t.setPadding((int) me.getX(), (int) me.getY(), 10, 10);
t.invalidate();
}
}return true;
}});
Perhaps you are not moving Views the way they are supposed to, in Android?
setPadding() is not the best way to go about it.
Here is an alternative way of Drag and Drop for Views