第一个片段崩溃时的 getActivity().getActionBar()

Posted

技术标签:

【中文标题】第一个片段崩溃时的 getActivity().getActionBar()【英文标题】:getActivity().getActionBar() on first fragment crash 【发布时间】:2015-08-29 20:00:00 【问题描述】:
public class MainActivity extends ActionBarActivity 

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

    

    private void setupViewPager() 
        // TODO Auto-generated method stub
        FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
                getSupportFragmentManager(), FragmentPagerItems.with(this)
                        .add("Home", HomeFragment.class)
                        .add("Message", MessageFragment.class)
                        .add("My", MyFragment.class).create());

        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(adapter);
        SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab);
        final LayoutInflater inflater = LayoutInflater.from(viewPagerTab.getContext());
        final Resources res = viewPagerTab.getContext().getResources();
        viewPagerTab.setCustomTabView(new SmartTabLayout.TabProvider() 
            @Override
            public View createTabView(ViewGroup container, int position,PagerAdapter adapter) 
                ImageView icon = (ImageView) inflater.inflate(R.layout.mainactivity_tab, container, false);
                switch (position) 
                case 0:
                    icon.setImageDrawable(res.getDrawable(R.drawable.mainactivity_tab_icon_home));
                    break;
                case 1:
                    icon.setImageDrawable(res.getDrawable(R.drawable.mainactivity_tab_icon_message));
                    break;
                case 2:
                    icon.setImageDrawable(res.getDrawable(R.drawable.mainactivity_tab_icon_my));
                    break;
                default:
                    throw new IllegalStateException("Invalid position: "+ position);
                
                return icon;
            
        );
        viewPagerTab.setViewPager(viewPager);

    

这是那三个片段中的代码

public class HomeFragment extends Fragment 
    View rootView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        rootView = inflater.inflate(R.layout.fragment_home, container, false);

        TextView title = (TextView) rootView.findViewById(R.id.item_title);
        title.setText("Home");

        return rootView;
    

    @Override
    public void setMenuVisibility(final boolean visible) 
        super.setMenuVisibility(visible);
        if (visible) 
            Log.d("Action bar", "Home");

            ActionBar mActionBar= getActivity().getActionBar();
            mActionBar.setDisplayShowHomeEnabled(true);
            mActionBar.setDisplayShowTitleEnabled(false);

            LayoutInflater mInflater = LayoutInflater.from(getActivity());
            View mCustomView = mInflater.inflate(R.layout.actionbar_message, null);
            mActionBar.setCustomView(mCustomView);
            mActionBar.setDisplayShowCustomEnabled(true);
            TextView title = (TextView) mCustomView.findViewById(R.id.actionbar_message_title);

            title.setText("Home action bar");
        
    

它们适用于 MessageFragment.class 和 MyFragment,但不适用于 HomeFragment。 它将崩溃,ActionBar mActionBar = getActivity().getActionBar(); 将返回 null 并崩溃。

为什么它只适用于 MessageFragment 和 MyFragment?

HomeFragment 是要显示的第一个片段。

我的想法:我会在不同的片段上使用不同的自定义操作栏。

【问题讨论】:

你在哪里打电话setMenuVisibility @Simas 我没有调用 setMenuVisibility 【参考方案1】:

替换这一行

ActionBar mActionBar = getActivity().getActionBar();

通过这个

ActionBar mActionBar=((ActionBarActivity) getActivity()).getSupportActionBar();

因为你扩展了ActionBarActivity

【讨论】:

不行不行,是的,我的MainActivity是扩展的ActionBarActivity,但是那个代码在片段中 @BenLuk 如果你扩展 Activity 而不是 ActionBarActivity 有什么问题吗? @IITAmiya 我在 ActionBarActivity 中使用 getSupportFragmentManager() @Praveen android.support.v7.app.ActionBarActivity.getSupportActionBar()' 在空对象引用上【参考方案2】:

问题是当调用setMenuVisibility 时,您的片段没有附加到活动。因此getActivity 返回null

我不明白你为什么要首先搞乱这个方法。您只需修改onCreateView 中的操作栏即可:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    rootView = inflater.inflate(R.layout.fragment_home, container, false);

    
        TextView title = (TextView) rootView.findViewById(R.id.item_title);
        title.setText("Home");
    

    ActionBar mActionBar= getActivity().getActionBar();
    mActionBar.setDisplayShowHomeEnabled(true);
    mActionBar.setDisplayShowTitleEnabled(false);

    LayoutInflater mInflater = LayoutInflater.from(getActivity());
    View mCustomView = mInflater.inflate(R.layout.actionbar_message, null);
    mActionBar.setCustomView(mCustomView);
    mActionBar.setDisplayShowCustomEnabled(true);
    TextView title = (TextView) mCustomView.findViewById(R.id.actionbar_message_title);

    title.setText("Message action bar");

    return rootView;


如果确实需要使用那个方法,那么你可以尝试一个简单的空检查:

if (visible && getActivity() != null) 

【讨论】:

我使用 setMenuVisibility 是为了确保片段被关注。当我关注第二个片段时,onCreateView 将预加载。 if (visible && getActivity() != null) 是一种解决方案,但操作栏不会在第一时间显示 @BenLuk 我认为你应该重新考虑你的设计。例如。让活动在显示/隐藏不同片段时修改操作栏。【参考方案3】:

我的解决方案,将我的代码放入 setUserVisibleHint

@Override
public void setUserVisibleHint(boolean isVisibleToUser) 
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) 

    

【讨论】:

以上是关于第一个片段崩溃时的 getActivity().getActionBar()的主要内容,如果未能解决你的问题,请参考以下文章

方向更改后片段中的 getActivity() 为空

getActivity() 在片段上返回 null?

在片段中显示 DatePickerDialog

Android getActivity() 总是在片段内返回 null

片段 getActivity() 与接口回调?

getActivity() 在片段的 AlertDialog 中为 null