将navigationView与tabLayout一起使用

时间:2015-08-26 23:31:53

标签: android android-layout android-fragments

所以我最近一直在努力更新我的应用以使用新的材料设计支持库。我的应用程序有一个主要活动,其中包含drawerLayout和导航视图。 app的主要内容通过片段显示在frameLayout中。但是,我现在正在尝试将材质标签添加到其中一个导航抽屉的片段中。但是,我不确定如何实现这一点,同时保持我的片段在导航抽屉功能。我想要实现的一个很好的例子如下所示:

enter image description here

在这个应用程序(谷歌播放音乐)中,只有一些导航抽屉的项目有标签,而其他项目没有。所以我的问题是,我将如何实现这一点? (不是寻找代码,只是概述我的布局应该如何组织)

  

回顾/澄清:   我有一个带有frameLayout的主布局(用于我的应用程序的内容)和一个navigationView(用于导航不同的项目片段)。然后,我有一个监听器,用项目的相应片段替换主布局的frameLayout。现在,我需要为这些片段中的一个添加制表符(在4个其他片段之间导航)。我还使用了一个工具栏,我将其作为单独的布局包含在内。

任何建议表示赞赏。如果我的描述有点令人困惑,我很抱歉;我将澄清任何必要的细节。

3 个答案:

答案 0 :(得分:7)

好的,假设您的NavigationView有两个选项,第一个显示带有标签的片段(标签布局),第二个显示带有工具栏的片段。您有两种选择:

  1. 您可以使用仅包含框架布局的主要布局,并将其替换为您想要的所有内容
  2. 您可以拥有协调员布局的主要布局 - > app bar - >工具栏 - >标签布局和框架布局以放置内容
  3. 我更喜欢第二个选项,以避免必须始终配置工具栏,所以这就是我曾经做过的事情:

    <!-- layout_main -->
    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    
        <android.support.design.widget.CoordinatorLayout
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.design.widget.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <android.support.v7.widget.Toolbar                    
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    app:layout_scrollFlags="scroll|enterAlways"/>
    
                <android.support.design.widget.TabLayout
                    android:id="@+id/tab_layout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="gone"
                    app:tabGravity="fill"
                    app:tabMode="fixed" />
    
            </android.support.design.widget.AppBarLayout>
    
            <FrameLayout
                android:id="@+id/main_content"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
        </android.support.design.widget.CoordinatorLayout>
    
        <!-- The NavigationView -->
        <fragment
            android:id="@+id/navigation_fragment"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:name="some.path.to.the.NavigationViewFragment"
            tools:layout="@layout/fragment_navigation_view" />
    
    </android.support.v4.widget.DrawerLayout>
    

    如您所见,我将TabLayout的可见性更改为“已消失”,以便带有制表符的片段注意设置为可见。带有选项卡的片段在布局中只有ViewPager:

    <!-- fragment_with_tabs -->
    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    现在带有标签的片段使用每个页面的片段初始化ViewPager:

    @Override 
    public onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    
        // The getChildFragmentManager() is Very important! Because fragments inside fragments are
        // not supported with the tipical fragmentManager, it requires NestedFragments and those
        // uses a childFragmentManager(). In other case a strange behaviour occurs
        ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
        adapter.addFragment(new TabOneFragment(), "Tab 1");
        adapter.addFragment(new TabTwoFragment(), "Tab 2");
        viewPager.setAdapter(adapter);
    
        tabLayout = (TabLayout) getActivity().findViewById(R.id.tab_layout);
        tabLayout.setVisibility(View.VISIBLE);
        tabLayout.setupWithViewPager(viewPager);
    }
    

    最后在TabFragments中做任何你想做的事情,这对我来说很好,我希望这对你也有用。对于代码语法的一些问题,我很抱歉,我使用Kotlin而不是Java开发android。

答案 1 :(得分:3)

