I want to move any normal view in my app along with swipe.
I am able to detect swipe using OnTouchListener in onTouch method. But am not able to move the view along with the swipe.
I want to move the view along with the swipe.
I think so that something i need to implement inside onTouch method to move the view or item along with swipe, but what i don't know.
Any help will be highly appreciated.
You just need to use view.setTranslationX(diffX) for X coordinate and view.setTranslationY(diffY) for Y coordinate while its MotionEvent.ACTION_MOVE under onTouch() method.
view.setOnTouchListener(new View.OnTouchListener() {
float downX, downY, nowX, nowY, diffX, diffY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getRawX();
downY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
nowX = event.getRawX();
nowY = event.getRawY();
diffX = nowX - downX;
diffY = nowY - downY;
v.setTranslationX(diffX);
v.setTranslationY(diffY);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
Related
I've tried many different solutions and none worked.
So, how do I drag and drop a Bitmap?
Here is a possible solution that also doesn't work, but I would love to know why:
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.our_image);
And then activate the OnTouchListener:
#Override
public boolean onTouch (View v, MotionEvent event)
{
Imageview iv = new ImageView(this);
iv.setImageBitmap(bm);
if (v == iv)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
eventX = event.getXPrecision();
eventY = event.getYPrecision();
break;
case MotionEvent.ACTION_MOVE:
distX = event.getX() - eventX;
distY = event.getY() - eventY;
iv.setX(distX + eventX);
iv.setY(distY + eventY);
eventX = event.getXPrecision();
eventY = event.getYPrecision();
}
return true;
}
return false;
}
and when I move the ImageView, I update the Bitmap's location to it's coordinates
by creating a canvas and redrawing the Bitmap:
Paint p = new Paint()
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(bm, iv.getLeft(), iv.getTop(), p);
Do I need to put invalidate() here? And if so, why?
Any kind of help would be greatly appreciated! ^_^
I thought this is a pretty relevant and common question, but I couldnt find an answer.
At the moment I have this method:
public boolean onTouchEvent (MotionEvent evt){
if (evt.getAction() == MotionEvent.ACTION_DOWN) {
do stuff ...
}
}
So if the user taps on the screen (wherever) the code is executed. Now I want the distinction between the right side of the display and the left side (left side means --> go back).
You can do this many ways. Here is one of them:
Attach onTouch listener to the view, which stretches to its edges. (For example your RelativeLayout which holds rest of views)
private View.OnTouchListener onTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
float halfOfAScreen = mainLayout.getMaxWidth() / 2;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float fingerPosition = event.getX();
if(fingerPosition < halfOfAScreen) {
onBackPressed();
}
return true;
default:
return false;
}
}
};
Refer to this post on how to get touch position.
It seems in your case you will use
int x = (int)event.getX();
int y = (int)event.getY();
and work within the bounds of your layout that you want the app to react to.
I posted a question yesterday [ Swipable Linear/Relative Layout ]. The question did not get any answers. Meanwhile, I tried to solve my own problem. What I did is that I used the OnTouchListener to detect swipe and thus toggle the scientific part of the calculator (Read the question I posted earlier to get a clear idea) I used the following code :-
RelativeLayout layout = (RelativeLayout)findViewById(R.id.advanced);
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
return true;
}
case MotionEvent.ACTION_MOVE: {
upX = event.getX();
float deltaX = downX - upX;
swipe((int) deltaX);
return true;
}
case MotionEvent.ACTION_UP: {
downX = 0;
}
}
return true;
}
and the swipe method is :-
private void swipe(int distance) {
RelativeLayout layout = (RelativeLayout)findViewById(R.id.advanced);
LinearLayout.LayoutParams head_params = (LinearLayout.LayoutParams)layout.getLayoutParams();
head_params.setMargins(-distance, 0, 0, 0); //substitute parameters for left, top, right, bottom
layout.setLayoutParams(head_params);
}
The code works fine and achieves what it was meant to be till a certain extent. The problem is that, the swipe is buggy,i.e., it kind of flashes when I swipe it and also, it is very slow. Please tell me how to implement this correctly. Shall I use ViewPager or something else. Please enlighten me. Thanks
The reason this is buggy is because you've registered a touch listener on the view you're moving as well. This causes the touch listener to return 'twitchy' values. One approach you could take is putting the listener on a parent view that is stationary, and using that to update the child view. I would also recommend looking into using a GestureDetector instead, it does most of the touch logic for you and provides some very useful methods through a listener.
I have a listview and I set an onClickListener and an onTouchListener. The click listener for when they click on an item, I had just this and everything thing worked fine. But, when I added the touch listener to watch for left and right swipes, it won't let me scroll anymore.
listview.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event){
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
historicX = event.getX();
historicY = event.getY();
break;
case MotionEvent.ACTION_UP:
if(event.getX() - historicX < -DELTA){
slidingLeft(event.getX(),event.getY());
return true;
}
else if(event.getX() - historicX > DELTA){
slidingRight(event.getX(), event.getY());
return true;
}
break;
default: return true;
}
return false;
}
});
How can I have to able to scroll through the listview again. Is there another listener I could add to do this, or could I modify the onTouchListener to watch for scrolls too?
You should use GestureDetector .
You can use example from here, it is very clear.
https://stackoverflow.com/a/12938787/1374065
Is there any way to disable getView() method in ListView Adapter when I use MotionEvent.ACTION_MOVE in OnTouchListener??
I need to do because i try move my conteiner(inside is my ListView) by finger. I use for this method setLayoutParams:
private class MyListener implements View.OnTouchListener{
#Override
public boolean onTouch(View v, MotionEvent event) {
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
RelativeLayout.LayoutParams paramsUp = (RelativeLayout.LayoutParams) myBar.getLayoutParams();
paramsUp.topMargin = 0;
myBar.setLayoutParams(paramsUp);
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams paramsMove = (RelativeLayout.LayoutParams) myBar.getLayoutParams();
paramsMove.topMargin = Y - yDelta;
myBar.setLayoutParams(paramsMove);
break;
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) myBar.getLayoutParams();
yDelta = Y - lParams.leftMargin;
break;
}
//myBar.invalidate();
return true;
}
}
When I moving container, everything happens very slowly. This is because the container changes its size and all objects are loaded again.
And my second question:
How to disbale scroll when I move ListView item? For example: move on left or move on right.
Thx