工具栏-仅通过一个活动即可从抽屉切换到后退按钮 [英] Toolbar - Switching from drawer to back button with only one Activity

查看:73
本文介绍了工具栏-仅通过一个活动即可从抽屉切换到后退按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找如何在抽屉打开/关闭图标(从汉堡到箭头)到一个简单的后退箭头之间切换的方法.目前,我的应用程序只有一个Activity,可以在多个片段之间进行切换.在某一时刻,我想在一个主要片段(即抽屉中的一个片段)之间过渡到一个分层结构,该片段分层地位于前一个片段之下(即"Add New"片段).在这个新片段中,我希望工具栏显示后退按钮而不是抽屉按钮.

I've been searching for a while on how to change between the drawer open/close icon (going from a hamburger to the arrow) to a simple back arrow. My application at the moment only has one Activity which switches between several fragments. At one point, I want to transition between one of the main fragments (ie, one of the fragments in the drawer) to a fragment that hierarchically is under the previous fragment (ie, an "Add New " fragment). In this new fragment, I want to have the Toolbar to show the back button instead of the drawer button.

我已经四处寻找并尝试了不同的解决方案.这是最著名的:

I've been looking around and trying different solutions for quite a while. Here are the most notable:

  • Change drawer icon back to back arrow - I successfully removed the drawer icon, but in place there's.... nothing. No up caret, no back button, no icon. I suspect this is because my Activity has no parent, but other than a cheap work around (create another Activity that acts as a parent which launches the main Activity), I'm at a lost of what to do.
  • Switching between Android Navigation Drawer image and Up caret when using fragments - Similar to the above, yet has far more detail. Ultimately, the icon still doesn't turn into a back button.
  • Android lollipop toolbar switch between open/close drawer and back button - I find this hard to follow, but ultimately the drawer icon can be tapped and does nothing (although I believe I know how to make it act as a back press). However, the icon doesn't change.

目前,我正在考虑创建一个隐藏并显示(以及隐藏/显示本机抽屉图标)的自定义图标的漫长而艰巨的方法.但是,是否有更好的方式在抽屉按钮和后退按钮之间进行切换?

At the moment, I'm thinking of a long, arduous method of creating a custom icon that I hide and show (and hide/show the native drawer icon). However, is there a better way to switch between the drawer and back buttons?

作为一个侧面但又相关的问题,我一直在查看Material Design文档,并且一些示例的左上角有一个X.与实现抽屉与后退/向上按钮相比,实现起来有何不同?

As a side yet related question, I've been looking at the Material Design docs, and a few examples have an X in the top left corner. How different is that to implement than implementing the drawer vs back/up buttons?

谢谢〜

我可以弄清楚如何替换图标,但是如何获得点击事件?

I can figure out how to replace the icon, but how would I get the click event?

到目前为止,这是我最好的线索:

So far, this was my best lead:

我现在尝试过的事情:

  • 必要时禁用DrawerToggle(即mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);)
  • 在我的NavigationDrawerFragment,我的Activity以及我当前正在测试的DialogFragment中的onOptionsItemSelected中添加日志,如果item.getItemId() == android.R.id.home为true,则运行该对话框.这些日志语句都不会消失
  • Disabled the DrawerToggle when necessary (ie, mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);)
  • Added logs in onOptionsItemSelected in my NavigationDrawerFragment, my Activity, as well as the DialogFragment I'm currently testing which run if item.getItemId() == android.R.id.home is true. None of these log statements go off

为了获得更好的上下文,我现在有一个全屏片段,该片段在菜单上添加了保存"按钮,并将抽屉图标更改为"X".片段可以获取保存菜单事件,但是在点按X时,甚至活动和抽屉都无法获取.

For better context, I now have a full screen fragment which adds a "Save" button to the menu and changes the drawer icon to an "X". The fragment can get the save menu event, yet not even the Activity and Drawer can get when the X is tapped.

