Android 碎片更改标题

16
我有一个与我的片段相关的问题。基本上,我有一个应用程序,其中有一个导航抽屉和4个按钮在活动上。当按下每个按钮时,它将显示另一个片段。我遇到的问题是,我想在 ActionBar 上显示正确的标题。我可以在 ActionBar 上显示从导航中选择的项目。但是当我按下按钮去另一个片段时,我无法在 ActionBar 上显示标题。有什么想法吗?
这是我的示例代码: HomeActivity.class
 private void displayView(final int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new HomeFragment();
            break;
        case 1:
            fragment = new MyProfileFragment();
            break;
        case 2:
            fragment = new AboutFragment();
            break;
        default:
            break;
    }

    if (fragment != null) {
        fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        drawer.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }

}

主页碎片:

public class HomeFragment extends Fragment {

public HomeFragment() {
}

CardView card_cart, card_scan, card_categories, card_about;
Intent i;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    initControls(rootView);
    return rootView;
}

private void initControls(View rootView) {

    card_cart = (CardView) rootView.findViewById(R.id.card_cart);
    card_scan = (CardView) rootView.findViewById(R.id.card_scan);
    card_categories = (CardView) rootView.findViewById(R.id.card_categories);
    card_about = (CardView) rootView.findViewById(R.id.card_about);

    card_categories.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            i = new Intent(getActivity(), CategoriesActivity.class);
            startActivity(i);
        }
    });

    card_cart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MyCartFragment nextFrag = new MyCartFragment();
            getFragmentManager().beginTransaction()
                    .replace(R.id.frame_container, nextFrag)
                    .addToBackStack(null)
                    .commit();
        }
    });

    card_about.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AboutGrabHutFragment aboutFrag = new AboutGrabHutFragment();
            getFragmentManager().beginTransaction()
                    .setBreadCrumbTitle(getResources().getString(R.string.about))
                    .replace(R.id.frame_container, aboutFrag)
                    .addToBackStack(null)
                    .commit();


        }
    });

    card_scan.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            i = new Intent(getActivity(), ScanActivity.class);
            startActivity(i);
        }
    });

}

HomeFragment 中会找到这4个按钮。当点击一个按钮时,会跳转到另一个片段。可以使用以下代码来显示:

HomeFragment中将找到那4个按钮。当点击按钮时,将跳转到另一个片段。我可以使用以下方法显示:

card_about.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AboutGrabHutFragment aboutFrag = new AboutGrabHutFragment();
            getFragmentManager().beginTransaction()
                    .setBreadCrumbTitle(getResources().getString(R.string.about))
                    .replace(R.id.frame_container, aboutFrag)
                    .addToBackStack(null)
                    .commit();
            getActivity().setTitle("About");

        }
    });

但问题是,当我返回时,标题仍然是About


1
请查看此链接 https://dev59.com/QWUp5IYBdhLWcg3wCUKx#46705242 - Ahmad Aghazadeh
对于任何使用导航抽屉的人,你的答案可能是更新你的目标标签,请参考此问题 - lasec0203
这篇文章中还有另一个答案。它是更新的,最近实现了MVVM模式的新想法。请查看此链接:https://dev59.com/QWUp5IYBdhLWcg3wCUKx#18011671 - Dimitri Leite
4个回答

21

在所需碎片的onCreateView()方法中,调用您的主Activity的setTitle("")方法。这样,您甚至都不需要检查后退按下事件。

这对我有用

例如***

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.id.your_fragment_layout, container,
                false);
        getActivity().setTitle("Your actionbar title");

        return rootView;
    }

更新:

你可以通过覆盖 onResume 方法来更改标题。为了安全起见,你还可以覆盖 setUserVisibleHint 方法,在片段 isVisibleToUser 时更改标题。


4
如果将片段添加到返回堆栈中,这个解决方案就不起作用了。 - Amir

8

如果有人使用 Kotlin,而 @Sachin Rao 的回答无法解决问题(就像我的情况一样),我已经编写了扩展函数来更改标题:

fun Fragment.setActivityTitle(@StringRes id: Int) {
    (activity as? AppCompatActivity)?.supportActionBar?.title = getString(id)
}

fun Fragment.setActivityTitle(title: String) {
    (activity as? AppCompatActivity)?.supportActionBar?.title = title
}

使用方法(在片段的任何位置):

setActivityTitle(R.string.title)
setActivityTitle("Title")

1
代码可以优化为:(activity as? AppCompatActivity)?.supportActionBar?.title = title这样,如果活动未实现AppCompatActivity,应用程序就不会崩溃。 - BladeCoder

3
我在MainActivity中使用了onBackStackChangedListener,并将其用于在应用程序中导航时更新各种内容。您已经手动更改了标题,因此可以尝试以下代码:
//manager is my FragmentManager
manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            //I'm using this check to check if i'm on my MainFragment, you can use this in al kinds of ways. Decide yourself if you use it or not.
            if (manager.getBackStackEntryCount() == 1) {
                Class<? extends Fragment> FragClass;
                //mCurrentFragment is my global Fragment variable to do and check stuff with as below.
                FragClass = mCurrentFragment.getClass();
                if ((FragClass == DesiredFragment.class)) {
                    this.setTitle("desired title");
                } else if ((FragClass == OtherDesiredFragment.class)) {
                    //hope this helps.
                } //etc..
            }
        }
    });
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
    try {
        Class<? extends Fragment> FragClass;
        FragClass = mCurrentFragment.getClass();
        if ((FragClass == HomeFragment.class)) {
            System.exit(0);
        }
            popFragment();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

public void popFragment() {
    try {
        if (manager.getBackStackEntryCount() > 1) {
            manager.popBackStack();
            manager.executePendingTransactions();
            ArrayList<Fragment> reversedFragments = new ArrayList<Fragment>(manager.getFragments());
            Collections.reverse(reversedFragments);
            for (Fragment fragment : reversedFragments) {
                if (fragment != null) {
                    try {
                        mCurrentFragment = (BaseFragment) fragment;
                    } catch (ClassCastException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        } else {
            finish();
        }
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

尝试过这样做,但当我回来时,标题没有改变。 - user1410081
1
你是否有 @Override OnBackPressed 函数,并且在按下返回键时处理后退堆栈? - Jordi Sipkens
1
请查看更新后的答案,它可以在按下返回按钮时控制后退栈。BaseFragment是我为我的Fragments创建的自定义类,所以在您的情况下可能是Fragment。 - Jordi Sipkens
@bEtTy Barnes,这个有帮到你吗?或者你找到了其他的解决方案? - Jordi Sipkens

1

对我来说,所有的答案都没用,有效的方法是在mobile_navigation.xml(导航XML文件)中设置标签。

    android:label="@string/title_library"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接