Is there a way to make the SwipeRefreshLayout have a small deadzone so that if the user scrolls to the top and keeps scrolling, it wont immediately try bring down the pull to refresh? i would like it to have a small dead zone because the pull to refresh is interfering with a view pager in the ListView.
if the user swipes the viewpager and moves their finger down very slightly through the drag, it starts to do the pull to refresh and the swipe motion is lost and the viewpager just resets its position.
i've tried doing something like this
mSwipeRefreshLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
p1 = new Point((int) event.getX(), (int) event.getY());
else if(event.getAction() == MotionEvent.ACTION_MOVE)
p2 = new Point((int) event.getX(), (int) event.getY());
if(p1 != null && p2 != null && Math.abs(p1.y - p2.y) < 50) {
return true;
}
return false;
}
});
and
mSwipeRefreshLayout.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
if(event.getAction() == DragEvent.ACTION_DRAG_ENTERED)
p1 = new Point((int) event.getX(), (int) event.getY());
else if(event.getAction() == DragEvent.ACTION_DRAG_LOCATION)
p2 = new Point((int) event.getX(), (int) event.getY());
if(p1 != null && p2 != null && Math.abs(p1.y - p2.y) < 50) {
return true;
}
return false;
}
});
but p2 doesnt get set properly it seems so not sure what to do
Related
I want to get the X & Y coordinates of the location where i long click and set the button to this location, but i don't get it because there is no MotionEvent as with the onClick method.
private View.OnLongClickListener layoutOnTouchListener(){
return new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
RelativeLayout.LayoutParams positionRules = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
positionRules.leftMargin = (int) v.getX();
positionRules.topMargin = (int) v.getY();
mainButton.setLayoutParams(positionRules);
Log.d("X", String.valueOf(v.getX()));
return true;
}
};
}
Thats the code i tried.
You can try setonkeyListener and check whether it's long click or not
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (null != keyEvent && keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (System.currentTimeMillis() - mLastClickedTime > DEFAULT_PRESSED_DELAY) {
Log.d(TAG, "onKey: single presed");
onKeyPressed(view, keyEvent);
} else {
Log.d(TAG, "onKey: repeat pressed");
onKeyRepeatPressed(view);
}
mLastClickedTime=System.currentTimeMillis();
}
return false;
}
If it's long click take the x and y points
I have an ImageView which fills my whole Activity. I need to be able to detect 4 touch events :
Hold (longer than 400 ms)
Click
Swipe Left
Swipe Right
At the moment I am able to detect the first two using the following code :
imageView.setOnTouchListener(new View.OnTouchListener() {
private Timer timerr = new Timer();
private long LONG_PRESS_TIMEOUT = 400; // TODO: your timeout here
private boolean wasLong = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(getClass().getName(), "touch event: " + event.toString());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// HOLD DETECTED
timerr.schedule(new TimerTask() {
#Override
public void run() {
SlideShow.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}, LONG_PRESS_TIMEOUT);
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if (!isPaused && !wasLong) {
// CLICK DETECTED
timerr.cancel();
timerr = new Timer();
if (!wasLong) {
return false;
}
});
Now I am trying to use the code from this question to implement the swipe right and swipe left actions. Android Swipe on List The problem with this is that this works on listview, where you can implement an onTouchListener for the whole listview, and a seperate onItemClickListener for the list item. I do not know how to adapt this to this situation though where only one Listener is available.
Gesture Detector is the way to go.
Alternatively,
image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x1 = event.getX();
y1 = event.getY();
t1 = System.currentTimeMillis();
return true;
case MotionEvent.ACTION_UP:
x2 = event.getX();
y2 = event.getY();
t2 = System.currentTimeMillis();
if (x1 == x2 && y1 == y2 && (t2 - t1) < CLICK_DURATION) {
Toast.makeText(getActivity(), "Click", Toast.LENGTH_SHORT).show();
} else if ((t2 - t1) >= CLICK_DURATION) {
Toast.makeText(getActivity(), "Long click", Toast.LENGTH_SHORT).show();
} else if (x1 > x2) {
Toast.makeText(getActivity(), "Left swipe", Toast.LENGTH_SHORT).show();
} else if (x2 > x1) {
Toast.makeText(getActivity(), "Right swipe", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
I'm trying to call the onTouch method from a different class but I have no idea what to pass in for MotionEvent. Using null makes the app force close. Heres the code
public final class Touch {
private static final String TAG = Touch.class.getSimpleName();
public boolean onTouchEvent(MotionEvent event, Droid droid, Thread thread) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
droid.handleActionDown((int)event.getX(), (int)event.getY());
/*if (event.getY() > getHeight() - 50)
{
thread.setRunning(false);
((Activity)getContext()).finish();
}
else
{
Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
}*/
}
if (event.getAction() == MotionEvent.ACTION_MOVE)
{
// the gestures
if (droid.isTouched())
{
// the droid was picked up and is being dragged
droid.setX((int)event.getX());
droid.setY((int)event.getY());
}
}
if (event.getAction() == MotionEvent.ACTION_UP)
{
// touch was released
if (droid.isTouched())
{
droid.setTouched(false);
}
}
return true;
}
}
Thats the class, how would I call that in the main thread? Currently I'm trying:
public void Touch()
{
MotionEvent event = null;
touch.onTouchEvent(event, droid, thread);
}
As null is the only thing that I can think of to pas in.
Try:
MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, metaState);
I'm trying to implement the "swipe for action" feature - like you can see in the "new" twitter app. A closer description you find at swipe for action description.
Now, are there any ideas/solution how to implement this feature?
Thanks!
Use a GestureDetector in each row, and wrap the row contents itself in a ViewFlipper. On a swipe, switch children of the ViewFlipper.
I have a ViewSwiper that combines a GestureDetector and ViewFlipper, but it is designed to work in either direction (e.g., from the regular row, a swipe left or right would switch to the actions), which may or may not be desirable. But, it should give you an idea of how this might work.
I did something similiar to what you need - you can find some info about there. I'm doing some manual stuff there but it works nice. For your convenience here is the code I've used:
OnTouchListener gestureListener = new View.OnTouchListener() {
private int padding = 0;
private int initialx = 0;
private int currentx = 0;
private ViewHolder viewHolder;
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
padding = 0;
initialx = (int) event.getX();
currentx = (int) event.getX();
viewHolder = ((ViewHolder) v.getTag());
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
currentx = (int) event.getX();
padding = currentx - initialx;
}
if (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL) {
padding = 0;
initialx = 0;
currentx = 0;
}
if (viewHolder != null) {
if (padding == 0) {
v.setBackgroundColor(0xFF000000);
if (viewHolder.running)
v.setBackgroundColor(0xFF058805);
}
if (padding > 75) {
viewHolder.running = true;
v.setBackgroundColor(0xFF00FF00);
viewHolder.icon.setImageResource(R.drawable.clock_running);
}
if (padding < -75) {
viewHolder.running = false;
v.setBackgroundColor(0xFFFF0000);
}
v.setPadding(padding, 0, 0, 0);
}
return false;
}
};
I'm doing some maths calculations in android map activity and I need to find a position of a GeoPoint which user has clicked on the map. I understand that I need to use onTouch event handler. This is how it looks like at the moment:
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN)
{
GeoPoint pGoal = mapView.getProjection().fromPixels(
(int) event.getX(),
(int) event.getY());
DisplayInfoMessage("The screen has been touched!" + event.getX() + " AND " + event.getY() + "Latitude: "+ pGoal.getLatitudeE6()); // only for displaying test popup
}
super.onTouchEvent(event);
return true;
}
It doesn't do what I want though. Any help or hint at least greatly appreciated!
Actually this already is the answer:
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN)
{
GeoPoint pGoal = mapView.getProjection().fromPixels(
(int) event.getX(),
(int) event.getY());
DisplayInfoMessage("The screen has been touched!" + event.getX() + " AND " + event.getY() + "Latitude: "+ pGoal.getLatitudeE6()); // only for displaying test popup
}
super.onTouchEvent(event);
return true;
}