Written by Brightec Team
Jan 23, 2014

Simple multi pane in Android - Pt 2

In the second part of this article we look at how to add interactions to the split screen layout

Now let's make it work

In part 1 of this article, we created some layouts for a multi-pane screen using fragments, now it’s time to add some functionality. More specifically, we want to hide/show the first pane (Alpha) with the other pane (Omega) behind it on demand. Let’s review how it should behave:

  • Show the Alpha pane when the Omega pane is swiped right.
  • Hide the Alpha pane when we touch the Omega pane.
  • Hide the Alpha pane when we swipe the Omega pane left.

Open up MainActivity.java class and add two methods to it:

/**
 * Method to hide the Alpha pane
 */
private void hideAlphaPane() {
	View alphaPane = findViewById(R.id.alpha);
	if (alphaPane.getVisibility() == View.VISIBLE) {
		alphaPane.setVisibility(View.GONE);
	}		
}

/**
 * Method to show the Alpha pane
 */
private void showAlphaPane() {
	View alphaPane = findViewById(R.id.alpha);
	if (alphaPane.getVisibility() == View.GONE) {
		alphaPane.setVisibility(View.VISIBLE);
	}
}

These two methods handle locating the Alpha pane and hiding/showing it respectively. It does this by simply finding the view with the id of alpha (findViewById(R.id.alpha);) and then setting its visibility.

We’ll call these methods whenever we want to hide/show the pane. Next we need to determine if the device is Landscape or portrait as the hiding/showing of the Alpha pane should only work for portrait mode. Add the following lines in the onCreate method after setContentView():

int screenOrientation = getResources().getConfiguration().orientation;
if (screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
// Code to run whilst device is portrait goes here
}

In this method we want to start off by hiding the Alpha pane:

int screenOrientation = getResources().getConfiguration().orientation;
if (screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
hideAlphaPane();
}

Now we’re ready to detect the user’s gestures

In order to distinguish between left and right swipe gestures we need to implement our own OnTouchListener.

I found this solution on StackOverflow, which does a great job of detecting different gesture types. Using this code, create a new file called OnSwipeTouchListener.java and paste the following code into it (Being sure to include the correct imports):

/**
 * Detects left and right swipes across a view.
 */
public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public void onSwipeLeft() {
    }

    public void onSwipeRight() {
    }

    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
      
    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_DISTANCE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        	
        	
            float distanceX = e2.getX() - e1.getX();
            float distanceY = e2.getY() - e1.getY();
            if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                if (distanceX > 0)
                    onSwipeRight();
                else
                    onSwipeLeft();
                return true;
            }
            return false;
        }
    }
}

We’ll now use this class to detect swipes and touches on our panes. Head back to your MainActivity class and add the following code (making sure to import your new class at the top):

if (screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
	hideAlphaPane();
	
	View omegaPane = findViewById(R.id.omega); 
	omegaPane.setOnTouchListener(new OnSwipeTouchListener(this) {
		@Override
		public void onSwipeLeft(){
			hideAlphaPane();
			super.onSwipeLeft();
		}
		
		@Override
		public void onSwipeRight(){
			showAlphaPane();
			super.onSwipeRight();
		}
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			hideAlphaPane();
			return super.onTouch(v, event);
		}
	});
}

Here, we’re locating the omega pane and telling it to listen out for any swipe or touch gestures using our extended OnTouchListener class. If it detects a gesture then it will run the relevant code.

As you can see, we’ve set it up so that right swipes show the Alpha pane and left swipes & on touches hide it. If all has gone well, this should now be a fully functioning multi pane layout which simulates the iOS Split View controller.

Please feel free to tweet me any questions or suggestion at @andyhails

I’ve uploaded the code used in the project to Github so please feel free to take it, fork it and hack it.

This article was originally written for Brightec by Andy Hails

Previous Post

Simple multi pane in Android - Pt 1

Top