我不能推荐Yiyo建议的内容。如果您要使用具有不同布局的Fragments,则应该让Fragments在XML中自定义这些布局。这就是为什么工具栏的引入对于Android开发非常有意义。将来,您可能会在每个片段之间有更多不同的要求。其中一些可能不需要工具栏,其中一些可能需要工具栏上方的另一个视图,其中一些将具有您希望CoordinatorLayout和AppBar可访问的RecyclerView,以便滚动行为正常工作。

我建议您只将FrameLayout作为DrawerLayout的内容(如第1点中提到的Yiyo)。在这里,您将从NavigationView的回调中加载每个片段。

<android.support.v4.widget.DrawerLayout 
    ...
    android:fitsSystemWindows="true"
    >

    <FrameLayout
        android:id="@+id/drawer_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

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

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

在每个Fragment的XML中,如果片段需要,您将放置一个工具栏。在标签片段的XML中,您将放置TabLayout,如果您愿意,还可以使用CoordinatorLayout和AppBarLayout。从具有工具栏的每个片段中,您将工具栏设置为ActionBar:

Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(toolbar);

这就是它的全部。当然,您不希望在每个片段中重复自己,因此您可以将此代码放在DrawerFragment中,并使用工具栏将其子类化为片段。您还需要将工具栏XML配置放在一个文件中,并将其包含在Fragment的XML <include layout="@layout/toolbar" />中。或者您可能希望从某些片段中删除工具栏,或者更改其颜色,主题等。

答案 2 :(得分:2)

你可以这样做。我自己做了检查并且效果很好

步骤1:像这样创建主要活动的布局

    

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout" android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar" android:layout_width="match_parent"
            android:layout_height="wrap_content" android:background="@color/blue"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:titleTextAppearance="@style/TextAppearance.AppCompat.Small"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout" style="@style/FreeWiFiTabLayout"
            android:layout_width="match_parent" android:layout_height="wrap_content"
            android:layout_gravity="center" android:background="@color/blue"
            android:visibility="gone" android:fitsSystemWindows="true"
            android:minHeight="?attr/actionBarSize" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/wifi_type_pager" android:layout_width="match_parent"
        android:layout_height="match_parent" android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<fragment android:id="@+id/navigation_drawer"
    android:name="com.easyway.freewifi.NavigationDrawerFragment"
    android:layout_width="wrap_content" android:layout_height="match_parent"
    android:layout_gravity="start|bottom" android:layout_marginTop="?attr/actionBarSize"
    tools:layout="@layout/navigation_drawer_fragment" />

第2步:

在您的活动中,您需要在viewpager上设置onpagechangelistener:

 viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

  }

  @Override
  public void onPageSelected(int position) {
        if(position ==0){
          tabLayout.setVisibility(View.GONE);
        }else{
          tabLayout.setVisibility(View.VISIBLE);
        }
  }

  @Override
  public void onPageScrollStateChanged(int state) {

  }
});

在此之后你需要添加  viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

第3步:

这就是为viewpager创建适配器的方法:

公共类WiFiPagerAdapter扩展FragmentPagerAdapter {     private final List registeredFragments = new ArrayList&lt;&gt;();

public WiFiPagerAdapter(final FragmentManager fm) {
  super(fm);
}

@Override
public Fragment getItem(final int pos) {
  Fragment fragment;
  fragment = WiFiFragment.newInstance(pos);
  registeredFragments.add(pos, fragment);
  return fragment;
}

@Override
public int getCount() {
  return tabLayout.getTabCount();
}

public List<Fragment> getRegisteredFragmentsList() {
  return registeredFragments;
}

@Nullable
public Fragment getRegisteredFragment(final int position) {
  final Fragment wr = registeredFragments.get(position);
  if (wr != null) {
    return wr;
  } else {
    return null;
  }
}

@Override
public void notifyDataSetChanged() {
  super.notifyDataSetChanged();
  for (int i = 0; i < registeredFragments.size(); i++) {
    WiFiFragment wiFiFragment = ((WiFiFragment) registeredFragments.get(i));
    wiFiFragment.setWiFiFragmentRecyclerViewAdapter();
  }
}

}