Consider the following diagram below (for a better understanding of my problem). 
As you can see, I am looking at a list view surrounded by indents. Now, if the user clicks on the list item, as the action I provided, this is a light blue background color. My app is now dealing with onTouch events to identify actions like
- Click
- Swipe left to right
- Right to left Swipe
Here is my code
public boolean onTouch(View v, MotionEvent event) { if(v == null) { mSwipeDetected = Action.None; return false; } switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { downX = event.getRawX(); downY = event.getRawY(); mSwipeDetected = Action.Start; // Find the child view that was touched (perform a hit test) Rect rect = new Rect(); int childCount = listView.getChildCount(); int[] listViewCoords = new int[2]; listView.getLocationOnScreen(listViewCoords); int x = (int) event.getRawX() - listViewCoords[0]; int y = (int) event.getRawY() - listViewCoords[1]; View child; for (int i = 0; i < childCount; i++) { child = listView.getChildAt(i); child.getHitRect(rect); if (rect.contains(x, y)) { mDownView = child; break; } } return false; // allow other events like Click to be processed } case MotionEvent.ACTION_MOVE: { upX = event.getRawX(); upY = event.getRawY(); float deltaX=0,deltaY=0; deltaX = downX - upX; deltaY = downY - upY; if(deltaY < VERTICAL_MIN_DISTANCE) { setTranslationX(mDownView, -(deltaX)); setAlpha(mDownView, Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / listView.getWidth()))); return false; } else { forceBringBack(v); } return false; } case MotionEvent.ACTION_UP: { stopX = event.getX(); float stopValueY = event.getRawY() - downY; float stopValue = stopX - downX; if(!mDownView.isPressed()) { forceBringBack(mDownView); return false; } boolean dismiss = false; boolean dismissRight = false; if(Math.abs(stopValue)<10) { mSwipeDetected = Action.Start; } else { mSwipeDetected = Action.None; } String log = ""; Log.d(log, "Here is Y" + Math.abs(stopValueY)); Log.d(log, "First Comparison of Stop Value > with/4" + (Math.abs(stopValue) > (listView.getWidth() /4))); Log.d(log, "Second Comparison " + (Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE)); Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value " + stopValue); if((Math.abs(stopValue) > (listView.getWidth() /4))&&(Math.abs(stopValueY)<VERTICAL_MIN_DISTANCE)) { dismiss = true; dismissRight = stopValue > 0; if(stopValue>0) { mSwipeDetected = Action.LR; } else mSwipeDetected = Action.RL; } Log.d(log, "Action Detected is " + mSwipeDetected + " with Stop Value after dissmiss" + stopValue); if(dismiss) { if(dismissRight) mSwipeDetected = Action.LR; else mSwipeDetected = Action.RL; animate(mDownView) .translationX(dismissRight ? listView.getWidth() : - listView.getWidth()) .alpha(0) .setDuration(mAnimationTime) .setListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { } }); } else { animate(mDownView) .translationX(0) .alpha(1) .setDuration(mAnimationTime) .setListener(null); } break; } } return false; }
As you can see, I define the completed action in MotionEvent.ACTION_UP and set the Enum Action value accordingly. This logic works like a talisman if the user does not cross the border of the list view.
Now, if the user, moving (or, in particular), moving his finger on the list item, moves from blue to orange, MotionEvent.ACTION_UP will not be passed to listview, which causes my code to not make a decision due to translationX () and setAlpha ( ), since in this case the action is not defined, this particular list item becomes empty.
The problem does not stop here, because, I do not inflate the view every time, the same line of translationX () inflates every time, leading to multiple occurrence of an empty / white list item.
Is there anything I can do so that even if I did not encounter MotionEvent.ACTION_UP, I could still make some kind of decision?
Thank you
android android-listview listview
Paras Apr 03 '13 at 23:10 2013-04-03 23:10
source share