Fragment ActionBarCompat 내부의 getSupportActionBar


102

나는를 사용하는 새로운 프로젝트를 시작 해요 AppCompat/ActionBarCompat에서 v7지원 라이브러리를. getSupportActionBar조각 내에서 를 사용하는 방법을 알아 내려고 노력 중 입니다. 조각을 호스팅하는 내 활동은 확장 ActionBarActivity되지만 조각에 대한 유사한 지원 클래스가 표시되지 않습니다.

내 조각 내에서

    public class CrimeFragment extends Fragment {
          //...

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

          //...
    }

그것을 사용하기위한 구글 페이지 ( http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html )는 v4조각에 대한 변경이 없어야한다고 말합니다 . 내 모든 getActivity()통화를 에 캐스팅해야 ActionBarActivity합니까? 디자인이 좋지 않은 것 같습니다.

답변:


287

Fragment.onActivityCreated (...) 당신이 getActivity를 통해 액세스 할 수있는 유효한 활동을해야합니다 ().

이를 ActionBarActivity로 캐스트 한 다음 getSupportActionBar ()를 호출해야합니다.

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

캐스트가 필요합니다. 열악한 디자인이 아니라 이전 버전과의 호환성입니다.


3
감사. 나는 이것이 답이 아니길 바랬다. getActionBar ()가 추가 기능이 필요한 경우 캐스팅 할 v7 ActionBar를 반환하기를 바랐습니다. 이제 내 Fragments가 호스팅되는 활동 유형을 알아야합니다.
Paul

아니요, getActionBar ()가 이전 버전의 SDK (벌집 이전)에 존재하지 않는 활동 API이기 때문이 아닙니다. 그렇기 때문에 최신 SDK에서 새롭게 개선 된 클래스 및 API의 기능을 미러링하는 지원 클래스가 필요합니다.
Pierre-Antoine LaFayette

@ Pierre-AntoineLaFayette 왜 이것이 onAttach ()에서 이루어져야합니까? onActivityCreated ()에서 더 좋지 않을까요?
IgorGanapolsky 2014

예, getSupportActionBar ()에 대한 첫 번째 호출은 활동에서 뷰를 조회하여 ActionBar를 초기화하므로 onActivityCreated ()에서이 호출을 수행하는 것이 더 좋습니다. 나는 조각이 활동을 할 때까지 기다려야 함을 나타내려고 더 노력했습니다. 답변을 업데이트하겠습니다.
Pierre-Antoine LaFayette 2014

2
대신 ActionBarActivity의 사용 AppCompatActivity
Aparajita 신하

37

이 질문은 이미 허용 답을 가지고 있지만, 나는 그것이 완전히 정확하지 않은 점을 지적해야 호출 getSupportActionBar()에서하는 Fragment.onAttach()원인이됩니다 NullPointerException활동이 회전 할 때.

짧은 답변:

대신 ((ActionBarActivity)getActivity()).getSupportActionBar()in onActivityCreated()(또는 수명주기 이후의 모든 지점)을 사용하십시오 onAttach().

긴 대답 :

그 이유는 ActionBarActivity회전 후를 다시 만들면 실제로 개체를 만들기 전에 모든 조각을 복원 하기 때문입니다 ActionBar.

소스 코드 ActionBarActivity에서 support-v7라이브러리 :

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
  • ActionBarActivityDelegate.createDelegate()mImplAndroid 버전에 따라 객체를 생성합니다 .
  • super.onCreate()is FragmentActivity.onCreate(), 회전 후 이전 조각을 복원합니다 ( FragmentManagerImpl.dispatchCreate(), & c).
  • mImpl.onCreate(savedInstanceState)is ActionBarActivityDelegate.onCreate(), mHasActionBar창 스타일에서 변수 를 읽습니다 .
  • Before mHasActionBar가 true이면 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;
}

2
ActionBarActivity더 이상 사용되지 않습니다. 사용 AppCompatActivity대신에
삼안 Sattari에게

29

누군가 com.android.support:appcompat-v7 : 및 AppCompatActivity를 활동으로 사용하면 작동합니다.

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

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

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

items툴바 에 추가 하려면 함수 안에이 줄 MyFragmentmust추가하세요.onCreateView

        setHasOptionsMenu(true);

이 줄은 중요합니다. 잊어 버린 경우 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;
}

도움이 되었기를 바랍니다


5

Pierre-Antoine LaFayette의 답변에 대한 업데이트 된 답변으로

ActionBarActivity는 더 이상 사용되지 않습니다. 사용하는 AppCompatActivity대신

((AppCompatActivity)getActivity()).getSupportActionBar();

3

kotlin을 사용하는 사람들을 위해

(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.