简体   繁体   中英

ViewPager + TabLayout with NavigationDrawer in every Activity - Issue

I encountered a problem that I didn't managed to solve: I have a MainActivity where there's a NavigationDrawer that allows me to go to three different activities. Those extend the MainActivity so I get the Drawer in every activity. In the same MainActivity, I put a TabLayout with three tab Fragments .

The problem I'm facing is that whenever I go to one of the three activity from the drawer layout, I don't get the layout xml attached to Activity1 but instead I get again the TabLayout with the Fragments. How can I solve this?

The result should look like Google Play app.

Here's my MainActivity :

public class MainActivity extends AppCompatActivity {

DrawerLayout mDrawerLayout;
ListView mDrawerList;
ActionBarDrawerToggle mDrawerToggle;
CollectionPagerAdapter mCollectionPagerAdapter;
ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);

    TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
    mTitle.setText(R.string.app_name);
    setSupportActionBar(toolbar);

    assert getSupportActionBar() != null;

    this.getSupportActionBar().setDisplayShowTitleEnabled(false);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);

    Button button1 = (Button)findViewById(R.id.button1); //this is inside the drawer layout
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this, Activity1.class);
            startActivity(intent);
        }
    });

    mDrawerToggle = new ActionBarDrawerToggle(this,
            mDrawerLayout,
            null,
            R.string.drawer_open,
            R.string.drawer_close) {
        public void onDrawerClosed(View v) {
            super.onDrawerClosed(v);
            invalidateOptionsMenu();
            syncState();
        }

        public void onDrawerOpened(View v) {
            super.onDrawerOpened(v);
            invalidateOptionsMenu();
            syncState();
        }
    };

    mDrawerLayout.addDrawerListener(mDrawerToggle);
    mDrawerToggle.setDrawerIndicatorEnabled(false); 
    mDrawerToggle.syncState();

    mCollectionPagerAdapter = new CollectionPagerAdapter(
            getSupportFragmentManager());


    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mCollectionPagerAdapter);

    TabLayout tabs = (TabLayout)findViewById(R.id.tabs);
    tabs.setupWithViewPager(mViewPager);

}

public class CollectionPagerAdapter extends FragmentPagerAdapter {

    //final int NUM_ITEMS = 3; // number of tabs

    public CollectionPagerAdapter(FragmentManager fm) {
        super(fm);

    }

    @Override
    public Fragment getItem(int position)
    {

        switch (position) {
            case 0:
                return new Tab1();
            case 1:
                return new Tab2();
            case 2:
                return new Tab3();
        }

        return null;
    }

    @Override
    public int getCount()
    {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position)
        {
            case 0:
                return getString(R.string.tab1);
            case 1:
                return getString(R.string.tab2);
            case 2:
                return getString(R.string.tab3);
        }
        return null;
    }
}




@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home: {
            if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
                mDrawerLayout.closeDrawer(mDrawerList);
            } else {
                mDrawerLayout.openDrawer(mDrawerList);
            }
            return true;
        }

        default:
            return super.onOptionsItemSelected(item);
    }
}

Activity1 :

public class Activity1 extends MainActivity { //extends MainActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.classe1);  //setContentView before super.onCreate(savedInstanceState) allows me to get drawer in each activity
    super.onCreate(savedInstanceState);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);

    TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
    mTitle.setText("Activity 1");
    setSupportActionBar(toolbar);

    assert getSupportActionBar() != null;

    this.getSupportActionBar().setDisplayShowTitleEnabled(false);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

}

Tab1 (Fragment):

public class Tab1 extends Fragment {
View view;

public Tab1() {
}

@SuppressLint("InflateParams")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.tab1, null);

    return view;
}

and my activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <android.support.v4.view.ViewPager
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_marginBottom="60dp"
        android:id="@+id/pager">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:overScrollMode="never">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:orientation="vertical">

            </LinearLayout>

        </ScrollView>

    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="bottom">

        <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:id="@+id/tabs"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="@color/colorPrimaryDark"
            app:tabTextColor="@color/tab_text"
            app:tabIndicatorColor="@android:color/transparent"
            app:tabBackground="@drawable/selected_tab_color"
            style="@style/MyCustomTabLayout"/>

        <include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>

    </LinearLayout>

</RelativeLayout>

