用您的Activity 和Fragment 的某种责任划分来说明要容易得多。
问题1:管理左上角的汉堡包/返回按钮。将图标和功能切换到菜单和返回导航。
从图中可以看出,解决方案应该用Activity封装,看起来像这样:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawer;
private ActionBar mActionBar;
private boolean mToolBarNavigationListenerIsRegistered = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mActionBar = getSupportActionBar();
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
mDrawer.addDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// On orientation change savedInstanceState will not be null.
// Use this to show hamburger or up icon based on fragment back stack.
if(savedInstanceState != null){
resolveUpButtonWithFragmentStack();
} else {
// You probably want to add your ListFragment here.
}
}
@Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount >= 1) {
getSupportFragmentManager().popBackStack();
// Change to hamburger icon if at bottom of stack
if(backStackCount == 1){
showUpButton(false);
}
} else {
super.onBackPressed();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} else if (id == android.R.id.home) {
// Home/Up logic handled by onBackPressed implementation
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
// Navigation drawer item selection logic goes here
mDrawer.closeDrawer(GravityCompat.START);
return true;
}
private void replaceFragment() {
/**
* Your fragment replacement logic goes here
* e.g.
* FragmentTransaction ft = getFragmentManager().beginTransaction();
* String tag = "MyFragment";
* ft.replace(R.id.content, MyFragment.newInstance(tag), tag).addToBackStack(null).commit();
*/
// The part that changes the hamburger icon to the up icon
showUpButton(true);
}
private void resolveUpButtonWithFragmentStack() {
showUpButton(getSupportFragmentManager().getBackStackEntryCount() > 0);
}
private void showUpButton(boolean show) {
// To keep states of ActionBar and ActionBarDrawerToggle synchronized,
// when you enable on one, you disable on the other.
// And as you may notice, the order for this operation is disable first, then enable - VERY VERY IMPORTANT.
if(show) {
// Remove hamburger
mDrawerToggle.setDrawerIndicatorEnabled(false);
// Show back button
mActionBar.setDisplayHomeAsUpEnabled(true);
// when DrawerToggle is disabled i.e. setDrawerIndicatorEnabled(false), navigation icon
// clicks are disabled i.e. the UP button will not work.
// We need to add a listener, as in below, so DrawerToggle will forward
// click events to this listener.
if(!mToolBarNavigationListenerIsRegistered) {
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
mToolBarNavigationListenerIsRegistered = true;
}
} else {
// Remove back button
mActionBar.setDisplayHomeAsUpEnabled(false);
// Show hamburger
mDrawerToggle.setDrawerIndicatorEnabled(true);
// Remove the/any drawer toggle listener
mDrawerToggle.setToolbarNavigationClickListener(null);
mToolBarNavigationListenerIsRegistered = false;
}
// So, one may think "Hmm why not simplify to:
// .....
// getSupportActionBar().setDisplayHomeAsUpEnabled(enable);
// mDrawer.setDrawerIndicatorEnabled(!enable);
// ......
// To re-iterate, the order in which you enable and disable views IS important #dontSimplify.
}
}
问题 2:页面标题 - 每当插入和弹出片段时更改页面标题。
基本上,这可以在每个Fragment 的onStart 中处理,即您的 ListFragment、DetailsFragment 和 CommentsFragment 看起来像这样:
@Override
public void onStart() {
super.onStart();
// where mText is the title you want on your toolbar/actionBar
getActivity().setTitle(mText);
}
在您的片段的onCreate 中也可能值得拥有setRetainInstance(true)。