Intereting Posts
Android Wear Пользовательские голосовые действия Android-SQLite LIKE escape-шаблон Как я могу получить значение счетчика webkit-column-count и текущую страницу или идентификатор столбца? Сила остановить блокировку читать AsyncTask Повторное использование атрибутов xml для Android Custom enum Не найдено никаких совместимых целей Распространение (и обновление) корпоративного приложения для Android, которое будет использоваться только внутри компании Как остановить сообщения logcat Как получить URI видео HTML5 в HTML5VFullScreen $ SurfaceVideoView в Android 4.0? Как мне упаковать файлы .so в мой архив .aar? Экспорт APK из eclipse (ADT) бесшумно падает Android: Почему getDimension и getDimensionPixelSize возвращают то же самое? Два вопроса о максимальных размерах кучи и доступной памяти в android Как вставить контактную информацию о существующем контакте в Android 1.6? Пользовательский вид Android должен расширять AppCompatTextView

Как добавить фрагмент в 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 предоставляет уникальный идентификатор, который не используется во время сборки.