将后退按钮添加到工具栏,用于打开导航抽屉的主页片段以外的所有片段

Add back button to Toolbar for all Fragments other than Home Fragment which opens Navigation Drawer

当我的应用程序打开时显示主屏幕 first.On 我的主屏幕 NavigationDrawer 在按下 HamburgerIcon 后打开。稍后我转到不同的 fragments.When 我我在除主页以外的其他片段中 Activity 我需要在 Toolbar 上显示后退按钮才能回到上一个 fragment.But 每次显示汉堡包 icon.How 来执行此操作?
这是在 XML

中设置 Toolbar 的代码
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/drawerLayout"
    tools:context="biz.fyra.myApp.ActivityTwo">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ccc"
            android:minHeight="?attr/actionBarSize">
            <ImageView
                android:id="@+id/tooImage"
                android:src="@drawable/latest"
                android:layout_width="match_parent"
                android:layout_gravity="center_horizontal"
                android:layout_height="40dp" />
        </android.support.v7.widget.Toolbar>
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/frame">
        </FrameLayout>
    </LinearLayout>
    <android.support.design.widget.NavigationView
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        android:id="@+id/navigationView"
        app:menu="@menu/actionmenu"
        android:background="@android:color/white">
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>  

如何实现?

你可以试试

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {   super.onCreate(savedInstanceState);
[...]
        if (getSupportActionBar() != null)
        {   getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setHomeButtonEnabled(true);
        }
[...]
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {   if (getSupportFragmentManager().getBackStackEntryCount() > 0)
        {   switch (item.getItemId())
            {   case android.R.id.home:
                    onBackPressed();
                    return true;
            }
        }

[...]
    }

如果我没理解错的话,你使用的是 activity 片段替换。所以,看看 你会得到这样的东西:

重要:Activity 主题应扩展 Theme.AppCompat.Light.NoActionBar


Activity:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private Toolbar toolbar;
private ActionBarDrawerToggle toggle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    drawer = findViewById(R.id.drawer);
    toolbar = findViewById(R.id.toolbar);

    setSupportActionBar(toolbar);
    toggle = new ActionBarDrawerToggle(
            this,
            drawer,
            toolbar,
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close
    );
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    // First creation
    if (savedInstanceState == null)
        showFragment(StartFragment.newInstance());
}
/**
* Using in Base Fragment
*/
protected ActionBarDrawerToggle getToggle() {
    return toggle;
}

@Override
public void onBackPressed() {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.frame);

    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else if (fragment instanceof OnBackPressedListener) {
        ((OnBackPressedListener) fragment).onBackPressed();
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    drawer.closeDrawer(GravityCompat.START);
    switch (item.getItemId()) {
        case R.id.start: {
            showFragment(StartFragment.newInstance());
            break;
        }
        case R.id.orders: {
            showFragment(OrdersFragment.newInstance());
            break;
        }
        case R.id.category: {
            showFragment(CategoryFragment.newInstance());
            break;
        }
        case R.id.calendar: {
            showFragment(CalendarFragment.newInstance());
            break;
        }
        case R.id.settings: {
            showFragment(SettingsFragment.newInstance());
            break;
        }
        case R.id.about: {
            showFragment(AboutFragment.newInstance());
            break;
        }
    return true;
}

private void showFragment(Fragment fragment) {
    getSupportFragmentManager().beginTransaction().replace(R.id.frame, fragment).commit();
}
}

从activity向片段发送backpress事件的接口:

public interface OnBackPressedListener {
    void onBackPressed();
}

以及您应该扩展和实现方法的抽象基础片段:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;

import ...
/**
 * Abstract fragment with FAB button, Toolbar and 2 interfaces: 
OnClick, OnBackPress
 *
 */
public abstract class BaseFragment extends Fragment implements 
View.OnClickListener, OnBackPressedListener {

protected FloatingActionButton fab;
protected Toolbar toolbar;
protected ActionBar actionBar;
protected ActionBarDrawerToggle toggle;
protected DrawerLayout drawer;
protected boolean mToolBarNavigationListenerIsRegistered = false;

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    fab = ((MainActivity)getActivity()).findViewById(R.id.fab);
    toolbar = ((MainActivity) getActivity()).findViewById(R.id.toolbar);
    actionBar = ((MainActivity) getActivity()).getSupportActionBar();
    drawer = ((MainActivity) getActivity()).findViewById(R.id.drawer_layout);
    toggle = ((MainActivity) getActivity()).getToggle();
    fab.setOnClickListener(this);
}

/**
* Simplify fragment replacing in child fragments
*/
protected void replaceFragment(@NonNull Fragment fragment) {
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.beginTransaction().replace(R.id.container, fragment).commit();
}

// hide FAB button
protected void hideFab() {
    fab.hide();
}

//show FAB button
protected void showFab() {
    fab.show();
}

/**
 * Shows Home button as Back button
 * Took from here {@link}
 * <p>
 * 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!!!
 *
 * @param show = true to show <showHomeAsUp> or show = false to show <Hamburger> button
 */
protected void showBackButton(boolean show) {

    if (show) {
        // Remove hamburger
        toggle.setDrawerIndicatorEnabled(false);
        // Show back button
        actionBar.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) {
            toggle.setToolbarNavigationClickListener(v -> onBackPressed());
            mToolBarNavigationListenerIsRegistered = true;
        }

    } else {
        // Remove back button
        actionBar.setDisplayHomeAsUpEnabled(false);
        // Show hamburger
        toggle.setDrawerIndicatorEnabled(true);
        // Remove the/any drawer toggle listener
        toggle.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.
}

/**
* Simplify setTitle in child fragments
*/
protected void setTitle(int resId) {
    getActivity().setTitle(getResources().getString(resId));
}

//
@Override
public abstract void onClick(View v);

// Handles BackPress events from MainActivity
@Override
public abstract void onBackPressed();
}

MainActivity 中使用的所有带后退按钮的片段都应从该 BaseFragment 扩展。