vlio20
vlio20

Reputation: 9295

ViewFlipper inside of fragment

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

Answers (3)

Estevex
Estevex

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

wyoskibum
wyoskibum

Reputation: 1859

I've had better luck initializing my event handlers in the onActivityCreated method. Try putting your touch listeners there.

Upvotes: 0

sergej shafarenka
sergej shafarenka

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

Related Questions