Фрагменты. Нужно ли использовать обертыватель активности вокруг фрагмента, который включает всю активность?
Рассмотрим пример приложения из developers.android.com
Это описывает использование таких фрагментов:
- На телефоне вы можете использовать фрагмент 1 в действии A и фрагмент 2 в действии B.
- На планшете у вас больше недвижимости, поэтому вы используете Фрагмент 1 и Фрагмент 2 на мероприятии А.
Отлично!... Но... В первом примере (с телефоном) вы создаете Activity с xml файлом, содержащим один <fragment>
, и все это, в действии вы вызываете только setContentView()
на этом xml? Это похоже на много избыточного кода (Activity, XML и Fragment для отображения фрагмента). Можете ли вы установить Fragment
как Activity
или требуется ли Wrapper с XML?
Ответы
Ответ 1
А, нашел здесь
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
, который, как я полагаю, является внутренним идентификатором андроида для просмотра внешней линии.
С помощью этого метода вы по-прежнему оказываете преимущественно избыточную активность (если все, что вам нужно, это Фрагмент, действующий как Activity). Но все же, вдвое меньше пута, чем с активностью и файлом XML, действующим в качестве контейнера.
Любые другие ответы будут оценены!
Ответ 2
В онлайн-примере не заполняются все пробелы. Я постараюсь ответить на ваши вопросы напрямую:
"В первом примере (с телефоном) вы должны создать Activity с xml файлом, содержащим сингл и действие, которое вызывает только вызов setContentView() в этом xml и все??
Вы начали работу в нужном месте. Но там больше, чем это. Всегда существует несколько способов решения проблемы в Android, но рекомендуется использовать способ генерации динамического количества фрагментов на основе avail. Недвижимость:
- Создание макетов XML файлов в /layout для первичной (по умолчанию) целевой ориентации/устройства/форм-фактора/SDK
- Создайте XML файлы формата для минимальной базовой линии для других целевых устройств. Вы также можете настроить таргетинг на другие ориентации, SDK и т.д.
- Каждый XML файл макета будет иметь собственный набор определенных фрагментов
- В Управлении проверьте, какие фрагменты присутствуют.
Очевидно, что для программных макетов может быть использована аналогичная стратегия.
В вашем примере в исходном вопросе (из документов Google) вы можете:
- layout/main.xml:: в этом макете будет только фрагмент 1
- layout-sw600dp/main.xml:: этот макет будет иметь фрагменты 1, 2
Затем в MainActivity.java вы должны проверить наличие каждого фрагмента. Для этого вы можете использовать FragmentManager # findFragmentById() для проверки: if findFragmentById() возвращает null для Fragment-2, тогда MainActivity знает, что устройство загрузило layout/main.xml и поддерживает только один фрагмент.
Шаг назад из примера несколько показывает, что: до использования фрагментов вы могли бы вызвать Activity B из Activity A с startAcitityForResult (int). В парадигме фрагмента вы, вероятно, должны только иметь результат из фрагмента 2, чтобы что-то произошло во Фрагменте 1, поэтому разумно иметь MainActivity для этого гейткипера. По мере того, как вы расширяете пример, вы можете увидеть, что в других приложениях MainActivity, возможно, потребуется вызвать другие действия - по какой-либо причине. Возможно, вы ориентируетесь на большой планшет с достаточным количеством недвижимости для 3 фрагментов, но на телефоне, который должен быть 3-мя действиями. Все может стать интересным, но API-интерфейс Fragment достаточно мощный.
"Можете ли вы установить фрагмент как активность или всегда требуется Wrapper при использовании фрагментов?"
Фрагмент не является активностью. Действительно, фрагменты загружаются в действия, поэтому да можно сказать, что всегда требуется оболочка. Вы касаетесь другого тонкого аспекта Фрагментов. Принимая во внимание, что действия ведут себя как контроллеры MVC, фрагменты можно назвать "мини-контроллерами" из-за их жизненного цикла, которые похожи и выполняются вместе с Activity. Опять же, жизненный цикл фрагмента содержится внутри ( "завернутый" ) жизненный цикл Activity, управляющего фрагментом. Я рекомендую ознакомиться с жизненным циклом фрагмента, зарегистрированным в http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle.
Ответ 3
В общем случае вы можете создать класс контейнера фрагментов:
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);
}