<LinearLayout
    android:id="@+id/linearLayout"
    android:layout_width="304dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:clickable="true"
    android:background="#ffffff">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/uno"
                android:text="Button to Activity1"/>

        </LinearLayout>

    </ScrollView>

</LinearLayout>

classe1.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <FrameLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_marginBottom="30dp"
        android:id="@+id/content_frame">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:overScrollMode="never">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="CLASSE 1"
                    android:textSize="35sp"
                    android:gravity="center"/>

            </LinearLayout>

        </ScrollView>

    </FrameLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom">

        <include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>

    </RelativeLayout>

</RelativeLayout>

Your problem is that the super.onCreate() call in Activity1 is calling setContentView() again in MainActivity , which is completely replacing Activity1 's layout set with its call to setContentView() .

Since you want tabs in MainActivity but not the other Activities, your other Activities shouldn't extend MainActivity . Instead, you should create a base Activity with the DrawerLayout that all of your Activities extend, including MainActivity , and then add whichever View s you need in the individual subclasses.

In the base Activity , we'll override the setContentView() method to first set the base layout, setup the drawer and toggle, and then inflate the subclass's layout into the DrawerLayout 's content View . Note that we do not call setContentView() in the base Activity 's onCreate() method.

public abstract class BaseActivity extends AppCompatActivity {

    protected Toolbar toolbar;
    protected DrawerLayout mDrawerLayout;
    protected ActionBarDrawerToggle mDrawerToggle;
    protected TextView mTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
    }

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(R.layout.activity_base);

        toolbar = (Toolbar) findViewById(R.id.toolbar_layout);

        mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
        mTitle.setText(R.string.app_name);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayShowTitleEnabled(false);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //this is inside the drawer layout
        Button button1 = (Button)findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(BaseActivity.this, Activity1.class);
                    startActivity(intent);
                }
            });

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this,
                                                  mDrawerLayout,
                                                  null,
                                                  R.string.drawer_open,
                                                  R.string.drawer_close) {
            public void onDrawerClosed(View v) {
                super.onDrawerClosed(v);
                invalidateOptionsMenu();
                syncState();
            }

            public void onDrawerOpened(View v) {
                super.onDrawerOpened(v);
                invalidateOptionsMenu();
                syncState();
            }
        };

        mDrawerLayout.addDrawerListener(mDrawerToggle);
        mDrawerToggle.setDrawerIndicatorEnabled(false);
        mDrawerToggle.syncState();

        getLayoutInflater().inflate(layoutResID,
                                    (ViewGroup) findViewById(R.id.content));
    }
}

The base layout is pretty much the same, except everything specific to MainActivity is removed.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="304dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:clickable="true"
        android:background="#ffffff">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/button1"
                    android:text="Button to Activity1"/>

            </LinearLayout>

        </ScrollView>

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

In MainActivity , we no longer need to setup the drawer and toggle.

public class MainActivity extends BaseActivity {

    private CollectionPagerAdapter mCollectionPagerAdapter;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mCollectionPagerAdapter = new CollectionPagerAdapter(
            getSupportFragmentManager());


        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mCollectionPagerAdapter);

        TabLayout tabs = (TabLayout)findViewById(R.id.tabs);
        tabs.setupWithViewPager(mViewPager);
    }
    ...
}

And the layout for MainActivity is now basically just the ViewPager and TabLayout .

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/pager">

        ...

    </android.support.v4.view.ViewPager>

    <android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:id="@+id/tabs"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="@color/colorPrimaryDark"
        app:tabTextColor="@color/tab_text"
        app:tabIndicatorColor="@android:color/transparent"
        app:tabBackground="@drawable/selected_tab_color"
        style="@style/MyCustomTabLayout" />

</LinearLayout>

Then, to accomplish everything in Activity1 that your posted code is doing, all we need is this, since the Toolbar and title TextView are now in BaseActivity .:

public class Activity1 extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.classe1);

        mTitle.setText("Activity 1");
    }
}

And the layout for Activity1 can be pared down significantly:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:overScrollMode="never">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="CLASSE 1"
            android:textSize="35sp"
            android:gravity="center"/>

    </LinearLayout>

</ScrollView>

You call setContentView two times in the Activity1 onCreate method, the first time with R.layout.classe1 and the second time with R.layout.activity_main (when you call the super.onCreate). The last setContentView wins, your problem is here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM