Android全屏对话框callback问题

我遇到了困难,但我首先描述一下我的设置:

流

我有一个活动引用3个片段,每个片段在正确的时间显示。 这是ChildrenSpecificationFragment的外观:

如果用户单击浮动操作button,将打开下面的DialogFragment:

我在新的材料devise指南中find了以下信息: https : //www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs

避免以下对话框:在对话框中打开其他对话框。 包含滚动内容,特别是警报。 相反,请考虑为读取或与大量内容进行交互而优化的备用容器或布局。

例外情况包括:全屏对话框可能会打开其他对话框,例如拾取器,因为它们的devise可以容纳额外的材质层,而不会显着增加应用感知的z深度或视觉噪声。

这是我的问题开始的地方。 “添加孩子”对话框具有可滚动的内容(横向模式),当用户点击“出生date”时,dateselect器打开。

我试图find一个方法来实现一个全屏幕对话框(如在指南中),有一个callback到ChildrenSpecificationFragment,以便我可以添加到RecyclerView的孩子。

我希望我的任务是明确的,将不胜感激任何意见,导致我的解决scheme。 提前致谢!

Solutions Collecting From Web of "Android全屏对话框callback问题"

我没有看到你的post的代码。 所以我猜你的代码结构是一个开始。 首先用监听器构build对话框,然后处理setPositiveButton()和onClick事件。

代码build议:

public class ChildrenSpecificationFragment extends Fragment { ... public void passData(Object obj) { } class SubChildFragment extends Fragment { AlertDialog.Builder builder = new AlertDialog.Builder(thisContext); ... // Add the buttons... builder.setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { ... passData(Object obj); // pass data to the outer fragment class 

笔记:

  • 例如, SubChildFragment是从片段派生的内部类。 它可以调用外部类ChildrenSpecificationFragment的public方法passData ()来传递您需要的任何数据。
  • 我正在使用一个内部类,因为我认为这是你在图中的意思

添加小孩全屏幕片段

  • 这种编码技术比开始一个新的活动和意图容易。

为了显示全屏对话框 ,有一个很好的Google网页,我觉得@ 对话框 – 全屏 。 search文本“显示对话框全屏或embedded片段”。

TL; DR – DialogFragment对于除完全全屏之外的其他任何内容都是不够的。 使用一个活动。

全屏显示DialogFragment (使用ActionBar显示)是可能的,但是它带来了很多烦恼。

DialogFragment就是一个Dialog和一个Fragment它可以被当作一个Dialog ,使用show()dismiss() ,或者作为一个Fragment来使用,并且用一个FragmentManager

正如官方文档所build议的 ,通过将对话框附加到根视图android.R.id.content来实现完全全屏的对话(覆盖所有内容):

 public void showDialog() { FragmentManager fragmentManager = getSupportFragmentManager(); CustomDialogFragment newFragment = new CustomDialogFragment(); if (mIsLargeLayout) { // The device is using a large layout, so show the fragment as a dialog newFragment.show(fragmentManager, "dialog"); } else { // The device is smaller, so show the fragment fullscreen FragmentTransaction transaction = fragmentManager.beginTransaction(); // For a little polish, specify a transition animation transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); // To make it fullscreen, use the 'content' root view as the container // for the fragment, which is always the root view for the activity transaction.add(android.R.id.content, newFragment) .addToBackStack(null).commit(); } } 

要让对话框出现在ActionBar下方,需要使用一个FrameLayout来代替根布局:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_height="match_parent" android:layout_width="match_parent" android:fitsSystemWindows="true"> <LinearLayout 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.AppBarLayout> </android.support.design.widget.CoordinatorLayout> <FrameLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_height="match_parent" android:layout_width="wrap_content" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" app:menu="@menu/nav_view"/> </android.support.v4.widget.DrawerLayout> 

现在来了痛苦。

根据应用程序的主要导航设置,不同的箍将需要跳过,以使一切正常工作。

上面的例子有一个NavigationView 。 由于在主视图中处理了主页buttonandroid.R.id.home ,因此需要一些逻辑来检查是否显示我们的对话框,以便现在为X的主页button将closures对话框。 在这里返回false允许在对话框中处理事件。

 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: FragmentManager fm = getSupportFragmentManager(); Fragment f = fm.findFragmentById(R.id.content); if (f instanceof MyDialogFragment) { return false; } mDrawerLayout.openDrawer(GravityCompat.START); return true; } return super.onOptionsItemSelected(item); } 

另外,后退button需要类似的逻辑来确定NavigationView是否需要closures或重置ActionBar内容。

 @Override public void onBackPressed() { if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { mDrawerLayout.closeDrawer(GravityCompat.START); } else { FragmentManager fm = getSupportFragmentManager(); Fragment f = fm.findFragmentById(R.id.content); if (f instanceof MyDialogFragment) { final ActionBar ab = getSupportActionBar(); ab.setHomeAsUpIndicator(R.drawable.ic_menu); ab.setTitle(R.string.app_name); } super.onBackPressed(); } } 

DialogFragment本身中,需要实现closures对话框(以及滥用ActionBar )的逻辑。

 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: if (mActionBar != null) { mActionBar.setHomeAsUpIndicator(R.drawable.ic_menu); mActionBar.setTitle(R.string.app_name); } getActivity().getSupportFragmentManager().popBackStack(); case R.id.action_save: if (mOnAcceptListener != null) { mOnAcceptListener.onAccept(); } if (mActionBar != null) { mActionBar.setHomeAsUpIndicator(R.drawable.ic_menu); mActionBar.setTitle(R.string.app_name); } getActivity().getSupportFragmentManager().popBackStack(); return true; } return super.onOptionsItemSelected(item); } 

这一切都感觉非常糟糕 。 当然,如果你使用的是TabLayout ,就忘了我刚刚说的一切。

使用TabLayout可以处理DialogFragment中的DialogFragment ,但是如果使用的是ViewPager ,将无法使对话框覆盖标签,而不是操作栏。 请参阅通过TabLayout显示DialogFragment 。

这个问题(由我)有一个答案,表明相同的@Jdruwe,这是忘记DialogFragment的绝望,并使用一个Activity而不是。

在我的博客上使用startActivityForResult(…)描述的解决scheme: http : //jeroendruwe.be/full-screen-dialogs-in-android/

将此行添加到自定义对话框片段中的oncreate中。

 setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen); 

另一方面,您可以使用内容parsing器来存储您的子数据。 它有观察者模式。 因此每个附加到该内容的CursorAdapter都会刷新自己而不调用notifySetDataChanged();

我想你正在使用RecyclerView.Adapter。 你可以使用这个类。

另一个实现添加子特性的build议是使用startActivityForResult(activity); 。 你可以使用getIntent().getExtras().put(key,value);返回数据getIntent().getExtras().put(key,value); 您可以search结果的自定义开始活动。

祝你好运