处理动作条标题与片段回栈?(Handling ActionBar title with the fr

2019-07-04 00:12发布

我有一个Activity ,其中我在负载ListFragment ,并且在点击,它能够深入一个水平和一个新型的ListFragment示,取代了原来的(使用showFragment下面方法)。 这是摆在回堆栈中。

一开始,该活动显示在操作栏中的默认标题(即它是基于应用程序的自动设置android:label )。

当显示列表层次结构中的一个新的水平,该项目的名称,点击应该成为操作栏的标题。

然而,当按下后退 ,我想恢复原来的默认标题。 这不是FragmentTransaction知道,所以标题是不可恢复的。

我隐约读到FragmentBreadCrumbs ,但这似乎需要使用自定义视图。 我使用ActionBarSherlock宁可没有我自己的自定义标题视图。

什么是这样做的最佳方式? 是否有可能没有样板代码的负载,并具有跟踪沿途显示的标题?


protected void showFragment(Fragment f) {
  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  ft.replace(R.id.fragment_container, f);
  ft.addToBackStack(null);
  ft.commit();
}

Answer 1:

在每一个片段和每一次活动我更改标题是这样的。 通过这种方式,积极称号永远是正确的:

@Override
public void onResume() {
    super.onResume();
    // Set title
    getActivity().getActionBar()
        .setTitle(R.string.thetitle);
}

有一些情况下的onResume没有内部片段叫。 在一些案件我们可以使用:

public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser) {
        // Set title
        getActivity().getActionBar()
            .setTitle(R.string.thetitle);
    }
}


Answer 2:

由于原来的答案是很老,这可能来帮助为好。 作为文档状态,一个可能要注册一个listener ,以监听在主机背面栈变化Activity

getSupportFragmentManager().addOnBackStackChangedListener(
        new FragmentManager.OnBackStackChangedListener() {
            public void onBackStackChanged() {
                // Update your UI here.
            }
        });

然后,找出回调方法的情况下,并设置一个适当的标题,而不用访问ActionBarFragment

这是作为一个更优雅的解决方案Fragment不必了解ActionBar的存在和Activity通常是这样的管理有它处理了,似乎是更合适的返回堆栈的地方。 Fragment应该在所有的时间只有它自己的内容,而不是周围的环境考虑。

更多关于在主题文件 。



Answer 3:

让控制活动做所有的工作如下:

倾听堆栈中的事件(在活动的onCreate()):

// Change the title back when the fragment is changed
    getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fragment = getFragment();
            setTitleFromFragment(fragment);
        }
    });

获得从容器中的当前片段:

/**
 * Returns the currently displayed fragment.
 * @return
 *      Fragment or null.
 */
private Fragment getFragment() {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container);
    return fragment;
}

设置内容视图里面的片段:

private void setFragment(Fragment fragment, boolean addToBackStack) {
    // Set the activity title
    setTitleFromFragment(fragment);
    .
    .
    .
}


Answer 4:

Warpzit是正确的。 当设备的取向发生变化这也解决了标题问题。 此外,如果您使用支持V7行动吧,你可以从这样的片段行动起来吧:

@Override
public void onResume() {
    super.onResume();
    ((ActionBarActivity)getActivity()).getSupportActionBar().setTitle("Home");
}


Answer 5:

最好是让OS做尽可能多的工作尽可能的。 假设每个片段用.addToBackStack正确命名(“标题”),那么你可以重写onBackPressed像这样以达到所需的行为:

// this example uses the AppCompat support library
// and works for dynamic fragment titles
@Override
public void onBackPressed() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    int count = fragmentManager.getBackStackEntryCount();
    if (count <= 1) {
        finish();
    }
    else {
        String title = fragmentManager.getBackStackEntryAt(count-2).getName();
        if (count == 2) {
            // here I am using a NavigationDrawer and open it when transitioning to the initial fragment
            // a second back-press will result in finish() being called above.
            mDrawerLayout.openDrawer(mNavigationDrawerFragment.getView());
        }
        super.onBackPressed();
        Log.v(TAG, "onBackPressed - title="+title);
        getSupportActionBar().setTitle(title);
    }
}


Answer 6:

使用方法片段:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)

这就是所谓的在每一个片段的外观,但的onResume不是。



Answer 7:

我使用了类似的解决方案, 李的方法 ,但用onBackStackChanged()方法来代替。

首先,我加入了交易后退堆栈时设置的片段名。

getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_content, fragment)
                .addToBackStack(fragmentTitle)
                .commit();

然后我重写onBackStackChanged()方法。我呼吁setTitle()与最后返回堆栈条目名称。

@Override
public void onBackStackChanged() {
    int lastBackStackEntryCount = getSupportFragmentManager().getBackStackEntryCount() - 1;
    FragmentManager.BackStackEntry lastBackStackEntry =
            getSupportFragmentManager().getBackStackEntryAt(lastBackStackEntryCount);

    setTitle(lastBackStackEntry.getName());
}


Answer 8:

