Intereting Posts
Отправка SMS на Android Как создать линейную компоновку справа налево Обнаружение, если другой игрок случайно проиграл (например, отключение интернета) и снова подключился – Google играет в режиме реального времени Тень с плавающей запятой Андроид отключить onclick-событие, когда ссылки на URL-адрес нажали Android: перспектива DDMS против перспективы отладки Извлечь черно-белое изображение из формата NV21 от андроидной камеры Как прочитать тестовый файл в тесте Android Android: беззаботное воспроизведение зацикленного аудиофайла в MediaPlayer Аспекты доступа из другого приложения? GetLayoutInflater () в фрагменте Как публиковать имя устройства (переменная) через Wi-Fi, как это делают некоторые приложения для передачи файлов? Как я могу отображать несколько строк текста на кнопке Ошибка WaitingInMainSignalCatcherLoop в приложении для Android Keytool генерирует отпечаток SHA1 вместо MD5?

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