简体   繁体   English

使用工具栏+ TabLayout充气AppBarLayout

[英]Inflating AppBarLayout with Toolbar + TabLayout

I currently have a DrawerLayout in my main.xml. 我目前在main.xml中有一个DrawerLayout。 There's a Toolbar wrapped in an AppBarLayout, and then a simple LinearLayout to swap out fragments. 有一个工具栏包装在AppBarLayout中,然后是一个简单的LinearLayout来交换片段。

One of the fragments I navigate to, I want it to contain a TabLayout for a ViewPager of fragments. 我导航到的一个片段,我希望它包含一个用于ViewPager片段的TabLayout。 Currently, I have both of these in the fragment's layout file, but this causes a drop shadow to appear between the Toolbar and the TabLayout, which is something I don't want. 目前,我在片段的布局文件中都有这两个,但这会导致工具栏和TabLayout之间出现阴影,这是我不想要的。 I also don't want to use setElevation() because it won't work for pre-Lollipop devices. 我也不想使用setElevation(),因为它不适用于pre-Lollipop设备。

A possible solution would be to inflate the AppBarLayout from my fragment, so that it holds both the Toolbar+Tabs. 一个可能的解决方案是从我的片段中膨胀AppBarLayout,以便它同时包含工具栏+标签。 However, I'm not really sure how to do this, so any help would be appreciated. 但是,我不确定如何做到这一点,所以任何帮助将不胜感激。

Here is my main.xml file: 这是我的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>

And here is my fragment's xml file: 这是我的片段的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>

You are able to have separate toolbar for each fragment. 您可以为每个片段分别设置工具栏。 Its possible to set fragments toolbar as activity actionbar. 可以将片段工具栏设置为活动操作栏。 Example code: 示例代码:

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

It should be possible to have titles, icons and other stuff as well. 它应该可以有标题,图标和其他东西。 With it you can mimic shadow on pre lollipop devices, no matter what you have on them. 有了它,您可以模仿棒棒糖前设备上的阴影,无论您拥有它们。

I modified the solution given by bleeding182 and got it to work for AppBarLayout as well (to resolve the problem pointed out by bopa ). 我修改了由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);
    }
}

What I did was replace the call to getSupportActionBar() by giving an ID to my AppBarLayout and then calling findViewById() on it and then calling setElevation on its result. 我做的是通过给我的AppBarLayout提供一个ID,然后在其上调用findViewById()然后在其结果上调用setElevation来替换对getSupportActionBar()的调用。 Tested on API 23. 在API 23上测试。

I had a similar issue where I wanted a TabLayout just inside of one fragment. 我有一个类似的问题,我想在一个片段内部使用TabLayout

Without changing any other code you can solve this by using onAttach and onDetach inside your fragment with the TabLayout. 在不更改任何其他代码的情况下,您可以使用onDetach在片段内使用onAttachonDetach来解决此问题。

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

Be sure to set the same elevation on your TabLayout and everything works fine! 一定要在TabLayout上设置相同的高度,一切正常! ;D ; d

You can simply add TabLayout programmatically from Fragment in wich you need TabLayout 你可以简单地从Fragment中以编程方式添加TabLayout,因为你需要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));

and remove TabLayout from AppBar in onDetach() 并在onDetach()中从AppBar中删除TabLayout

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

To fix my problem I ended up putting the Toolbar, TabLayout, and ViewPager all in my MainActivity. 为了解决我的问题,我最终将工具栏,TabLayout和ViewPager都放在了我的MainActivity中。

main_activity.xml: 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>

Then, in all of my fragments, I set the visibility for the TabLayout and the ViewPager programmatically in onCreateView: 然后,在我的所有片段中,我在onCreateView中以编程方式设置TabLayout和ViewPager的可见性:

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

Of course, in the fragment with tabs, you would want to set the visibility to View.VISIBLE instead of View.GONE . 当然,在带有制表符的片段中,您可能希望将可见性设置为View.VISIBLE而不是View.GONE

The Artem_lens approach worked for me with some modifications. 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));

    ...
}

And removing the view at onDestroyView() 并在onDestroyView()删除视图

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

The solution is simple in the XML. 解决方案在XML中很简单。 Just add the following code to your AppBarLayout: app:elevation="0dp" . 只需将以下代码添加到AppBarLayout: app:elevation="0dp" So the AppBarLayout should look like this: 所以AppBarLayout看起来应该是这样的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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