onBackPressed 和 backStack 在退出前显示空白屏幕

onBackPressed and backStack showing blank screen before exit

早些时候,我遇到了 onBackPressed 问题,在一些帮助下得到了解决

经过一些研究后,我发现由于我的起始片段在后台堆栈中,它会产生额外的 'back' 计数,所以当我尝试退出我的应用程序时,我得到一个空白屏幕:

而不是空白屏幕,我应该得到 "Are you sure to exit" 的提示而不是空白。从空白屏幕中,我确实得到了我的 'are you sure to exit' 菜单,但我不希望看到额外的空白屏幕。

I've also noticed that it seems to not update the fragment titles on the back pressed, but I'm assuming that's another issue all together.

我不确定如何将我的主页片段与 backStack 计数分开。如果我要避免将其添加到堆栈中,但将其保留为导航项,我什至不知道它是如何工作的。

代码:

public class Home extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {
private Fragment fragment = null;
private FragmentManager fragmentManager;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    DatabaseHelper myDbHelper = new DatabaseHelper(Home.this);


    try {
        myDbHelper.createDataBase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setItemIconTintList(null);
//        getHome();

    displayView(R.id.nav_large_monsters);

}

private boolean viewIsAtHome;

@Override
public void onBackPressed() {
    // Pressing back popped the back stack, nothing else to do
    FragmentManager fragmentManager = getSupportFragmentManager();
    if (!fragmentManager.isStateSaved() && fragmentManager.popBackStackImmediate()) {
        return;
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        }

    if (!viewIsAtHome) {
            displayView(R.id.nav_large_monsters);
        } else {
            new AlertDialog.Builder(this)
                    .setMessage("Are you sure you want to exit?")
                    .setCancelable(false)
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            Home.this.finish();
                        }
                    })
                    .setNegativeButton("No", null)
                    .show();
     }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.search_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    return super.onOptionsItemSelected(item);
}


private void getHome(){
    fragment = new HomeFragment();
    if (fragment != null) {
        FragmentManager fragmentMgmt = getSupportFragmentManager();
        fragmentMgmt.beginTransaction().replace(R.id.content_frame, fragment).commit();
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    displayView(item.getItemId());
    return true;

}

public void displayView(int viewId) {

//        Fragment fragment = null;
    String title = getString(R.string.app_name);

    switch (viewId) {
        default:
            fragment = new Large_Monsters();
            title  = "Large Monsters";
            break;

        case R.id.nav_large_monsters:
            fragment = new Large_Monsters();
            title  = "Large Monsters";
            viewIsAtHome = true;
            break;

        case R.id.nav_small_monsters:
            fragment = new Small_Monsters();
            title = "Small Monsters";
            viewIsAtHome = false;
            break;

        case R.id.nav_weapons:
            fragment = new Weapons();
            title = "Weapons";
            viewIsAtHome = false;
            break;

        case R.id.nav_armors:
            fragment = new Armors_Low_High();
            title = "Armor Sets";
            viewIsAtHome = false;
            break;

        case R.id.nav_charms:
            fragment = new Charms();
            title = "Charms";
            viewIsAtHome = false;
            break;

        case R.id.nav_items:
            fragment = new Items();
            title = "Items";
            viewIsAtHome = false;
            break;

        case R.id.palico_armor:
            fragment = new Palico_Armor();
            title = "Palico Armor";
            viewIsAtHome = false;
            break;

        case R.id.palico_gadgets:
            fragment = new Palico_Gadgets();
            title = "Palico Gadgets";
            viewIsAtHome = false;
            break;

        case R.id.palico_weps:
            fragment = new Palico_Weapons();
            title = "Palico Weapons";
            viewIsAtHome = false;
            break;

        case R.id.palico_helms:
            fragment = new Palico_Helms();
            title = "Palico Helmets";
            viewIsAtHome = false;
            break;

    }

    if (fragment != null) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.content_frame, fragment, fragment.getTag());
                ft.addToBackStack(null);
                ft.commit();
    }

    // set the toolbar title
    if (getSupportActionBar() != null) {
        getSupportActionBar().setTitle(title);
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);

}

}

我想我在发布这篇文章后就明白了...

onBackPressed() 中的部分:

if (!viewIsAtHome) {
            displayView(R.id.nav_large_monsters);
        }

是否可以帮助设置主页的检查,但如果我使用我的 getHome() 方法,并将其设置在 OnCreate 下:

private void getHome(){
    fragment = new Large_Monsters();

    if (fragment != null) {
        FragmentManager fragmentMgmt = getSupportFragmentManager();
        fragmentMgmt.beginTransaction().replace(R.id.content_frame, fragment).commit();
    }
}

这让我设置了我的主页,并避免了在 onBackPressed 的双重检查。但主要是,这避免了在我的 onNavigationItemSelected 区域设置检查,让我们 android 照常处理 onBackPressed。

您不必在主页上调用 addToBackStack(null)(例如:Large_Monsters 片段)

所以只需像这样添加 onCreate 方法

Large_Monsters fragment = new Large_Monsters();

if (fragment != null) {
    FragmentManager fragmentMgmt = getSupportFragmentManager();
    fragmentMgmt.beginTransaction().replace(R.id.content_frame, fragment).commit();
}

在你的左侧菜单中,你只需要检查这个片段是否存在,如果不存在则替换它,否则删除其他片段。