Intereting Posts
Android ListView заголовки Как запустить приложение только для Android-приложений Интеграция Facebook на Android fbconnect неработающая ссылка Загрузка файла HTML не отображает галерею на Android Android: Получить представление Ссылка на пункт меню Сделать вкладки в ActionBar прокручивать, когда достигнут предел, а не создавать выпадающий список ActionBar up navigation воссоздает родительскую активность вместо onResume Как заблокировать всплывающее меню при нажатии на флажок Переключение пробных версий и pro с помощью приложений Android в Eclipse: как сделать это менее болезненным? Android ускоряет использование процессора (и медленно!) Как определить, является ли тип сети 2G, 3G или 4G Как исключить свое приложение из меню «Поделиться»? Как загрузить растровое изображение в изображение с помощью Picasso Строка JSON возвращается из веб-службы SOAP, не содержащей записей для таблицы Нажмите уведомление, чтобы начать работу дважды

Как добавить фрагмент в Activity с программно созданным контентом

Я хочу добавить Fragment к Activity, который программно реализует свой макет. Я просмотрел документацию Фрагмента, но примеров, описывающих то, что мне нужно, мало. Вот тип кода, который я пытался написать:

public class DebugExampleTwo extends Activity { private ExampleTwoFragment mFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FrameLayout frame = new FrameLayout(this); if (savedInstanceState == null) { mFragment = new ExampleTwoFragment(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(frame.getId(), mFragment).commit(); } setContentView(frame); } } 

 public class ExampleTwoFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Button button = new Button(getActivity()); button.setText("Hello There"); return button; } } 

Этот код компилируется, но сбой при запуске, возможно, потому что мой FragmentTransaction.add() неверен. Каков правильный способ сделать это?

Solutions Collecting From Web of "Как добавить фрагмент в Activity с программно созданным контентом"

Оказывается, есть несколько проблем с этим кодом. Фрагмент не может быть объявлен таким образом внутри одного и того же java-файла, что и активность, но не как открытый внутренний класс. Структура ожидает, что конструктор фрагмента (без параметров) будет общедоступным и видимым. Перемещение фрагмента в Activity как внутренний класс или создание нового java-файла для исправлений фрагментов.

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

 public class DebugExampleTwo extends Activity { private static final int CONTENT_VIEW_ID = 10101010; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FrameLayout frame = new FrameLayout(this); frame.setId(CONTENT_VIEW_ID); setContentView(frame, new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); if (savedInstanceState == null) { Fragment newFragment = new DebugExampleTwoFragment(); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(CONTENT_VIEW_ID, newFragment).commit(); } } public static class DebugExampleTwoFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { EditText v = new EditText(getActivity()); v.setText("Hello Fragment!"); return v; } } } 

Вот что я придумал после прочтения комментария Тони Вонга :

 public class DebugExampleTwo extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addFragment(android.R.id.content, new DebugExampleTwoFragment(), DebugExampleTwoFragment.FRAGMENT_TAG); } } 

 public abstract class BaseActivity extends Activity { protected void addFragment(@IdRes int containerViewId, @NonNull Fragment fragment, @NonNull String fragmentTag) { getSupportFragmentManager() .beginTransaction() .add(containerViewId, fragment, fragmentTag) .disallowAddToBackStack() .commit(); } protected void replaceFragment(@IdRes int containerViewId, @NonNull Fragment fragment, @NonNull String fragmentTag, @Nullable String backStackStateName) { getSupportFragmentManager() .beginTransaction() .replace(containerViewId, fragment, fragmentTag) .addToBackStack(backStackStateName) .commit(); } } 

 public class DebugExampleTwoFragment extends Fragment { public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".DEBUG_EXAMPLE_TWO_FRAGMENT_TAG"; // ... } 
  public class Example1 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setFragment(new TestFragment1()); } // This could be moved into an abstract BaseActivity // class for being re-used by several instances protected void setFragment(Fragment fragment) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(android.R.id.content, fragment); fragmentTransaction.commit(); } } 

Чтобы добавить фрагмент в Activity или FramentActivity, требуется контейнер. Этот контейнер должен быть « Framelayout », который должен быть включен в xml, иначе вы можете использовать контейнер по умолчанию для этого типа « android.R.id.content » для удаления или замены фрагмента в Activity.

main.xml

 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Framelayout to display Fragments --> <FrameLayout android:id="@+id/frame_containerone" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView android:id="@+id/imagenext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="16dp" android:src="@drawable/next" /> </RelativeLayout> 

Прочитав все ответы, я придумал:

 public class MyActivity extends ActionBarActivity { Fragment fragment ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); fragment = fm.findFragmentByTag("myFragmentTag"); if (fragment == null) { FragmentTransaction ft = fm.beginTransaction(); fragment =new MyFragment(); ft.add(android.R.id.content,fragment,"myFragmentTag"); ft.commit(); } } 

В основном вам не нужно добавлять frameLayout в качестве контейнера вашего фрагмента, вместо этого вы можете добавить фрагмент в корневой каталог Android. Просмотреть контейнер

ВАЖНО: не используйте фрагмент замены как большую часть приведенного здесь aproach, если вы не возражаете потерять состояние экземпляра переменной фрагмента во время процесса onrecreation.

 public abstract class SingleFragmentActivity extends Activity { public static final String FRAGMENT_TAG = "single"; private Fragment fragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { fragment = onCreateFragment(); getFragmentManager().beginTransaction() .add(android.R.id.content, fragment, FRAGMENT_TAG) .commit(); } else { fragment = getFragmentManager().findFragmentByTag(FRAGMENT_TAG); } } public abstract Fragment onCreateFragment(); public Fragment getFragment() { return fragment; } } 

использование

 public class ViewCatalogItemActivity extends SingleFragmentActivity { @Override public Fragment onCreateFragment() { return new FragmentWorkShops(); } } 

Для API уровня 17 или выше View.generateViewId () решит эту проблему. Метод utility предоставляет уникальный идентификатор, который не используется во время сборки.