Java.lang.IllegalArgumentException: для id 0x1020002 (android: id/content) для фрагмента нет
Я пытаюсь перейти от одного фрагмента к другому. Он показывает следующую ошибку во время транзакции фрагмента -
java.lang.IllegalArgumentException: No view found for id 0x1020002 (android:id/content) for fragment PhotosFragment2{41a57218 #3 id=0x1020002}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:930)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:446)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
at dalvik.system.NativeStart.main(Native Method)
Ниже приведены классы. Я использовал следующий код для транзакции фрагмента
Fragment fragment = new PhotosFragment2();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
PhotosFragment.java
public class PhotosFragment extends Fragment {
private FragmentActivity myContext;
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.photos, container, false);
rootView.setVerticalScrollBarEnabled(false);
int[] mThumbIds = {
R.drawable.album8, R.drawable.album3,
R.drawable.album4, R.drawable.album8,
R.drawable.album6, R.drawable.album7,
R.drawable.album12, R.drawable.album10,
};
int[] mThumbIds2 = {
R.drawable.album8, R.drawable.album3,
R.drawable.album4,
R.drawable.album6, R.drawable.album7,
R.drawable.album9, R.drawable.album10,
R.drawable.album11, R.drawable.album12, R.drawable.album8,
R.drawable.album8, R.drawable.album3,
R.drawable.album4,
R.drawable.album6, R.drawable.album7,
R.drawable.album9, R.drawable.album10,
R.drawable.album11, R.drawable.album12, R.drawable.album8,
};
CustomGridSingle2 adapter = new CustomGridSingle2(myContext, mThumbIds);
GridView grid = (GridView)rootView.findViewById(R.id.gridView);
final ImageView img= (ImageView)rootView.findViewById(R.id.imageView7);
grid.setFocusable(false);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fragment fragment = new PhotosFragment2();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
}
});
CustomGridSingle2 adapter2 = new CustomGridSingle2(myContext, mThumbIds2);
GridView grid2 = (GridView)rootView.findViewById(R.id.gridView2);
grid2.setFocusable(false);
grid2.setAdapter(adapter2);
grid2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fragment fragment = new PhotosFragment2();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
}
});
return rootView;
}
}
PhotosFragment2.java
public class PhotosFragment2 extends Fragment {
private FragmentActivity myContext;
@Override
public void onAttach(Activity activity) {
myContext = (FragmentActivity) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.photos2, container, false);
myContext.getActionBar().hide();
return rootView;
}
}
Файл операции xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/left_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@drawable/bgmenu"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/profilelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:paddingTop="10dp">
<ImageView
android:id="@+id/drawer_profile_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/drawer_profile_background"
android:layout_alignLeft="@+id/drawer_profile_background"
android:layout_alignRight="@+id/drawer_profile_background"
android:layout_alignTop="@+id/drawer_profile_background"
android:layout_marginBottom="7.667dp"
android:layout_marginLeft="6.5dp"
android:layout_marginRight="8.3dp"
android:layout_marginTop="7.667dp"
android:scaleType="centerCrop"></ImageView>
<ImageView
android:id="@+id/drawer_profile_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:scaleType="centerCrop"
android:src="@drawable/profileblock">
</ImageView>
<ImageView
android:id="@+id/settingicon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/drawer_profile_background"
android:layout_marginLeft="-15dp"
android:layout_toRightOf="@+id/drawer_profile_background"
android:background="@drawable/settings" />
<textview
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/drawer_profile_background"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textColor="@android:color/white" />
</RelativeLayout>
<ListView
android:id="@+id/list_slidermenu"
style="@style/buttonStyle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="30dp"
android:layout_weight="2"
android:cacheColorHint="@android:color/transparent"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="1dp"
android:listSelector="@android:color/transparent"
android:scrollbars="none" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
Ответы
Ответ 1
Когда вы используете fragmentTransaction.replace(R.id.container,fragment)
он удалит все фрагменты, которые уже находятся в контейнере, и добавит ваш новый в тот же контейнер.
Теперь я могу предложить вам 2 вещи. Во-первых, если вы хотите использовать fragmentTransaction.replace(android.R.id.content, fragment);
что вы делаете прямо сейчас, то не устанавливайте контент для вашей Activity
с помощью setContentView
должно работать нормально. Чтобы знать, что именно android.R.id.content
вы можете сослаться на этот вопрос и ответ на стекопоток
Или, во-вторых, в макете вашей Activity
есть FrameLayout
чей идентификатор является content
. А потом использовать
fragmentTransaction.replace(R.id.content, fragment);
fragmentTransaction.addToBackStack(null);//add the transaction to the back stack so the user can navigate back
// Commit the transaction
fragmentTransaction.commit();
Надеюсь это поможет.
Больше информации:
Из ваших комментариев кажется, что у вас возникли проблемы с FrameLayout
использования FrameLayout
в макете Activity
(а не в макете Fragment
). Из документов
FrameLayout предназначен для блокировки области на экране для отображения одного элемента. Как правило, FrameLayout следует использовать для хранения одного дочернего представления, потому что может быть трудно организовать дочерние представления таким образом, чтобы их можно было масштабировать до разных размеров экрана без перекрытия дочерних элементов друг с другом.
Таким образом, основная цель FrameLayout
- заблокировать область, необходимую для наибольшего дочернего представления. Если вы используете FrameLayout
качестве контейнера Fragment
вы можете быть уверены, что у вас всегда будет свободное место для размещения самого большого макета Fragment
.
Таким образом, вы можете иметь свой FrameLayout
что-то вроде этого в вашем XML файле макета Activity
<FrameLayout
android:id="@+id/content"
android:layout_height="match_parent"
android:layout_width="match_parent">
<!--you can put your existing views of your current xml here, so yes your entire xml is now inside this FrameLayout -->
</FrameLayout>
Ответ 2
Я не использую getSupportFragmentManager()
.
Я использую getChildFragmentManager()
, и это сработало для меня.
Вы можете попробовать.
Ответ 3
Если вы пытаетесь поместить Fragment
в Fragment
, используйте getChildFragmentManager()
Ответ 4
Если вы используете ViewPager, используйте getChildFragmentManager() для адаптера пейджера
viewPager.setAdapter(new ItemsAdapter(getChildFragmentManager()));
Ответ 5
Вы должны установить в своем мероприятии представление содержимого, в которое будет добавлен ваш фотофрагмент.
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
//...
}
Ответ 6
Есть две наиболее распространенные причины этой проблемы.
- Указание неправильного макета в setContentView() метода onCreate()
- Ошибка также возникает при наличии вложенных фрагментов и их добавлении с помощью getSupportFragmentManager() вместо getChildFragmentManager()
Надеюсь, это поможет
Summved
Ответ 7
Так как Android 4.2 (API 17) вложенные фрагменты становятся доступными.
См. this
Чтобы разместить фрагмент внутри другого фрагмента, используйте getChildFragmentManager()
Также доступен в библиотеке поддержки.
Ответ 8
Я знаю, что это очень поздно. Но это может сработать для других.
Я объявил идентификатор для каждого макета, например (3-я строка ниже)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
Ответ 9
Поместите этот блок кода в метод PhotosFragment2 onCreateView:
View rootView = inflater.inflate(R.layout.photos2, null);
вместо:
View rootView = inflater.inflate(R.layout.photos2, container, false);
Ответ 10
в моем случае мне пришлось изменить
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.sample,
container);
к
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.sample,
container, false);
Ответ 11
В этом ответе подчеркивается глупая ошибка, которая может возникнуть, возникающая при вложении фрагментов или преобразовании действий в фрагменты.
Если вы пытаетесь заменить фрагмент внутри фрагмента на fragmentManager
, но вы не раздуваете родительский фрагмент, который может вызвать проблему.
В BaseFragment.java OnCreateView
:
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.replace(R.id.container, new DifferentFragment())
.commit();
}
return super.onCreateView(inflater, container, savedInstanceState);
Заменить super.onCreateView(inflater, container, savedInstanceState);
с раздуванием правильной компоновки для фрагмента:
return inflater.inflate(R.layout.base_fragment, container, false);
Ответ 12
Проблема может заключаться в том, что вы добавляете фрагмент и beginTransaction в некоторый фрагмент, например
getFragmentManager().beginTransaction().replace(android.R.id.content, ImageBrowseFragment.newInstance(bundle),"ImageBrowseFragment")
.addToBackStack(null).commit();
Я просто изменяю getFragmentManager()
на getActivity().getSupportFragmentManager()
Затем все идет нормально
Когда вы добавляете фрагмент в фрагменте, используйте android.R.id.content
or Window.ID_ANDROID_CONTENT
, я предполагаю, что он представляет собой корневой контейнер вашего фрагмента, а не активность. Итак, измените на getActivity().getSupportFragmentManager()
.
Ответ 13
У меня была такая же ошибка, и после многих попыток я обнаружил, что проблема связана с "id" и "getActivity(). getSupportFragmentManager()".
Перед тем, как реализовать, мне нравятся эти
txt_more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getChildFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, new OpportunitiesFragment())
.commit(); }
});
Затем я изменил эти
txt_more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
## Heading ##
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new OpportunitiesFragment())
.commit(); }
});
Ответ 14
Если вы используете ViewPager
с фрагментами (страницами) и пытаетесь показать новый фрагмент со страницы, вы получите эту ошибку. Я думаю, что вы не можете ссылаться на контейнер Activity
со страницы ViewPager
.
В этом случае вы должны вызвать getActivity()
. Затем в Activity
напишите метод, который откроет новый фрагмент.
class YourActivity : AppCompatActivity() {
fun showNewFragment(title: String) {
val fm = supportFragmentManager
fm?.beginTransaction()?.apply {
val fragment = NewFragment.newInstance(title)
replace(R.id.container, fragment, NewFragment.TAG)
addToBackStack(null)
}?.commit()
}
}
class PageFragment : Fragment() {
private fun show() {
(activity as YourActivity).showNewFragment("New fragment")
}
}
Если вы getParentFragment()
и добавите новый фрагмент, то вы поместите новый фрагмент в ViewPager
:
class ViewPagerFragment : Fragment() {
fun showNewFragment(title: String) {
val fm = childFragmentManager
fm?.beginTransaction()?.apply {
val fragment = NewFragment.newInstance(title)
replace(R.id.container, fragment, NewFragment.TAG)
addToBackStack(null)
}?.commit()
}
}
class PageFragment : Fragment() {
private fun show() {
(parentFragment as? ViewPagerFragment)?.showNewFragment("New fragment")
}
}