Android Swipe to change fragments not working

后端 未结 2 886
孤城傲影
孤城傲影 2021-01-23 13:40

I am trying to make an app where a user can swipe and change which fragment they are seeing on the screen. I can not use view pager because I want the user to be able to swipe t

2条回答
  •  北恋
    北恋 (楼主)
    2021-01-23 14:37

    First of all, you can really simplify your swipe code using droidQuery:

    //global variables
    private boolean isSwiping = false;
    private SwipeDetector.Direction swipeDirection = null;
    private View v;//set to the parent layout of the fragments.
    
    //swipe-handling code
    $.with(v).swipe(new Function() {
        @Override
        public void invoke($ droidQuery, Object... params) {
            if (params[0] == SwipeDetector.Direction.START)
                isSwiping = true;
            else if (params[0] == SwipeDetector.Direction.STOP) {
                if (isSwiping) {
                    isSwiping = false;
                    if (swipeDirection != null) {
                        switch(swipeDirection) {
                            case DOWN :
                                //TODO: Down swipe complete, so do something
                                break; 
                            case UP :
                                //TODO: Up swipe complete, so do something
                                break; 
                            case LEFT :
                                //TODO: Left swipe complete, so do something
                                break; 
                            case RIGHT :
                                //TODO: Right swipe complete, so do something (such as):
                                day++;
                                Fragment1 rightFragment = new Fragment1();
                                Bundle args = new Bundle();
                                args.putInt("day", day);
                                rightFragment.setArguments(args);
    
                                android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                                transaction.replace(R.id.fragment_container, rightFragment);
                                transaction.addToBackStack(null);
                                transaction.commit();
                                break; 
                            default :
                                break; 
                        }
                    }
                }
            }
            else {
                swipeDirection = (SwipeDetector.Direction) params[0];
            }
        }
    });
    

    You can find more on Fragment transactions here.

    Also, consider keeping an int offset variable that keeps track of the +/- offset from zero. So for instance, you could get the already-instantiated Fragments from an ArrayList, then just swap out the one at mArrayList.get(offset), and when flinging right, do offset++, and 'offset--` for left swipes.

    Edit

    As requested in the comments, this code can be used to handle swipes and a child image click:

    Include the SwipeInterceptorView in your main Layout (res/layout/main.xml):

    
    
    
    
    

    You will need to have class variables:

    SwipeInterceptorView view;//instantiated in onCreate
    ImageView fragImage;//must be instantiated when the new Fragment is transitioned in
    

    Next, include the following components in onCreate:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set main view to the main layout
        setContentView(R.layout.main);
        //get a reference to the content view
        view = (SwipeInterceptorView) findViewById(R.id.swipe_view);
        //add Swiper
        view.setSwipeListener(new SwipeListener() {
            public void onUpSwipe(View v) {
                //TODO handle up swipe
            }
            public void onRightSwipe(View v) {
                //TODO handle right swipe
            }
            public void onLeftSwipe(View v) {
                //TODO handle left swipe
            }
            public void onDownSwipe(View v) {
                //TODO handle down swipe
            }
        });
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return super.onTouch(v, event);
            }
        });
    }
    

    When the new Fragment containing the ImageView is transitioned in, you need to reference it and update the swipe interceptor's onTouch method:

    fragImage = (ImageView) fragment/* references the now non-null, on-display fragment */.getView().findViewById(R.id.yourImageId);
    int[] origin = new int[2];
    fragImage.getLocationOnScreen(origin);
    final Rect bounds = new Rect(origin[0], origin[1], fragImage.getRight(), fragImage.getBottom());
    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public void onTouch(View v, MotionEvent event) {
            if (bounds.contains(event.getRawX(), event.getRawY())) {
                return false;//now clicks will be handled by the Image.
            }
            return v.onTouchEvent(event);
        }
    });
    

提交回复
热议问题