Reputation: 9295
I have a Fragment in which i have a ViewFlipper that contains two ScrollViews. I want to detect swipe on ViewFlipper and change the ScrollView. I have tried to do this:
public class HomeFragment extends Fragment implements OnGestureListener
{
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_TRESHOLD_VELOCITY = 200;
private View thisFragment;
private Animation slideLeftIn;
private Animation slideLeftOut;
private Animation slideRightIn;
private Animation slideRightOut;
private GestureDetector detecture;
private ViewFlipper riddleFlipper;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
thisFragment = LayoutInflater.from(getActivity()).inflate(R.layout.home_fragment, null);
//views
riddleFlipper = (ViewFlipper) thisFragment.findViewById(R.id.home_fragment_riddle_flipper_ViewFlipper);
slideLeftIn = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_left_in);
slideLeftOut = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_left_out);
slideRightIn = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_right_in);
slideRightOut = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_right_out);
//sliding
detecture = new GestureDetector(getActivity(), this);
riddleFlipper.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View view, MotionEvent event)
{
return detecture.onTouchEvent(event);
}
});
return thisFragment;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public boolean onDown(MotionEvent e)
{
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if(Math.abs(e1.getY() - e2.getY()) > 250)
return false;
if((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_TRESHOLD_VELOCITY)
{
riddleFlipper.setInAnimation(slideLeftIn);
riddleFlipper.setOutAnimation(slideLeftOut);
riddleFlipper.showNext();
}
else if((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_TRESHOLD_VELOCITY)
{
riddleFlipper.setInAnimation(slideRightIn);
riddleFlipper.setOutAnimation(slideRightOut);
riddleFlipper.showNext();
}
return false;
}
@Override
public void onLongPress(MotionEvent e)
{
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY)
{
return false;
}
@Override
public void onShowPress(MotionEvent e)
{
}
@Override
public boolean onSingleTapUp(MotionEvent e)
{
return false;
}
}
It seems that riddleFlipper does not "feel" any touch events.
EDIT
I have changed the code to this:
public class HomeFragment extends Fragment implements OnGestureListener
{
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_TRESHOLD_VELOCITY = 200;
private View thisFragment;
private ImageView userImage;
private ViewFlipper riddleFlipper;
private RelativeLayout usersRiddleLinearLayout;
private RelativeLayout favoriteLinearLayout;
private Animation slideLeftIn;
private Animation slideLeftOut;
private Animation slideRightIn;
private Animation slideRightOut;
private GestureDetector detecture;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
thisFragment = LayoutInflater.from(getActivity()).inflate(R.layout.home_fragment, null);
//views
riddleFlipper = (ViewFlipper) thisFragment.findViewById(R.id.home_fragment_riddle_flipper_ViewFlipper);
userImage = (ImageView) thisFragment.findViewById(R.id.home_fragment_user_image_ImageView);
usersRiddleLinearLayout = (RelativeLayout) thisFragment.findViewById(R.id.home_fragment_users_riddles_LinearLayout);
favoriteLinearLayout = (RelativeLayout) thisFragment.findViewById(R.id.home_fragment_favorite_riddles_LinearLayout);
slideLeftIn = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_left_in);
slideLeftOut = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_left_out);
slideRightIn = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_right_in);
slideRightOut = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_right_out);
//sliding
detecture = new GestureDetector(getActivity(), this);
usersRiddleLinearLayout.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View view, MotionEvent event)
{
return detecture.onTouchEvent(event);
}
});
favoriteLinearLayout.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View view, MotionEvent event)
{
return detecture.onTouchEvent(event);
}
});
return thisFragment;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public boolean onDown(MotionEvent e)
{
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
if(Math.abs(e1.getY() - e2.getY()) > 250)
return false;
if((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_TRESHOLD_VELOCITY)
{
Toast.makeText(getActivity(), "a", Toast.LENGTH_SHORT).show();
riddleFlipper.setInAnimation(slideLeftIn);
riddleFlipper.setOutAnimation(slideLeftOut);
riddleFlipper.showNext();
}
else if((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_TRESHOLD_VELOCITY)
{
Toast.makeText(getActivity(), "b", Toast.LENGTH_SHORT).show();
riddleFlipper.setInAnimation(slideRightIn);
riddleFlipper.setOutAnimation(slideRightOut);
riddleFlipper.showNext();
}
return false;
}
@Override
public void onLongPress(MotionEvent e)
{
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY)
{
return false;
}
@Override
public void onShowPress(MotionEvent e)
{
}
@Override
public boolean onSingleTapUp(MotionEvent e)
{
return false;
}
}
Now the touch event is recored but it's never gets to the onFling
. WHY???
Thanks
Upvotes: 2
Views: 5110
Reputation: 790
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.charts,container,false);
viewFlipper = (ViewFlipper) view.findViewById(R.id.viewFlipper);
viewFlipper.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
lastX = motionEvent.getX();
return true;
case MotionEvent.ACTION_UP:
float currentX = motionEvent.getX();
if(lastX < currentX)
{
if(viewFlipper.getDisplayedChild() == 0) {
return true;
}
viewFlipper.showNext();
}else if (lastX > currentX){
if(viewFlipper.getDisplayedChild() == 1) {
return true;
}
viewFlipper.showPrevious();
}
return true;
}
return false;
}
});
}
This worked for me.
Upvotes: 1
Reputation: 1859
I've had better luck initializing my event handlers in the onActivityCreated method. Try putting your touch listeners there.
Upvotes: 0
Reputation: 20416
What if you try to override onTouchEvent(MotionEvent event)
of your activity and call detecture.onTouchEvent(event)
from there, instead of using OnTouchListener
?
Upvotes: 2