조각은 대체되지 않지만 이전 조각 위에 놓입니다.


104

활동:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();

transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();

FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();

보기의 코드 :

<fragment
    android:id="@+id/Fragment1"
    android:name="com.landa.fragment.Fragment1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/include1" /> 

문제는 콘텐츠가 실제로 교체되지 않는다는 것입니다.

다시 클릭하면 첫 번째 조각이 제대로 표시되지만 (두 번째 조각은 제외) 처음에는 둘 다 표시됩니다 (마지막 조각 만 표시하고 싶습니다).

내가 여기서 무엇을 놓치고 있습니까?


내 경우에는 문제는 내가 즉, 내가 올바른 통과되지 않은, 컨테이너보기의 해당 ID를 사용하지 않는 것을 사실로 인해했다 containerViewId합니다 (의 replace방법).
nbro

답변:


145

여기서 두 가지 잘못하고 있습니다.

  1. xml레이아웃 파일 에 정적으로 배치 된 조각은 바꿀 수 없습니다 . FrameLayout레이아웃에 컨테이너 (예 : a )를 생성 한 다음을 사용하여 프로그래밍 방식으로 조각을 추가해야합니다 FragmentTransaction.

  2. FragmentTransaction.replace첫 번째 매개 변수로 조각의 ID가 아니라 조각을 포함하는 컨테이너의 ID를 예상합니다. 따라서 첫 번째 조각을 추가 한 컨테이너의 ID로 첫 번째 인수를 전달해야합니다.

자세한 내용 은 이 링크 를 참조하십시오.


17
FrameLayout컨테이너로 사용 하는 것이 LinearLayout.
Marcel Bro

3
내 문제는 너무 활동의 빈 FrameLayout이 해결 사용
미묘한 폭스

1
이렇게 작동합니다. 하지만 애플리케이션을 시작하고 즉시 뒤로 버튼을 누르면 앱을 종료하는 대신 프래그먼트가 비어있는 상태가됩니다.
MasterScrat

@MasterScrat addTobackStack(..)처음으로 거래를 할 때 생략하십시오 . 이렇게하면 빈 FrameLayout 컨테이너가 백 스택에 배치되지 않습니다. 추가 한 조각으로 다시 이동할 수 있습니다.
Alex Meuer 2017-08-02

여기 당신의 설명을 보여주는 훌륭한 비디오가 있습니다. youtube.com/watch?v=EbcdMxAIr54
SQL 및 Java 학습자

32

비슷한 문제가 있었지만 내 문제는 두 개의 다른 Fragment 관리자를 사용 getSupportFragmentManager()하고 있다는 것입니다 getFragmentManager(). 하나의 조각을으로 추가 한 다음 조각 SupportFragmentManager을으로 바꾸려고 FragmentManager하면 조각이 맨 위에 추가됩니다. 동일한 코드를 FragmentManager사용하고 문제를 처리 하도록 코드를 변경해야했습니다 .


17

안드로이드 개발자 사이트에서는 FrameLayout런타임에 동적으로 조각을로드 하기 위해 a 를 사용할 것을 제안합니다 . xml 파일에 조각을 하드 코딩했습니다. 따라서이 링크에서 언급 한대로 런타임에 제거 할 수 없습니다.

http://developer.android.com/training/basics/fragments/creating.html

이 링크는 프로그램을 통해 조각을 추가하는 방법을 보여줍니다.

http://developer.android.com/training/basics/fragments/fragment-ui.html


7

나는 같은 문제가 있었고 모든 답을 보았지만 그들 중 어느 것도 내 실수를 포함하지 않았습니다! 현재 조각을 교체하기 전에 다음과 같이 컨테이너 활동의 xml에 기본 조각을 표시했습니다.

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="....ShopFragment"
        android:id="@+id/fragment"
        tools:layout="@layout/fragment_shop" />
</FrameLayout>

그 후, 나는이 통과되었지만 FrameLayout받는 fragmentTransaction.replace()하지만 난 정확한 문제가 있었다. 이전 조각 위에 두 번째 조각이 표시되었습니다.

XML에서 조각을 제거하고 onCreate()다음과 같이 프로그램 시작시 기본 미리보기에 대한 컨테이너 활동 의 메서드 에서 프로그래밍 방식으로 표시하여 문제를 해결 했습니다.

    fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment());
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

및 컨테이너 활동 xml :

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

4

조각을 교체하기 전에 backStack을 지울 수 있습니다.

    FragmentManager fm = getActivity().getSupportFragmentManager();

    for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
        fm.popBackStack();
    }

    // replace your fragments

문제는 그가 자신의 xml 레이아웃 파일에서 조각을 선언했다는 것입니다. 따라서 런타임에 제거 / 교체 할 수 없습니다.
Poonam Anthony

이것은 저에게 효과적이었습니다. 백 스택을 지우지 않고 조각을 교체하려고하면 가장 최근의 백 스택 항목이 다른 조각 위에 남는 것처럼 보였습니다.
speedynomads

3
<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:windowBackground">
//Add fragment here
</FrameLayout>

android:background="?android:windowBackground">조각이있는 컨테이너에 추가 합니다. 제 경우에는 FrameLayout도움이 될을 추가했습니다 .


1

조각을 사용하는 대신 컨테이너 사용

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hello World!" />

