来自Fragment ActionBarCompat内部的getSupportActionBar

Pau*_*aul 94 android android-fragments android-support-library android-actionbar-compat

我正在开始一个使用AppCompat/ActionBarCompatin v7支持库的新项目.我试图找出如何getSupportActionBar在片段中使用from.我承载片段的活动扩展了ActionBarActivity,但我没有看到片段的类似支持类.

从我的片段中

    public class CrimeFragment extends Fragment {
          //...

          getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment

          //...
    }
Run Code Online (Sandbox Code Playgroud)

使用它的谷歌页面(http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html)表示v4片段应该没有变化.我是否需要将所有getActivity()电话投入ActionBarActivity?这似乎是糟糕的设计.

Pie*_*tte 269

Fragment.onActivityCreated(...)之后,您将通过getActivity()访问有效活动.

您需要将其强制转换为ActionBarActivity,然后调用getSupportActionBar().

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
Run Code Online (Sandbox Code Playgroud)

你确实需要演员.它的设计并不差,它具有向后兼容性.

  • 谢谢.我希望这不是答案.我希望也许getActionBar()会返回一个v7 ActionBar,如果我需要额外的功能,我会转发它.现在我的片段必须知道它们所托管的活动类型. (3认同)
  • 使用AppCompatActivity而不是ActionBarActivity (2认同)

mat*_*ash 35

虽然这个问题已经有了一个公认的答案,但我必须指出它并不完全正确:调用getSupportActionBar()from Fragment.onAttach()会导致NullPointerException活动被轮换.

简短回答:

使用((ActionBarActivity)getActivity()).getSupportActionBar()onActivityCreated()(或任何在它的生命周期之后点)代替onAttach().

答案很长:

原因是如果ActionBarActivity在旋转后重新创建一个,它将实际创建ActionBar对象之前恢复所有片段.

ActionBarActivity中的源代码support-v7:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
Run Code Online (Sandbox Code Playgroud)
  • ActionBarActivityDelegate.createDelegate()mImpl根据Android版本创建对象.
  • super.onCreate()FragmentActivity.onCreate(),在旋转后恢复任何先前的片段(FragmentManagerImpl.dispatchCreate(),&c).
  • mImpl.onCreate(savedInstanceState)ActionBarActivityDelegate.onCreate(),mHasActionBar从窗口样式中读取变量.
  • 以前mHasActionBar是真的,getSupportActionBar()总会回来null.

来源ActionBarActivityDelegate.getSupportActionBar():

final ActionBar getSupportActionBar() {
    // The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
    // could change after onCreate
    if (mHasActionBar || mOverlayActionBar) {
        if (mActionBar == null) {
            ... creates the action bar ...
        }
    } else {
        // If we're not set to have a Action Bar, null it just in case it's been set
        mActionBar = null;
    }
    return mActionBar;
}
Run Code Online (Sandbox Code Playgroud)

  • `ActionBarActivity` 已弃用。改用`AppCompatActivity` (2认同)

Ami*_*mir 29

如果有人使用com.android.support:appcompat-v7:和AppCompatActivity作为活动,那么这将有效

((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
Run Code Online (Sandbox Code Playgroud)


小智 7

对于那些使用 kotlin 的人,

(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
Run Code Online (Sandbox Code Playgroud)


Das*_*uni 6

作为 Pierre-Antoine LaFayette 答案的更新答案

ActionBarActivity 已弃用;使用AppCompatActivity替代

((AppCompatActivity)getActivity()).getSupportActionBar();
Run Code Online (Sandbox Code Playgroud)


Bas*_*ANI 5

在支持库的fragment.xml添加Toolbar标签中

 <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
Run Code Online (Sandbox Code Playgroud)

现在我们如何从MyFragment课堂上控制它?让我们来看看

内部onCreateView函数添加以下内容

mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);

//add this line if you want to provide Up Navigation but don't forget to to 
//identify parent activity in manifest file
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Run Code Online (Sandbox Code Playgroud)

如果要添加items到工具栏中,MyFragmentmustonCreateView函数内添加此行

        setHasOptionsMenu(true);
Run Code Online (Sandbox Code Playgroud)

这行很重要,如果您忘记了它,android将不会填充菜单项。

假设我们在 menu/fragment_menu.xml

之后,覆盖以下功能

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_menu, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    switch (id) {
        case R.id.action_1:
            // do stuff
            return true;

        case R.id.action_2:
            // do more stuff
            return true;
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助