Disti
Disti

Reputation: 1513

Android: Multiple pages withing a single activity

I'm a beginner Android developer (I'm a Windows developer since 1995) and I'm developing my first app. I have a two dimensional array of data (something like a[2][]). Basically it represents three different set of data that need to be represented on the device screen. Unfortunately, while two of them can be represented using a grid, the third set must be represented in a completely different way. So what I need is a three-paged activity; in the first two I would like to use a common layout, populated with the needed data, while in the third page I have to use a completely different layout.

I found this: ViewPager Without Fragments, but unfortunately I am confused on where to place code to handle user input on the three pages.

Being a beginner on Android I'm actually a bit confused on what should be the general approach in such a situation. In my usual developement experience I would create a window with a tabbed control, three tabs, grids in the first two and some custom control in the third. These three controls would live in the same "scope" (my window) and would be populated during window loading.

I understand that in Android I have to follow a completely different approach, but, as I said I'm confused: fragments? No fragments? What else?

Thank you!

Upvotes: 0

Views: 8707

Answers (2)

Nathan Teyou
Nathan Teyou

Reputation: 2136

To implement multiple pages within the same activity, you need to use fragments. In your case, we will need 3 fragments. Your activity layout file should contain a ViewPager which will hold the fragments in the activity. You can also add a TabLayout if you want the fragments to also be accessible via tabs. A sample Activity layout can be as follows:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="your.package.name.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:contentInsetLeft="0dp"
            app:contentInsetStart="0dp"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:titleTextColor="@color/colorAccent"
            />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="fill"
            android:background="@color/grey"
            app:tabGravity="fill"
            app:tabIndicatorColor="@color/colorAccent"
            app:tabIndicatorHeight="5dp"
            app:tabSelectedTextColor="@color/colorAccent"
            app:tabTextColor="@color/black"/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>


</android.support.design.widget.CoordinatorLayout>

After doing this, you need to create a FragmentPagerAdapter class in your Activity Class. This adapter will manage the instantiation of your ViewPager which holds the fragments in the Activity. Here is a sample FragmentPagerAdapter SubClass

public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.

            Log.d(LOG_TAG, "postion " + position);
            if (position == 0) {
                return Fragment1.newInstance(position + 1);
            } else if (position == 1) {
                return Fragment2.newInstance(position + 1);
            } else {
                return Fragment3.newInstance(position + 1);
            }

        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                case 0:
                    return "Fragment1";
                case 1:
                    return "Fragment2";
                case 2:
                    return "Fragment3";


            }
            return null;
        }

    }

This done, you can now get the reference to the ViewPager in the Activity onCreate method and the set the ViewPager adapter as follows

@Override
    protected void onCreate(Bundle savedInstanceState) {

ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
       SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mSectionsPagerAdapter);

// setting the views to be accessed through tabs
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int currentTab = tab.getPosition();
                viewPager.setCurrentItem(currentTab);

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });


 }

Hope this clear for you. For more information, you can also check here

Upvotes: 2

Karakuri
Karakuri

Reputation: 38595

You can handle user input within your Activity, or you can break it up into Fragments. Both are described below.

Activity

The problem is usually you obtain references to Views in your layout during the Activity's onCreate() method and perform whatever setup (adding OnClickListeners, etc), but that's not really possible in this case because at that moment your ViewPager hasn't loaded any pages and the views on those pages aren't in the view hierarchy yet. (Android's view and layout system can be rather confusing when ViewPagers are involved).

Instead you would have to obtain the references and perform your setup inside of instantiateItem() of your adapter, and presumably invalidate those references in destroyItem().

Fragments

The issue described above is likely the reason Fragments are supported directly in the framework (using FragmentPagerAdapter or FragmentStatePagerAdapter). With a Fragment for each page, you can obtain references to views on that page and perform setup inside of onCreateView() (or onViewCreated()), and the business logic could also be encapsulated in the fragment. Basically, you don't have to worry about the existence of the views relative to the timing of these callbacks, unlike with the Activity's onCreate().

One other benefit is that by having logic encapsulated in separate Fragments, you have a degree of modularity with your app. If you can envision your app on a larger screen having perhaps two (or even all three) of your "pages" visible at once, then it's probably better to use Fragments from the beginning.

Upvotes: 1

Related Questions