根据要求,下面是一些代码.请注意,这些全部来自此Github存储库,我正在积极开展工作(注意我在快速测试中到处都有一些没用的功能.

As requested, here is some code. Note that this is all from this Github repo, which I'm actively working on (note that I have a few useless functions here or there from rapid testing).

ActivityMain:

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

    // Add the toolbar
    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    if (mToolbar != null) {
        setSupportActionBar(mToolbar);
    }

    // Initialize the drawer
    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);

    // Set up the drawer
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout),
            mToolbar);

    // TODO: Check if this helps to catch the main toolbar button click
    getSupportActionBar().setDisplayShowHomeEnabled(true);

    // Get the titles for the Toolbar
    mTitles = getResources().getStringArray(R.array.drawer_items);

    mDrawerPosition = -1;
    if (savedInstanceState == null) {
        // If there was no saved position, then the default, starting position should be used
        forceChangeItemSelected(0);
    }
    else {
        // Otherwise, get the saved position from the bundle
        int position = savedInstanceState.getInt(KEY_DRAWERPOS);
        mNavigationDrawerFragment.setSelectedItem(position);
        // Title needs to be re-set
        getSupportActionBar().setTitle(mTitles[position]);
    }

    // If I include the below bit, then the DrawerToggle doesn't function
        // I don't know how to switch it back and forth
    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(LOG_TAG, "Navigation was clicked");

        }
    });
}

@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.
    Log.d(LOG_TAG, "Activity responding to menu click...");
    if(item.getItemId() == android.R.id.home) Log.d(LOG_TAG, "Activity got it....");

    // If the fragment is supposed to handle things, then let it
    if(mIsFragmentHandlingMenus) return false;

    int id = item.getItemId();
    if(id == R.id.save) {
        // This isn't implemented! If chosen, then there's a bug!
        Log.e(LOG_TAG, "onOptionsItemSelected: Save was selected!");
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void fragmentHandlingMenus(boolean isFragmentHandlingMenus) {
    // Simply store the setting
    mIsFragmentHandlingMenus = isFragmentHandlingMenus;

    // Toggle the drawer as necessary
    mNavigationDrawerFragment.toggleDrawerUse(!isFragmentHandlingMenus);
}

NavigationDrawerFragment :

public void toggleDrawerUse(boolean useDrawer) {
    // Enable/Disable the icon being used by the drawer
    mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);

    // TODO: Enable/Disable the drawer even being able to open/close
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Log.d(LOGTAG, "Drawer responding to menu click...");
    if(item.getItemId() == android.R.id.home) Log.d(LOGTAG, "Drawer got it....");
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

GoalAdderFragment :

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // Allow this fragment to handle toolbar menu items
    setHasOptionsMenu(true);

    // Set up the toolbar
    ((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    ((ActionBarActivity) getActivity()).getSupportActionBar().setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel);
    ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(getResources().getString(R.string.title_addgoal));
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // Cache the Activity as the frag handler if necessary
    if(mFragHandler == null)
        mFragHandler = (TransactionHandler.FragmentTransactionHandler) getActivity();
    // Tell the Activity to let fragments handle the menu events
    mFragHandler.fragmentHandlingMenus(true);
}

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

    // Tell the Activity that it can now handle menu events once again
    mFragHandler.fragmentHandlingMenus(false);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.save_menu, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Log.d(LOGTAG, "Item id: " + item.getItemId() + " | Save id: " + R.id.save);
    Toast.makeText(getActivity(), "Fragment activated!", Toast.LENGTH_SHORT).show();

    switch (item.getItemId()) {
        case R.id.save:
            return true;
        case android.R.id.home:
            return true;
        default:
            break;
    }

    return false;
}

解决方案:

这是我最终得到的最终解决方案,借助以下公认的答案:

Solution:

This is the ultimate solution I ended up on, with the help of the accepted answer below:

NavigationDrawerFragment :

private View.OnClickListener mOriginalListener;

public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
     /* Rest of setting up code */

     // Save the default listener after setting everything else up
     mOriginalListener = mDrawerToggle.getToolbarNavigationClickListener();
}

// Tells the toolbar+drawer to switch to the up button or switch back to the normal drawer
public void toggleDrawerUse(boolean useDrawer) {
    // Enable/Disable the icon being used by the drawer
    mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);

    // Switch between the listeners as necessary
    if(useDrawer)
        mDrawerToggle.setToolbarNavigationClickListener(mOriginalListener);
    else
        mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(), "Custom listener", Toast.LENGTH_SHORT).show();
            }
        });
}

推荐答案

将此代码放入ActivityonCreate()中.对我来说效果很好.甚至使用compileSdk 23或更高版本.

Put this code into onCreate() of your Activity. Works well for me. Even using compileSdk 23 and higher.

    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    if(toolbar != null) {
        toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        toggle.syncState();
        drawer.setDrawerListener(toggle);
        getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    getSupportActionBar().setDisplayHomeAsUpEnabled(true); // show back button
                    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            onBackPressed();
                        }
                    });
                } else {
                    //show hamburger
                    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                    toggle.syncState();
                    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            drawer.openDrawer(GravityCompat.START);
                        }
                    });
                }
            }
        });

这篇关于工具栏-仅通过一个活动即可从抽屉切换到后退按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