getSupportActionBar from inside of Fragment ActionBarCompat

前端 未结 6 926
梦毁少年i
梦毁少年i 2020-12-07 11:45

I\'m starting a new project that uses the AppCompat/ActionBarCompat in v7 support library. I\'m trying to figure out how to use the getSuppor

相关标签:
6条回答
  • 2020-12-07 12:02

    After Fragment.onActivityCreated(...) you'll have a valid activity accessible through getActivity().

    You'll need to cast it to an ActionBarActivity then make the call to getSupportActionBar().

    ((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
    

    You do need the cast. It's not poor design, it's backwards compatibility.

    0 讨论(0)
  • 2020-12-07 12:03

    If someone uses com.android.support:appcompat-v7: and AppCompatActivity as activity then this will work

    ((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
    
    0 讨论(0)
  • 2020-12-07 12:07

    in your fragment.xml add Toolbar Tag from support library

     <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" />
    

    Now how we can control it from MyFragment class? let's see

    inside onCreateView function add the following

    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);
    

    and if you want to add items to the toolbar within MyFragment you must add this line inside onCreateView function

            setHasOptionsMenu(true);
    

    this line is important, if you forget it, android will not populate your menu Items.

    assume we identify them in menu/fragment_menu.xml

    after that override the following functions

    @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;
    }
    

    hope this helps

    0 讨论(0)
  • 2020-12-07 12:11

    For those using kotlin,

    (activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
    
    0 讨论(0)
  • 2020-12-07 12:17

    As an updated answer for Pierre-Antoine LaFayette's answer

    ActionBarActivity is deprecated; use AppCompatActivity instead

    ((AppCompatActivity)getActivity()).getSupportActionBar();
    
    0 讨论(0)
  • 2020-12-07 12:20

    While this question has an accepted answer already, I must point out that it isn't totally correct: calling getSupportActionBar() from Fragment.onAttach() will cause a NullPointerException when the activity is rotated.

    Short answer:

    Use ((ActionBarActivity)getActivity()).getSupportActionBar() in onActivityCreated() (or any point afterwards in its lifecycle) instead of onAttach().

    Long answer:

    The reason is that if an ActionBarActivity is recreated after a rotation, it will restore all Fragments before actually creating the ActionBar object.

    Source code for ActionBarActivity in the support-v7 library:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mImpl = ActionBarActivityDelegate.createDelegate(this);
        super.onCreate(savedInstanceState);
        mImpl.onCreate(savedInstanceState);
    }
    
    • ActionBarActivityDelegate.createDelegate() creates the mImpl object depending on the Android version.
    • super.onCreate() is FragmentActivity.onCreate(), which restores any previous fragments after a rotation (FragmentManagerImpl.dispatchCreate(), &c).
    • mImpl.onCreate(savedInstanceState) is ActionBarActivityDelegate.onCreate(), which reads the mHasActionBar variable from the window style.
    • Before mHasActionBar is true, getSupportActionBar() will always return null.

    Source for 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;
    }
    
    0 讨论(0)
提交回复
热议问题