工具栏(SupportActionBar)标题在方向更改时更改为应用程序名称 [英] Toolbar (SupportActionBar) title changes to app name on orientation change

查看:73
本文介绍了工具栏(SupportActionBar)标题在方向更改时更改为应用程序名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的活动中包含以下代码:

protected void onCreate(Bundle savedInstanceState) {
    ...
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
      actionBar.setDisplayHomeAsUpEnabled(true);
    }
    ...
}

我正在从onResume()中的各个片段更新ActionBar标题:

ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
    actionBar.setTitle(title);
}

这可以正常工作,但是更改方向后,标题会再次更改为应用程序名称.我该如何克服?

经过更多调查后,我尝试了一下,发现了这种奇怪的行为: 在片段中设置标题的地方添加了以下代码:

final ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
if (actionBar != null) {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.d("SWAPNIL", "IN RUN BEFORE: " + actionBar.getTitle());
            actionBar.setTitle(title);
            Log.d("SWAPNIL", "IN RUN AFTER : " + actionBar.getTitle());
        }
    }, 3000);
}

这是日志:

10-13 10:27:04.526 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: MY APP NAME
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title
10-13 10:27:21.012 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: title
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title

它已按照日志进行了更改,但未反映在UI中. 请帮帮我!

解决方案

好吧,终于,在花了两天时间处理这个愚蠢的事情之后,我得到了解决方案(我会说解决方法).

这可能是嵌套的Fragment错误.

我有嵌套的Fragment结构.众所周知,Fragment.getActivity()返回父级Activity.经过大量调试后,我观察到,如果在方向更改后(甚至在Fragment.onActivityCreated()内部)调用了getActivity(),它会返回旧Activity的引用,但最上层的父片段会正确地返回新创建的Activity./p>

因此,我编写了此方法来从任何Fragment中获取当前的Activity:

/**
 * When inside a nested fragment and Activity gets recreated due to reasons like orientation
 * change, {@link android.support.v4.app.Fragment#getActivity()} returns old Activity but the top
 * level parent fragment's {@link android.support.v4.app.Fragment#getActivity()} returns current,
 * recreated Activity. Hence use this method in nested fragments instead of
 * android.support.v4.app.Fragment#getActivity()
 *
 * @param fragment
 *  The current nested Fragment
 *
 * @return current Activity that fragment is hosted in
 */
public Activity getActivity(Fragment fragment) {
    if (fragment == null) {
        return null;
    }
    while (fragment.getParentFragment() != null) {
        fragment = fragment.getParentFragment();
    }
    return fragment.getActivity();
}

I have this code in my Activity:

protected void onCreate(Bundle savedInstanceState) {
    ...
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
      actionBar.setDisplayHomeAsUpEnabled(true);
    }
    ...
}

I'm updating the ActionBar title from various fragments like this in onResume():

ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
    actionBar.setTitle(title);
}

This is working fine, but after orientation change, the title changes to the app name again. How I can overcome this?

EDIT: After investigating more, I tried this and found this weird behaviour: Added this code where I was setting title in Fragments:

final ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
if (actionBar != null) {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.d("SWAPNIL", "IN RUN BEFORE: " + actionBar.getTitle());
            actionBar.setTitle(title);
            Log.d("SWAPNIL", "IN RUN AFTER : " + actionBar.getTitle());
        }
    }, 3000);
}

And here's the log:

10-13 10:27:04.526 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: MY APP NAME
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title
10-13 10:27:21.012 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: title
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title

It was getting changed as per logs but wasn't reflected in UI. Please help me!

解决方案

Okay, finally, after spending 2 days on this silly thing, I got the solution (I would say workaround).

This is probably a nested Fragment bug.

I have nested Fragment structure. As we know Fragment.getActivity() returns parent Activity. After lot of debugging I observed that if you call getActivity() after orientation change (even inside Fragment.onActivityCreated()) it returns reference of the old Activity except in top most parent fragment where it correctly returns the newly created Activity.

So I've written this method to get current Activity from any Fragment:

/**
 * When inside a nested fragment and Activity gets recreated due to reasons like orientation
 * change, {@link android.support.v4.app.Fragment#getActivity()} returns old Activity but the top
 * level parent fragment's {@link android.support.v4.app.Fragment#getActivity()} returns current,
 * recreated Activity. Hence use this method in nested fragments instead of
 * android.support.v4.app.Fragment#getActivity()
 *
 * @param fragment
 *  The current nested Fragment
 *
 * @return current Activity that fragment is hosted in
 */
public Activity getActivity(Fragment fragment) {
    if (fragment == null) {
        return null;
    }
    while (fragment.getParentFragment() != null) {
        fragment = fragment.getParentFragment();
    }
    return fragment.getActivity();
}

这篇关于工具栏(SupportActionBar)标题在方向更改时更改为应用程序名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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