在 TabLayout 上显示 DialogFragment
Show DialogFragment over TabLayout
我正在尝试全屏显示 DialogFragment,这样 ActionBar 仍然可见,但 TabLayout 中的选项卡被隐藏。
左边的图像是我设法实现的; 右侧的图片 是我的目标:
有两个问题:
- 选项卡仍然显示,用户可以与之交互;
- 由于显示对话框的额外
FrameLayout
,ViewPager
内容仍然可见(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 解决了所有这些问题。
我正在尝试全屏显示 DialogFragment,这样 ActionBar 仍然可见,但 TabLayout 中的选项卡被隐藏。
左边的图像是我设法实现的; 右侧的图片 是我的目标:
有两个问题:
- 选项卡仍然显示,用户可以与之交互;
- 由于显示对话框的额外
FrameLayout
,ViewPager
内容仍然可见(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 解决了所有这些问题。