Search code examples
androidandroid-layoutandroid-tabs

Swipe between screens inside tabs in android


There are 4 tabs in my app and each tab contains 3 screens within that, i want to switch between screens using swipe gesture:

enter image description here

public class AndroidTabLayoutActivity extends TabActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    TabHost tabHost = getTabHost();

    // Tab for Photos
    TabSpec photospec = tabHost.newTabSpec("Photos");
    photospec.setIndicator("Photos", getResources().getDrawable(R.drawable.icon_photos_tab));
    Intent photosIntent = new Intent(this, PhotosActivity.class);
    photospec.setContent(photosIntent);

    // Tab for Songs
    TabSpec songspec = tabHost.newTabSpec("Songs");
    // setting Title and Icon for the Tab
    songspec.setIndicator("Songs", getResources().getDrawable(R.drawable.icon_songs_tab));
    Intent songsIntent = new Intent(this, SongsActivity.class);
    songspec.setContent(songsIntent);

    // Tab for Videos
    TabSpec videospec = tabHost.newTabSpec("Videos");
    videospec.setIndicator("Videos", getResources().getDrawable(R.drawable.icon_videos_tab));
    Intent videosIntent = new Intent(this, VideosActivity.class);
    videospec.setContent(videosIntent);

 // Tab for Videos
    TabSpec otherspec = tabHost.newTabSpec("Others");
    otherspec.setIndicator("Others", getResources().getDrawable(R.drawable.icon_others_tab));
    Intent othersIntent = new Intent(this, OthersActivity.class);
    otherspec.setContent(othersIntent);

    // Adding all TabSpec to TabHost
    tabHost.addTab(photospec); // Adding photos tab
    tabHost.addTab(songspec); // Adding songs tab
    tabHost.addTab(videospec); // Adding videos tab
    tabHost.addTab(otherspec); // Adding videos tab
}

}

this is my main.xml file for the above java code

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />

    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@android:id/tabs"
        android:layout_alignParentTop="true" />

</RelativeLayout>





this is my photos activity that appears in one of my tab

public class PhotosActivity extends Activity{

private GestureDetector gestureDetector;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.photos_layout);
    gestureDetector = new GestureDetector(new SwipeGestureDetector());
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    if (gestureDetector.onTouchEvent(event)) {
        return true;
    }
    return super.onTouchEvent(event);
}

private void onLeftSwipe(){
    Toast.makeText(this, "Left Swipe", Toast.LENGTH_LONG).show();
    Log.d("Gesture", "Left Swipe");
}

private void onRightSwipe(){
    Toast.makeText(this, "Right Swipe", Toast.LENGTH_LONG).show();
    Log.d("Gesture", "Right Swipe");
}

class SwipeGestureDetector extends SimpleOnGestureListener{

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 200;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {

        try {
            float diffAbs = Math.abs(e1.getY() - e2.getY());
            float diff = e1.getX() - e2.getX();

            if (diffAbs > SWIPE_MAX_OFF_PATH)
                return false;

            // Left swipe
            if (diff > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                PhotosActivity.this.onLeftSwipe();

                // Right swipe
            } else if (-diff > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                PhotosActivity.this.onRightSwipe();
            }

        } catch (Exception e) {
            Log.e("YourActivity", "Error on gestures");
        }
        return false;
    }


}

}


Solution

  • Is there any reason in order to avoid using a ViewPager? I don't know why are you trying to implement your own swipe using gesture detector. You can use a viewpager, customize its swipe behaviour to change to next/previous tab when swiping right/left and do the same when clicking on a tab, changing to next/previous page of the ViewPager.

    Edit --> you can see and example here: lateral navigation using tabs and ViewPager

    I don't know why you are not using the native actionbar tabs, but anyway you can use a ViewPager if you want to keep on your design.

    I don't know if I am really miss-understanding something but... I think you can add:

    <android.support.v4.view.ViewPager xmlns:android="schemas.android.com/apk/res/android"; android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" />

    in your layout xml.

    Remember to set your desired width and height in case you still prefer to not use the native actionbar tabs.

    If you use the native tabs, then in your onTabSelected you will change to next view setting the next item to the ViewPager:

    `public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {             
    // When the tab is selected, switch to the             
    // corresponding page in the ViewPager.             mViewPager.setCurrentItem(tab.getPosition());         
    }` 
    

    and in the listener of the ViewPager:

    `mViewPager.setOnPageChangeListener(
                new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        // When swiping between pages, select the
                        // corresponding tab.
                        getActionBar().setSelectedNavigationItem(position);
                    }
                });
    `
    

    you select the tab after swiping.

    In case you want to keep on using your tabs navigation, you can do the same, taking into account those listeners. The one of the viewpager, will reflect a new selection of one of your tabs, and the listener of your tab, will change the page of the ViewPager.