developer tip

뒤로 버튼을 누른 조각에서 활동이 비어 있습니다.

copycodes 2020. 11. 22. 19:57
반응형

뒤로 버튼을 누른 조각에서 활동이 비어 있습니다.


나는 활동과 많은 조각이 동일하게 팽창했습니다. FrameLayout

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

예 : mainActivity> any fragment (뒤로 버튼 누르기)> 활동이 비어 있습니다.

onCreate에서 :

layout = (FrameLayout)findViewById(R.id.content_frame);
layout.setVisibility(View.GONE);

조각을 시작할 때 :

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
ft.addToBackStack(null);
ft.commit();
layout.setVisibility(View.VISIBLE);

GONE다시 눌렀을 때 frameLayout의 가시성을 다시 만들어야한다고 생각 하지만 어떻게해야합니까?


시도 onBackPressed하고 설정 layout.setVisibility(View.GONE);했지만 메인 페이지로 직접 이동하기 때문에 조각을 통해 돌아갈 수 없습니다.


활동에 둘 이상의 조각이 사용되었거나 조각이 하나만있는 경우에도 첫 번째 조각에는 addToBackStack이 정의되어 있지 않아야합니다. 이것은 뒤로 탐색을 허용하고이 조각 이전에 빈 활동 레이아웃이 표시됩니다.

 // fragmentTransaction.addToBackStack() // dont include this for your first fragment.

그러나 다른 조각의 경우이를 정의해야합니다. 그렇지 않으면 뒤로가 이전 화면 (조각)으로 이동하지 않고 대신 응용 프로그램이 종료 될 수 있습니다.


@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    }
    else {
        int fragments = getSupportFragmentManager().getBackStackEntryCount();
        if (fragments == 1) {
            finish();
        } else if (getFragmentManager().getBackStackEntryCount() > 1) {
            getFragmentManager().popBackStack();
        } else {
            super.onBackPressed();
        }
    }
}

조각을 추가하려면

 getSupportFragmentManager().beginTransaction()
                .replace(R.id.layout_main, dashboardFragment, getString(R.string.title_dashboard))
                .addToBackStack(getString(R.string.title_dashboard))
                .commit();

답장을 늦게 보내서 미안해.

ft.addToBackStack (null) 을 추가 할 필요가 없습니다 . 첫 번째 조각을 추가하는 동안.

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
// ft.addToBackStack(null); --remove this line.
ft.commit();
// ... rest of code

조각별로 추적하려면 다음 onBackPressed과 같이 메서드를 재정의해야 합니다.

public void onBackPressed() { 
   if (getFragmentManager().getBackStackEntryCount() == 1) {
        finish();
   } else {
        super.onBackPressed();
   }
}

onBackPressed백 스택에 무엇이 있는지 재정의 하고 확인할 수 있습니다 .

@Override
public void onBackPressed() {
    int fragments = getFragmentManager().getBackStackEntryCount();
    if (fragments == 1) { 
        // make layout invisible since last fragment will be removed
    }
    super.onBackPressed();
}

최근 개인 프로젝트 addToBackStack에서 스택이 비어 있는지 호출하지 않음으로써이 문제를 해결했습니다 .

    // don't add the first fragment to the backstack
    // otherwise, pressing back on that fragment will result in a blank screen
    if (fragmentManager.getFragments() != null) {
        transaction.addToBackStack(tag);
    }

내 전체 구현은 다음과 같습니다.

    String tag = String.valueOf(mCurrentSectionId);
    FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    if (fragment != null) {
        // if the fragment exists then no need to create it, just pop back to it so
        // that repeatedly toggling between fragments doesn't create a giant stack
        fragmentManager.popBackStackImmediate(tag, 0);
    } else {
        // at this point, popping back to that fragment didn't happen
        // So create a new one and then show it
        fragment = createFragmentForSection(mCurrentSectionId);

        FragmentTransaction transaction = fragmentManager.beginTransaction()
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.main_content, fragment, tag);

        // don't add the first fragment to the backstack
        // otherwise, pressing back on that fragment will result in a blank screen
        if (fragmentManager.getFragments() != null) {
            transaction.addToBackStack(tag);
        }

        transaction.commit();
    }

첫 번째 조각을 백 스택에 추가하지 마십시오.

다음은 나를 위해 일한 Kotlin 코드입니다.

    val ft = supportFragmentManager.beginTransaction().replace(container, frag)
    if (!supportFragmentManager.fragments.isEmpty()) ft.addToBackStack(null)
    ft.commit()

I still could not fix the issue through getBackStackEntryCount() and i solved my issue by making the main page a fragment too, so in the end i have an activity with a FrameLayout only; and all other fragments including the main page i inflate into that layout. This solved my issue.


irscomp's solution works if you want to end activity when back button is pressed on first fragment. But if you want to track all fragments, and go back from one to another in back order, you add all fragments to stack with:

ft.addToBackStack(null);

and then, add this to the end of onCreate() to avoid blank screen in last back pressed; you can use getSupportFragmentManager() or getFragmentManager() depending on your API:

FragmentManager fm = getSupportFragmentManager();
    fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if(getSupportFragmentManager().getBackStackEntryCount() == 0) finish();             
        }
});

Final words: I don't suggest you to use this solution, because if you go from fragment1 to fragment 2 and vice versa 10 times, when you press back button 10 times it will do it in back order which users will not want it.


Almost same as Goodlife's answer, but in Xamarin.Android way:

Load fragment (I wrote helper method for that, but it's not necessary):

public void LoadFragment(Activity activity, Fragment fragment, string fragmentTitle = "")
{
    var fragmentManager = activity.FragmentManager;
    var fragmentTransaction = fragmentManager.BeginTransaction();

    fragmentTransaction.Replace(Resource.Id.mainContainer, fragment);
    fragmentTransaction.AddToBackStack(fragmentTitle);

    fragmentTransaction.Commit();
}

Back button (in MainActivity):

public override void OnBackPressed()
{
    if (isNavDrawerOpen()) drawerLayout.CloseDrawers();
    else
    {
        var backStackEntryCount = FragmentManager.BackStackEntryCount;

        if (backStackEntryCount == 1) Finish();
        else if (backStackEntryCount > 1) FragmentManager.PopBackStack();
        else base.OnBackPressed();
    }
}

And isNavDrawerOpen method:

bool isNavDrawerOpen()
{
    return drawerLayout != null && drawerLayout.IsDrawerOpen(Android.Support.V4.View.GravityCompat.Start);
}

참고URL : https://stackoverflow.com/questions/20340303/in-fragment-on-back-button-pressed-activity-is-blank

반응형