Фрагменты - Нужно ли вам использовать обёртывание активности вокруг фрагмента, который содержит всю активность? - PullRequest
20 голосов
/ 13 июля 2011

Рассмотрим пример приложения от developers.android.com

Это описывает использование фрагментов следующим образом:

  • На телефоне вы можете использовать Фрагмент 1 в Занятии A и Фрагмент 2 в Занятии B.
  • На планшете у вас больше недвижимости, поэтому вы используете Фрагмент 1 и Фрагмент 2 в упражнении А.

Отлично! ... Но ... В первом примере (тот, что с телефоном) вы создаете действие с файлом xml, содержащим один <fragment>, и все, в упражнении вы вызываете только setContentView() для этого xml? Это выглядит как избыточный код (Activity, XML & Fragment для отображения фрагмента): вы можете установить Fragment как Activity или Wrapper с XML всегда требуется?

Ответы [ 3 ]

36 голосов
/ 13 июля 2011

Ах, нашел это здесь

public class MainMenuHolder extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        // If not already added to the Fragment manager add it. If you don't do this a new Fragment will be added every time this method is called (Such as on orientation change)
        if(savedInstanceState == null)
            getSupportFragmentManager().beginTransaction().add(android.R.id.content, new MainMenuFragment()).commit();
    }
}

FragmentActivity позволяет вам установить Фрагмент в качестве содержимого android.R.id.content, которое, как я полагаю, является внутренним идентификатором андроида в виде ствола.

С помощью этого метода вы по-прежнему получаете в основном избыточное действие (если все, что вам нужно, это фрагмент, действующий как действие). Но, тем не менее, вдвое меньше пуха, чем наличие активности и файла XML, выступающего в роли контейнера.

Любые другие ответы будут оценены!

2 голосов
/ 16 марта 2012

Онлайн-пример не заполняет все пробелы.Я постараюсь ответить на ваши вопросы напрямую:

"В первом примере (тот, что с телефоном) вы должны создать действие с файлом xml, содержащим один файл, и действием, которое вызывает только setContentView () длячто XML и это все? "

Вы начали в правильном месте.Но это еще не все.В Android всегда есть несколько способов решения проблемы, но рекомендуется создать эффект динамического количества фрагментов, основанных на доступности.real-estate:

  1. Создание XML-файлов макета в / layout для основной (по умолчанию) целевой ориентации / устройства / форм-фактора / SDK
  2. Создание XML-файлов макета для самых маленьких-ширина базовой линии для других целевых устройств.Вы также можете указать другие ориентации, SDK и т. Д.
  3. Каждый XML-файл макета будет иметь собственный набор определенных фрагментов
  4. В действии проверьте, какие фрагменты присутствуют.

Очевидно, что аналогичная стратегия может быть принята для программных макетов.

В вашем примере в исходном вопросе (из документов Google) вы могли бы иметь:

  • layout / main.xml :: этот макет будет иметь только Фрагмент 1
  • layout-sw600dp / main.xml :: этот макет будет иметь Фрагменты 1, 2

Тогда в MainActivity.Ява вы бы проверить на наличие каждого фрагмента.Для этого вы можете использовать FragmentManager # findFragmentById () для проверки вроде: если findFragmentById () возвращает ноль для Fragment-2, тогда MainActivity знает, что устройство загрузило layout / main.xml и поддерживает только один фрагмент.

Отступление «назад» из примера в некоторой степени показывает, что: до использования фрагментов вы могли вызвать Activity B из Activity A с startAcitityForResult (int).В парадигме фрагмента вам, вероятно, нужен только результат, полученный в результате фрагмента 2, что-то должно произойти во фрагменте 1, поэтому разумно, чтобы MainActivity был привратником для этого.Развернув пример, вы можете увидеть, что в других приложениях MainActivity может потребоваться вызывать другие действия - по любой причине.Возможно, вы ориентируетесь на большой планшет с достаточным количеством недвижимости для 3 фрагментов, но на телефоне, который должен быть 3 активами.Вещи могут стать интересными, но Fragment API является довольно мощным.

"Вы можете установить Fragment в качестве Activity или Wrapper всегда требуется при использовании фрагментов?"

Fragment - это не Activity,Действительно, фрагменты загружаются операциями, так что да, можно сказать, что обертка всегда требуется.Вы затрагиваете другой тонкий аспект фрагментов.В то время как действия ведут себя как контроллеры MVC, фрагменты можно назвать «мини-контроллерами» из-за их жизненного цикла, который напоминает и выполняется вместе с действием.Опять же, жизненный цикл Фрагмента содержится внутри («обернутый») жизненного цикла Действия, управляющего Фрагментом.Я рекомендую ознакомиться с жизненным циклом фрагмента, задокументированным в http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle.

1 голос
/ 25 августа 2017

В более общем смысле вы можете создать класс контейнера фрагмента:

public class SingleFragmentActivity extends Activity {

    public static final String FRAGMENT_NAME = "fragmentName";
    public static final String FRAGMENT_ARGUMENTS = "fragmentArguments";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String fragmentName = getIntent().getStringExtra(FRAGMENT_NAME);
        Fragment fragment = Fragment.instantiate(this, fragmentName);
        Bundle fragmentArguments = getIntent().getBundleExtra(FRAGMENT_ARGUMENTS);
        fragment.setArguments(fragmentArguments);
        getSupportFragmentManager().beginTransaction().replace(android.R.id.content,fragment, "tag").commit();
    }
}

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

public void showFragmentAsActivity() {
    Intent intent = new Intent(this, SingleFragmentActivity.class);
    intent.putExtra(SingleFragmentActivity.FRAGMENT_NAME, MyFragment.class.getName());
    intent.putExtra(SingleFragmentActivity.FRAGMENT_ARGUMENTS,MyFragment.getArgumentsBundle("a string argument"));
    startActivity(intent);
}
...