23

В настоящее время у меня есть DrawerLayout в моем main.xml. Там есть панель инструментов, завернутая в AppBarLayout, а затем простой LinearLayout для замены фрагментов.Inflating AppBarLayout с панелью инструментов + TabLayout

Один из фрагментов, к которым я перехожу, я хочу, чтобы он содержал TabLayout для ViewPager фрагментов. В настоящее время у меня есть оба в файле макета фрагмента, но это вызывает появление тени из панели инструментов и TabLayout, чего я не хочу. Я также не хочу использовать setElevation(), потому что он не будет работать для устройств pre-Lollipop.

Возможным решением было бы раздуть AppBarLayout из моего фрагмента, чтобы он содержал как панель инструментов + вкладки. Тем не менее, я не совсем уверен, как это сделать, поэтому любая помощь будет оценена по достоинству.

Вот мой main.xml файл:

<android.support.v4.widget.DrawerLayout 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:id="@+id/drawerLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.lumivote.lumivote.ui.MainActivity"> 

    <android.support.design.widget.CoordinatorLayout 
     android:id="@+id/rootLayout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <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="?attr/actionBarSize" 
       android:background="?attr/colorPrimary" 
       app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> 

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

     <LinearLayout 
      android:id="@+id/flContent" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior"/> 

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

    <android.support.design.widget.NavigationView 
     android:id="@+id/navigation" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     app:headerLayout="@layout/nav_header" 
     app:itemIconTint="#333" 
     app:itemTextColor="#333" 
     app:menu="@menu/navigation_drawer_items" /> 

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

А вот XML файл моего фрагмента:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="com.alexdao.democracy.ui.candidate_tab.CandidateListFragment"> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/tabLayout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@color/myPrimaryColor" 
     app:tabMode="fixed" 
     app:tabGravity="fill" 
     app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="@android:color/white" /> 
</LinearLayout> 

ответ

2

Чтобы исправить свою проблему, я закончил размещение панели инструментов, TabLayout и ViewPager в моей MainActivity.

main_activity.xml:

<android.support.v4.widget.DrawerLayout 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:id="@+id/drawerLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.design.widget.CoordinatorLayout 
     android:id="@+id/rootLayout" 
     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:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> 

      <android.support.design.widget.TabLayout 
       android:id="@+id/tabLayout" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       app:tabMode="fixed" 
       app:tabGravity="fill" 
       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> 

      <android.support.v4.view.ViewPager 
       android:id="@+id/viewpager" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:background="@android:color/white" /> 
     </android.support.design.widget.AppBarLayout> 

     <RelativeLayout 
      android:id="@+id/flContent" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior"/> 

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

    <android.support.design.widget.NavigationView 
     android:id="@+id/navigation" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     app:headerLayout="@layout/nav_header" 
     app:itemIconTint="#333" 
     app:itemTextColor="#333" 
     app:menu="@menu/navigation_drawer_items" /> 

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

Тогда, во всех моих фрагментов, я установить видимость для TabLayout и ViewPager программно в onCreateView:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     TabLayout tabLayout = (TabLayout) getActivity().findViewById(R.id.tabLayout); 
     tabLayout.setVisibility(View.GONE); 
     ViewPager mViewPager = (ViewPager) getActivity().findViewById(R.id.viewpager); 
     mViewPager.setVisibility(View.GONE); 

     return inflater.inflate(R.layout.fragment_layout, container, false); 
} 

Конечно, в фрагменте с вкладками, вы хотите установить видимость на View.VISIBLE вместо View.GONE.

+0

Это интересный подход –

+0

@ hitch.united спасибо, что это хорошо работает для меня – adao7000

12

Вы можете иметь отдельную панель инструментов для каждого фрагмента. Его можно установить панель инструментов фрагментов как панель действий. Пример кода:

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

Должно быть возможно иметь названия, значки и прочее. С его помощью вы можете имитировать тень на предустановленных устройствах, независимо от того, что у вас есть на них.

+0

Вы проверяли производительность и стабильность? –

+3

Я проверил производительность на своем устройстве с леденец и старом желании htc x с api 16. Переход фрагмента с собственными панелями инструментов был действительно плавным, а использование процессора никогда не достигало 25% (я несколько раз нажимал кнопку замены несколько раз в секунду) –

+0

Это отличное решение, но что, если я использую Activity with Navigation drawer и хочу, чтобы значок Hamburger (анимация) также находился на панели инструментов моего фрагмента? – Meet

4

У меня была аналогичная проблема, когда я хотел получить TabLayout только внутри одного фрагмента.

Без изменения какого-либо другого кода вы можете решить эту проблему, используя onAttach и onDetach внутри вашего фрагмента с помощью TabLayout.

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 

    // todo add some further checks, e.g. instanceof, actionbar != null 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     ((AppCompatActivity) activity).getSupportActionBar().setElevation(0); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     ((AppCompatActivity) getActivity()).getSupportActionBar() 
       .setElevation(getResources().getDimension(R.dimen.toolbar_elevation)); 
    } 
} 

Обязательно установите одинаковое возвышение на вкладке TabLayout, и все будет хорошо! ; D

+0

не будет работать в его случае, потому что AppBarLayout сбрасывает тень – bopa

+0

Вы можете лучше использовать 'onStart' и' onStop', потому что, когда фрагмент заменяется и добавляется в backscack, он не отсоединяется и 'onDetach' не вызывается, поэтому тень остается' 0dp'. Но это решило мою проблему, спасибо Дэвиду! – Wouter0100

5

Я изменил решение, данное bleeding182, и получил его для работы в AppBarLayout (чтобы решить проблему, указанную bopa).

@Override 
public void onAttach(Context context) { 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     getActivity().findViewById(R.id.appbar).setElevation(0); 
    } 
    super.onAttach(context); 

} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     getActivity().findViewById(R.id.appbar).setElevation(R.dimen.toolbar_elevation); 
    } 
} 

Что я сделал заменить вызов getSupportActionBar(), давая ID моему AppBarLayout и затем вызвать findViewById() на нем и затем вызвать setElevation на его результат. Протестировано по API 23.

3

Вы можете просто добавить TabLayout программно из фрагмента в Wich вам нужно TabLayout

tabLayout = (TabLayout) inflater.inflate(R.layout.tablay, null); 
appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.appbar); 
appBarLayout.addView(tabLayout, new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 

и удалить TabLayout из AppBar в onDetach()

@Override 
public void onDetach() { 
    appBarLayout.removeView(tabLayout); 
    super.onDetach(); 
} 
0

Artem_lens подход работал для меня с некоторыми изменениями.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    ... 

    mTabLayout = (TabLayout) inflater.inflate(
      R.layout.partial_tab_layout, 
      container, 
      false); 
    mAppBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar); 
    mAppBarLayout.addView(mTabLayout, 
      new LinearLayoutCompat.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, 
        ViewGroup.LayoutParams.WRAP_CONTENT)); 

    ... 
} 

и удаление вид на onDestroyView()

@Override 
public void onDestroyView() { 
    mAppBarLayout.removeView(mTabLayout); 
    super.onDestroyView(); 
} 
0

Решение простое в XML. Просто добавьте следующий код в свой AppBarLayout: app:elevation="0dp". Таким образом, AppBarLayout должен выглядеть так:

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