【问题标题】:ViewPager + TabLayout with NavigationDrawer in every Activity - Issue每个 Activity 中带有 NavigationDrawer 的 ViewPager + TabLayout - 问题
【发布时间】:2016-07-24 17:10:27
【问题描述】:

我遇到了一个我无法解决的问题:我有一个MainActivity,其中有一个NavigationDrawer,它允许我参加三个不同的活动。这些扩展了 MainActivity,所以我在每个活动中都得到了抽屉。 在同一个 MainActivity 中,我放置了一个带有三个选项卡 FragmentsTabLayout

我面临的问题是,每当我从抽屉布局转到三个活动之一时,我都没有获得附加到 Activity1 的布局 xml,而是再次获得带有片段的 TabLayout。 我该如何解决这个问题?

结果应该类似于 Google Play 应用。

这是我的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(片段):

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;
}

还有我的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>

【问题讨论】:

    标签: java android android-fragments tabs drawer


    【解决方案1】:

    您的问题是Activity1 中的super.onCreate() 调用在MainActivity 中再次调用setContentView(),这完全用调用setContentView() 替换了Activity1 的布局集。

    由于您想要MainActivity 中的标签而不是其他活动,因此您的其他活动不应扩展MainActivity。相反,您应该使用您的所有活动(包括MainActivity)扩展的DrawerLayout 创建一个基础Activity,然后在各个子类中添加您需要的任何Views。

    在基础Activity 中,我们将重写setContentView() 方法以首先设置基础布局,设置抽屉和切换,然后将子类的布局膨胀到DrawerLayout 的内容View。请注意,我们不会在基础 ActivityonCreate() 方法中调用 setContentView()

    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));
        }
    }
    

    基本布局几乎相同,只是删除了MainActivity 特有的所有内容。

    <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>
    

    MainActivity 中,我们不再需要设置抽屉和切换。

    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);
        }
        ...
    }
    

    MainActivity 的布局现在基本上只是ViewPagerTabLayout

    <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>
    

    然后,要完成您发布的代码在Activity1 中所做的所有事情,我们需要的就是这个,因为Toolbar 和标题TextView 现在在BaseActivity 中。:

    public class Activity1 extends BaseActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.classe1);
    
            mTitle.setText("Activity 1");
        }
    }
    

    Activity1 的布局可以大大缩减:

    <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>
    

    【讨论】:

    • 这很好用!但是我遇到了一个小问题:在 activity_base.xml 中,我将工具栏放在布局的底部,当我运行项目时,工具栏位于顶部
    • 好吧,请注意我稍微改变了布局。不再使用RelativeLayout,而是使用垂直的LinearLayout。并确保Toolbar &lt;include&gt; 列在FrameLayout 之后,而不是在其中。
    【解决方案2】:

    您在 Activity1 的 onCreate 方法中调用了两次 setContentView,第一次使用 R.layout.classe1,第二次使用 R.layout.activity_main(当您调用 super.onCreate 时)。最后一个 setContentView 获胜,你的问题就在这里。

    【讨论】:

    • 对不起,我不明白你的意思。我在 Activity1 中没有看到两个 setContentView
    • samizerouta 就在这里,super 的 setContentView 覆盖了你的布局资源,你可以看到主要活动的抽屉和布局资源。
    • 如果你想在整个应用程序中进行抽屉布局,那么你应该考虑使用具有抽屉布局的单个活动,并且应该在片段中更改活动的其余部分。
    • @abhishesh 没有办法可以在我的活动中排除标签吗?
    • @Rick 创建一个带有抽屉但没有标签的BaseActivity,您的所有活动都可以扩展,包括MainActivity。然后只需在MainActivity 中添加您的标签,不要在其他标签中添加它们。
    猜你喜欢
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 2017-03-10
    • 2016-10-16
    • 2015-02-16
    • 1970-01-01
    相关资源
    最近更新 更多