이제 MainActivity에서

if(condition)
    getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();                    
else
    getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();

프래그먼트 클래스는 'android.app.Fragment'를 가져와야합니다. "support.v4"또는 "원본"구현을 사용하고 두 가지를 혼합하지 마십시오. 나는 그들을 혼합했기 때문에이 문제가 발생했습니다.


0

나는 Sapan Diwakar의 대답에 동의합니다. 그러나 이것을 수행하는 방법에 대한 해결 방법을 찾았습니다.

먼저 activity_main모든 레이아웃이있는 활동 (예 :)에서 FrameLayout. 높이와 너비는 match parent. 또한 id.

이제 현재 레이아웃을 대체 할 조각에서 onPause()onResume(). 의 모든 내부 컨테이너를 초기화합니다 View. 그리고 자신의 설정 visibilityGONE있는onResume()VISIBLEonPause() .

참고 : FrameLayout이 조각으로 바꾸려는 것이 아닙니다 .

당신은 가정 ViewPager, TabLayout, ImageView및 사용자 정의 <fragment>에서 activity_main.xml. FrameLayout위에서 언급 한대로 a 를 추가합니다 .

에서은 abcFragment.javaonClick()기능 추가 addToBackstack(null)에서 transaction.

예제 코드 :

abcFragment (및 activity_main.xml에 표시된 모든 항목)를 대체 할 xyzFragment에서 다음을 수행합니다.

@Override
    public void onResume() {
        super.onResume();

    // On resume, make everything in activity_main invisible except this fragment.
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.GONE);
    viewPager.setVisibility(View.GONE);
    miniPlayerFragment.setVisibility(View.GONE);
}

@Override
public void onPause() {
    super.onPause();

    // Make everything visible again
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.VISIBLE);
    viewPager.setVisibility(View.VISIBLE);
    miniPlayerFragment.setVisibility(View.VISIBLE);
}

즐거운 코딩 되세요!


0

FragmentTransaction의 setTransition 메서드를 사용하여 겹치는 문제를 해결할 수 있습니다.

transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

0

Oncreate ()에서

  BaseFragmentloginpage fragment = new BaseFragmentloginpage();
            android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.frame, fragment);
            fragmentTransaction.isAddToBackStackAllowed();
            fragmentTransaction.commit();

이제 이것은 항상 기본 조각이 될 것입니다 ... xml 레이아웃에 조각을 추가하면 항상 겹칠 것이므로 런타임에 조각으로 초기 콘텐츠를 설정하십시오.


0

이 문제를 사용한 후에도 같은 문제가 해결되었습니다.

  1. u가 ur 조각을 대체하는 프레임 레이아웃 가져 오기

    <FrameLayout
                    android:id="@+id/fragment_place"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
  2. 및 교체 용 코드

    public void selectFrag(View view) {
    Fragment fr;
    
      if(view == findViewById(R.id.button2))
    {
         fr = new FragmentTwo();
    
     }else {
         fr = new FragmentOne();
     }
     FragmentManager fm = getFragmentManager();
     FragmentTransaction fragmentTransaction = fm.beginTransaction();
     fragmentTransaction.replace(R.id.fragment_place, fr);
     fragmentTransaction.commit();

전체 예시를 원하시면 댓글로 보내 드리겠습니다 ...


0

나도 같은 문제가 있었지만 프레임 레이아웃에 추가하려는 조각의 배경색을 변경하지 않았기 때문입니다.

와,이 일을 시도 layout_height하고 layout_width설정match_parent


0

한 번이 문제가 있었고 실수로 android:backgroundxml 코드에서 누락 된 속성을 삭제했기 때문이라는 것을 알았습니다 . 나는 그것이 벽을 칠할 때처럼 작동한다고 믿습니다 android:background. 벽이 될 색상이고 다른 뷰는 그 기본 색상 위에 배치됩니다. 뷰를 배치하기 전에 벽을 칠하지 않으면 해당 벽에 이미 있던 것, 귀하의 경우에는 다른 조각 위에 놓이게됩니다. 그래도 도움이 될지 모르겠습니다. 행운을 빕니다.


0

나는 무엇보다도 모든 경우를 시도하고 문제를 해결하려고 시도했지만 여전히 해결책을 얻지 못했습니다. 왜 그것이 나를 위해 작동하지 않는지 모르겠습니다. 많은 사람들이 동의하기 때문에 위의 답변에 동의합니다.

나는 대답을 확장하고 있으며 아래는 나를 위해 일하는 방식입니다.

이 속성 android:clickable="true"fragment.xml파일의 상위 상위 레이아웃에 추가했습니다 .

누군가가 도움을 받기를 바랍니다.


0

Sapan Diwakar와 다른 사람들에게 감사합니다. 이 답변이 도움이되었습니다. 내부에 조각이없는 RelativeLayout을 만들고 RelativeLayout을 부모 또는 그룹보기로 사용하고 대체 할 트랜잭션에서 해당 그룹보기를 지정하고 작동했습니다.

암호:

getSupportFragmentManager().beginTransaction()
                            .replace(R.id.content_group_view, itemDetailFragment).commit();

XML :

 <RelativeLayout
         android:id="@+id/content_group_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

 </RelativeLayout>

0

프레임 레이아웃 ID를 확인하고 아래와 같이 교체하십시오.

fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.