【问题标题】:UpButton doesn't work whatever I try to do无论我尝试做什么,UpButton 都不起作用
【发布时间】:2015-06-14 03:53:52
【问题描述】:

在我的应用程序 (minSdkVersion 15) 中,我有一个 Toolbar 而不是 ActionBarNavigationDrawer 在片段之间切换。一些片段有TabBar,里面有子片段。这些子片段是ListViews,它们的onItemClickListener 触发DetailFragment。我打电话给setDisplayHomeAsUpEnabled()DetailFragment 出现了一个向上的箭头,但我不能让它执行任何操作,甚至不能举杯。我已经尝试过this 并在onOptionsItemSelected() 中处理switch (item.getItemId()),但是这两种解决方案都不适合我。我错过了一些东西,但不知道是什么。

这是我的代码:

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {

//...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //Listen for changes in the back stack
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    //Handle when activity is recreated like on orientation Change
    shouldDisplayHomeUp();

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);
    final ActionBar actionBar = getSupportActionBar(); //...

...

public void shouldDisplayHomeUp(){
    //Enable Up button only  if there are entries in the back stack
    boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0;
    if (getSupportActionBar() != null) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(canback);
        actionBarDrawerToggle.setDrawerIndicatorEnabled(!canback);
    }
}

@Override
public boolean onNavigateUp() {
    //This method is called when the up button is pressed. Just the pop back stack.
    getSupportFragmentManager().popBackStack();
    return true;
}

@Override
public void onBackStackChanged() {
    shouldDisplayHomeUp();
}

我的整个onOptionsItemSelected

@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.
    switch (item.getItemId()) {
        case android.R.id.home:
            Toast.makeText(this, "Up button!", Toast.LENGTH_SHORT).show();
            //called when the up affordance/carat in actionbar is pressed
            onBackPressed();
            break;
        case R.id.action_search:
            Toast.makeText(this, "Search", Toast.LENGTH_SHORT).show();
            break;
    }
    return super.onOptionsItemSelected(item);
}

我不知道其他代码是否重要:

    // Initializing Drawer Layout and ActionBarToggle
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
    actionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,mToolbar,R.string.openDrawer, R.string.closeDrawer){//...


    //Setting the actionbarToggle to drawer layout
    mDrawerLayout.setDrawerListener(actionBarDrawerToggle);

    //calling sync state is necessay or else your hamburger icon wont show up
    actionBarDrawerToggle.syncState();

在我的清单中我没有父活动。

我找到了this,它似乎是正确的答案,但我不明白如何实现它,也没有声誉可以询问作者。

我可以尝试什么让向上按钮工作?

两个新问题:当我设置

public void shouldDisplayHomeUp(){
    //Enable Up button only  if there are entries in the back stack
    if (getSupportActionBar() != null) {
        if (getSupportFragmentManager().getBackStackEntryCount()>0) {
            actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        } else {
            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
            actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
        }
    }
}

...从子片段中,我按下硬件“后退”按钮,返回上一个片段,然后出现汉堡图标。但是向上按钮仍然没有来自子片段的响应。我相信这是因为ActionBarDrawerToggle 不再管理其行为。但是谁来管理它呢?如果我这样设置这个方法:

public void shouldDisplayHomeUp(){
    //Enable Up button only  if there are entries in the back stack
    if (getSupportActionBar() != null) {
        if (getSupportFragmentManager().getBackStackEntryCount()>0) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        } else {
            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        }
    }
}

...然后ActionBarDrawerToggle 处理向上按钮的单击并像汉堡图标一样打开抽屉。但是当我按下硬件后退按钮时,向上按钮(箭头)消失了,汉堡图标也没有出现。

所以现在我看到了解决这个问题的两种方法。首先,我可以弄清楚谁在什么时候管理向上按钮

actionBarDrawerToggle.setDrawerIndicatorEnabled(false);

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

否则,当向上按钮箭头可用而不是汉堡包图标时,如何覆盖 ActionBarDrawerToggle 行为以执行另一个操作?以及如何使我按下硬件返回按钮时出现汉堡图标?

【问题讨论】:

  • 你能把你的整个onOptionsItemSelected()贴出来吗?

标签: android android-fragments up-button


【解决方案1】:

答案很简单,但我花了一天多的时间才弄清楚这一点。我逐步实现了抽屉,为每种方法发现了文档。运行应用程序以注意任何更改。我发现当 setDisplayHomeAsUpEnabled(true) 时,它只会更改后退箭头图标上的抽屉汉堡图标,但是当您单击后退箭头时,它会执行相同的操作(显示隐藏抽屉)。

当你想为返回箭头实现另一种行为时,你应该setDrawerIndicatorEnabled(false) 然后setToolbarNavigationClickListener()。所以

public void shouldDisplayHomeUp(){
//Enable Up button only  if there are entries in the back stack
if (getSupportActionBar() != null) {
    if (getSupportFragmentManager().getBackStackEntryCount()>0) {
        actionBarDrawerToggle.setDrawerIndicatorEnabled(false); // order matters
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    } else {
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
    }
}

actionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getApplicationContext(), "ToolbarNavigationClickListener", Toast.LENGTH_SHORT).show();
        }
    });

协同工作以实现自定义 UpButton 行为。希望它会帮助别人。

【讨论】:

    【解决方案2】:

    您似乎没有处理onOptionsItemSelected() 中的ActionBarDrawerToggle。还返回 true 以使用选择。请尝试以下操作:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...
        switch (item.getItemId()) {
            case android.R.id.home:
                Toast.makeText(this, "Up button!", Toast.LENGTH_SHORT).show();
                //called when the up affordance/carat in actionbar is pressed
                onBackPressed();
                return true;
            case R.id.action_search:
                Toast.makeText(this, "Search", Toast.LENGTH_SHORT).show();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
    

    【讨论】:

    • 感谢您的回答。我试图解释我在上面的更新中发现的内容。当我使用您的解决方案 UpButton 响应单击但行为类似于常规汉堡图标单击行为时:显示隐藏抽屉。
    • 你能确认shouldDisplayHomeUp()setDrawerIndicatorEnabled(false) 被按预期调用吗?您是否使用addToBackStack() 将片段事务添加到后台堆栈?
    • 是的,我很确定应该调用 setDrawerIndicatorEnabled(false) 的 shouldDisplayHomeUp()。 setDrawerIndicatorEnabled() 和 setDisplayHomeAsUpEnabled() 的不同组合返回不同的结果。但它永远不会按预期工作。我也使用 addToBackStack() 添加片段事务 o backstack。
    • 您使用的是 android.support.v7 之外的ActionBarDrawerToggle
    • 是的。我终于找到答案了! @Markus Rubey 感谢您的考虑!
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2020-08-11
    • 2017-01-12
    相关资源
    最近更新 更多