2015-06-06 5 views
9

У меня возникли проблемы обертывание моей головы вокруг чего-то, но позвольте мне сначала описать мою установку:Android диалога обратного вызова полноэкранного вопрос

flow

У меня есть деятельность, которая ссылается на 3 фрагмента, каждый из них получают показано в правильное время. Это как ChildrenSpecificationFragment выглядит: открывает следующий DialogFragment

Если пользователь нажимает на кнопку плавающих действий:

я нашел следующую информацию в новых руководствах по дизайну материала: https://www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs

Избегайте диалогов, которые: Откройте дополнительные диалоги из диалогового окна. Содержит прокручиваемый контент, в частности предупреждения. Вместо этого рассмотрите альтернативные контейнеры или макеты, которые оптимизированы для чтения или взаимодействия со значительным количеством контента.

Исключения включают в себя: полноэкранные диалоги могут открывать дополнительные диалоги, такие как сборщики, потому что их дизайн содержит дополнительные слои материала без существенного увеличения воспринимаемой z-глубины или визуального шума приложения.

Здесь возникают проблемы. Диалог «добавить ребенка» имеет прокручиваемое содержимое (в альбомном режиме), и когда пользователь нажимает «Дата рождения», открывается панель выбора даты.

Я пытаюсь найти способ реализации полноэкранного диалога (как в руководстве), который имеет обратный вызов в ChildrenSpecificationFragment, так что я могу добавить ребенка в RecyclerView.

Я надеюсь, что мои поиски ясны и будут очень признательны за любые материалы, которые приведут меня к решению. Заранее спасибо!

+0

Каков ваш макет файла вашего дочернего фрагмента? – windchime

+0

http://pastebin.com/bhscbGu2 – Jdruwe

+0

Я видел ответы и другие вопросы, которые используют FragmentTransaction для добавления диалога, но я еще не получил его работу. – Jon

ответ

0

Я не вижу код из вашего поста. Поэтому я угадываю вашу структуру кода как начало. Сначала создайте свой диалог с помощью слушателя и процесса setPositiveButton() и события onClick.

код предложение:

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, например, внутренний класс, производный от фрагмента. Он может вызвать общедоступный метод passData() во внешнем классе ChildrenSpecificationFragment для передачи любых данных.
  • Я использую внутренний класс, потому что я думаю, что это то, что вы имели в виду в вашей диаграмме

Добавить ребенок полноэкранных техниками фрагмента

  • Это кодирование проще, чем начинать новую деятельность и намерение.

За показ полноэкранных диалогов, есть хороший веб-страница Google Я думаю, @Dialog - Fullscreen. Найдите текст для «Показать диалог в полноэкранном режиме или в виде встроенного фрагмента».

+0

Но показывает ли это содержимое макета в полноэкранном режиме в качестве примера Google: https://material-design.storage.googleapis.com/publish/material_v_4 /material_ext_publish/0B6Okdz75tqQsTXVxUFJQdy15ZzA/components_dialogs_fullscreen1.png? – Jdruwe

+1

Поскольку это было то, что у меня изначально были вещи, фрагмент, расширяющий диалогический фрагмент и вызывающий метод родительского интерфейса. – Jdruwe

+0

@Jdruwe, фрагмент SubChildFragment в моем примере может быть диалоговымфрагментом, и он может отображать полноэкранный режим. Я думаю, что диалог может быть полноэкранным по спецификации макета. Передача данных отделена от макета GUI. Существует ссылка http://developer.android.com/guide/topics/ui/dialogs .html, в случае, если вы этого не читали. Я думал, что у вас уже проблема с полноэкранным разрешением. –

0

добавьте эту строку в свой собственный фрагмент диалогового окна.

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

С другой стороны, вы можете использовать контент-преобразователи для хранения данных ваших детей. У этого есть образец наблюдателя. Поэтому каждый CursorAdapter, прикрепленный к этому контенту, обновляется без вызова notifySetDataChanged();.

Я думаю, вы используете RecyclerView.Adapter. Вы можете использовать this class.

Другим советом по внедрению дочерней функции является использование startActivityForResult(activity);. Вы можете отправить обратно данные с помощью getIntent().getExtras().put(key,value);. Вы можете найти пользовательскую начальную активность для результата.

Успехов

+0

SetStyle не работает, это результат, если я его использую: imgur.com/Zb5dtPP. И я действительно не вижу, как это может обеспечить «навигацию вверх», как в руководящих принципах. – Jdruwe

3

TL; DR - DialogFragment недостаточно для чего-либо кроме полностью полного экрана. Вместо этого используйте действие.

Можно сделать полный экран (ActionBar), но он содержит множество раздражений.

DialogFragment есть, как следует из названия, в Dialog и Fragment в одном лице: его можно рассматривать и как Dialog, используя show() и dismiss(), или в качестве Fragment, используя его с FragmentManager.

Как official documentation suggests, что делает диалог полностью полноэкранный (накладывания всё) достигается путем присоединения диалога с точки зрения корневой 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. Поскольку главная кнопка android.R.id.home обрабатывается в главном окне, для этого необходимо проверить, отображается ли наш диалог, чтобы кнопка «home», которая теперь находится X, закроет диалоговое окно. Возврат 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); 
} 

Кроме того, кнопка назад нуждается в подобную логике, чтобы определить, является ли закрывание NavigationView потребности или переустановка 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 сама логика для закрытия диалога (и злоупотребления 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); 
} 

Все это чувствует себя действительно kludgy. Конечно, если вы используете TabLayout, забудьте все, что я только что сказал.

С TabLayout вы можете просто обрабатывать все в DialogFragment, но если вы используете ViewPager, это будет невозможно получить диалог, чтобы покрыть вкладки, но не бар действия. См. Show DialogFragment over TabLayout.

Этот вопрос (у меня) имеет ответ, который предлагает то же самое, что и @Jdruwe, чтобы забыть безнадежность DialogFragment и вместо этого использовать Activity.

+0

Итак, вы говорите, что я должен придерживаться решения, которое я описал в: http://jeroendruwe.be/full-screen-dialogs-in-android/? – Jdruwe

+1

Думаю, да, да. Маршрут DialogFragment слишком клочковый; хотя, может быть, я недостаточно умен. – Jon

Смежные вопросы