最好的办法是使用了Android提供的接口OnBackStackChangedListener方法onBackStackChanged()。

比方说,我们与该用户可以导航到4个选项抽屉式导航。 在这种情况下,我们将有4个片段。 让我们先看看代码,然后我会解释工作。

    private int mPreviousBackStackCount = 0;
    private String[] title_name = {"Frag1","Frag2","Frag3","Frag4"};
    Stack<String> mFragPositionTitleDisplayed;

    public class MainActivity extends ActionBarActivity implements FragmentManager.OnBackStackChangedListener
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ....
    ....
    ....
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    mFragPositionTitleDisplayed = new Stack<>();
}

public void displayFragment() {
    Fragment fragment = null;
    String title = getResources().getString(R.string.app_name);
    switch (position) {
        case 0:
            fragment = new Fragment1();
            title = title_name[position];
            break;
        case 1:
            fragment = new Fragment2();
            title = title_name[position];
            break;
        case 2:
            fragment = new Fragment3();
            title = title_name[position];
            break;
        case 3:
            fragment = new Fragment4();
            title = title_name[position];
            break;
        default:
            break;
    }
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container_body, fragment)
                .addToBackStack(null)
                .commit();
        getSupportActionBar().setTitle(title);
    }
}

@Override
public void onBackStackChanged() {
    int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
    if(mPreviousBackStackCount >= backStackEntryCount) {
        mFragPositionTitleDisplayed.pop();
        if (backStackEntryCount == 0)
            getSupportActionBar().setTitle(R.string.app_name);
        else if (backStackEntryCount > 0) {
            getSupportActionBar().setTitle(mFragPositionTitleDisplayed.peek());
        }
        mPreviousBackStackCount--;
    }
    else{
        mFragPositionTitleDisplayed.push(title_name[position]);
        mPreviousBackStackCount++;
    }

}   

在所示的代码中,我们有displayFragment()方法。 在这里,我显示从drawer.The可变位置对应于所述项的位置从在导航抽屉ListView的或RecyclerView点击导航所选选项的基础上的片段。 我getSupportActionBar.setTitle(职称),其中标题存储相应的标题名称设置相应的动作条的标题。

每当我们从点击导航抽屉中的物品的片段显示的是根据单击的项目给用户。 但在后端侧该片段被添加到返回堆栈,并且所述方法onBackStachChanged(),被击中。 我所做的是,我已经创建了一个变量mPreviousBackStackCount并初始化为0。我也创建了一个额外的堆栈将存储操作栏标题名称。 每当我添加一个新片段到堆栈中,我添加相应的标题名称我创建堆栈。 在另一边时,我按onBackStackChanged后退按钮()被调用,我从栈中弹出最后的标题名称,并设置标题由堆栈的PEEK()方法得到的名称。

例:

比方说,我们的Android堆栈中为空:

按1选择从NAV抽屉:onBackStachChanged()被调用,将片段1被添加到Android堆栈中,backStackEntryCount设置为1和Frag1推到我的mFragPositionTitleDisplayed的堆栈,大小为1。

按选择2从导航抽屉:onBackStachChanged()被调用,将片段2添加到Android堆栈中,backStackEntryCount被设置为2,Frag2推到我的mFragPositionTitleDisplayed的堆栈和大小变为2。

现在我们都在Android栈和我的筹码2个元素。 当您按下后退按钮onBackStackChanged()被调用和backStackEntryCount的值是1的代码进入if部分和弹出从我的堆栈中的最后一项。 因此,Android的堆栈中只有1个片段 - “片段1”和我的筹码只有1个标题 - “Frag1”。 现在我只偷看()从我的堆栈标题,并设置操作栏这个称号。

记住:为了设置动作蝙蝠标题用PEEK(),而不是POP()否则你的应用程序会崩溃,当您打开超过2个片段,并尝试按后退按钮回去。



Answer 9:

您甘蔗解决的onkeydown! 我有一个bool mainisopen =真< - MainFragment是mainisopen可见其他片段=假

这里是我的代码:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == false) {
        mainisopen = true;
        HomeFrag fragment = new HomeFrag();
        FragmentTransaction fragmentTransaction =
                getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragmet_cont, fragment);
        fragmentTransaction.commit();
        navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.getMenu().findItem(R.id.nav_home).setChecked(true);
        navigationView.setNavigationItemSelectedListener(this);
        this.setTitle("Digi - Home"); //Here set the Title back
        return true;
    } else {
        if (keyCode == KeyEvent.KEYCODE_BACK && mainisopen == true) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Wollen sie die App schliessen!");
            builder.setCancelable(true);

            builder.setPositiveButton("Ja!", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    System.exit(1);
                }
            });

            builder.setNegativeButton("Nein!", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_SHORT).show();
                }
            });

            AlertDialog dialog = builder.create();
            dialog.show();

            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}


Answer 10:

要更新回按动作条标题。 只需简单地把

getActivity.setTitle( “标题”)

里面onCreateView方法。



文章来源: Handling ActionBar title with the fragment back stack?