在 TabLayout 上显示 DialogFragment

Show DialogFragment over TabLayout

我正在尝试全屏显示 DialogFragment,这样 ActionBar 仍然可见,但 TabLayout 中的选项卡被隐藏。

左边的图像是我设法实现的; 右侧的图片 是我的目标:

有两个问题:

  1. 选项卡仍然显示,用户可以与之交互;
  2. 由于显示对话框的额外 FrameLayoutViewPager 内容仍然可见(FAB 按钮不是对话框的一部分)。这也意味着用户可以与寻呼机中的内容进行交互,其中包括更改选项卡的能力。

主要Activity布局(main.xml)

<?xml version="1.0" encoding="utf-8"?>
<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.design.widget.CoordinatorLayout
        android:id="@+id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- Use ThemeOverlay to make the toolbar and tablayout text
             white -->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/abl_top"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:fitsSystemWindows="true"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                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"
                style="@style/CustomTabStyle"/>

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

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</LinearLayout>

MainActivity.java

package com.example.app;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MainActivity
    extends AppCompatActivity
{
    private static final String TAG = "MainActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Setup AppBar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }

        // Setup ViewPager
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        if (viewPager != null) {
            setupViewPager(viewPager);
        }

        // Setup TabLayout
        TabLayout tl = (TabLayout) findViewById(R.id.tab_layout);
        tl.setupWithViewPager(viewPager);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    private void setupViewPager(ViewPager viewPager) {
        Adapter adapter = new Adapter(
            getSupportFragmentManager(), MainActivity.this);
        adapter.addFragment(
            new Fragment1(),
            "Tab 1", R.drawable.numeric_1_box_outline);
        adapter.addFragment(
            new Fragment2(),
            "Tab 2", R.drawable.numeric_2_box_outline);
        viewPager.setAdapter(adapter);
    }

    static class Adapter extends FragmentPagerAdapter {
        private final List<Fragment> mFragments = new ArrayList<>();
        private final List<Integer> mFragmentIcons = new ArrayList<>();
        private final List<String> mFragmentTitles = new ArrayList<>();
        private Context context;

        public Adapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        public void addFragment(Fragment fragment, String title, int iconId) {
            mFragments.add(fragment);
            mFragmentTitles.add(title);
            mFragmentIcons.add(iconId);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Drawable image = context.getResources().getDrawable(
                    mFragmentIcons.get(position), null);
            image.setBounds(0, 0, image.getIntrinsicWidth(),
                    image.getIntrinsicHeight());
            SpannableString sb = new SpannableString("   " + mFragmentTitles.get(position));
            ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
            sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            return sb;
        }
     }

}

如果你想让对话框全屏显示,根视图应该是FrameLayout(而不是LinearLayout)。如果您希望对话框包含一个工具栏,您还需要第二个工具栏,因为您的第一个工具栏已附加到 TabLayout。

像这样的东西应该可以工作:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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:id="@+id/container">

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

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        <!-- Use ThemeOverlay to make the toolbar and tablayout text
             white -->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/abl_top"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:fitsSystemWindows="true"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                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.support.design.widget.AppBarLayout>

        <android.support.design.widget.FloatingActionButton
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            app:layout_anchor="@id/toolbar_layout"
            app:layout_anchorGravity="bottom|right|end"
            app:borderWidth="0dp"
            android:layout_margin="20dp"
            android:clickable="true"/>

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


</FrameLayout>

MainActivity.java

...

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

    // Setup AppBar
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    if (toolbar != null) {
        setSupportActionBar(toolbar);
    }

    // Setup ViewPager
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    if (viewPager != null) {
        setupViewPager(viewPager);
    }

    // Setup TabLayout
    TabLayout tl = (TabLayout) findViewById(R.id.tab_layout);
    tl.setupWithViewPager(viewPager);


    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.add(R.id.container, new DialogFragment());
    transaction.addToBackStack("tag");
    transaction.commit();
}

...

fragment_dialog.xml

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

    <android.support.v7.widget.Toolbar
        android:id="@+id/fragment_toolbar"
        android:fitsSystemWindows="true"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:background="?attr/colorPrimaryDark"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@android:color/background_light">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="This is the dialog"/>
        </FrameLayout>

</LinearLayout>

DialogFragment.java

public class DialogFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_dialog, container, false);


        final Toolbar toolbar = (Toolbar) view.findViewById(R.id.fragment_toolbar);
        toolbar.setTitle("Dialog Title");
        toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white));
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().getSupportFragmentManager().popBackStack();
            }
        });
        return view;
    }
}

我建议对对话框使用 Activity 而不是将对话框片段附加到视图,尤其是当您打算将输入文本放入对话框时。在对话框中使用 Fragment 时,我遇到了一些奇怪的动画和软键盘行为。创建一个新的 Activity 解决了所有这些问题。