115

サポート ライブラリを使用AppCompat/ActionBarCompatする新しいプロジェクトを開始しています。フラグメント内で fromv7を使用する方法を理解しようとしています。getSupportActionBarフラグメントをホストするアクティビティは extendsActionBarActivityですが、フラグメントの同様のサポート クラスは見当たりません。

私の断片の中から

    public class CrimeFragment extends Fragment {
          //...

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

          //...
    }

それを使用するためのGoogleページ(http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.htmlv4 )は、フラグメントに変更を加えるべきではないと述べています。getActivity()すべての呼び出しをにキャストする必要がありActionBarActivityますか? それは設計が悪いようです。

4

7 に答える 7

38

この質問にはすでに受け入れられた回答がありますが、完全に正しいわけではないことを指摘しなければなりません。getSupportActionBar()fromを呼び出すと、アクティビティがローテーションされるときにFragment.onAttach()a が発生します。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()これは、ローテーション ( 、&c)FragmentActivity.onCreate()の後に以前のフラグメントを復元します。FragmentManagerImpl.dispatchCreate()
  • mImpl.onCreate(savedInstanceState)isで、ウィンドウ スタイルから変数ActionBarActivityDelegate.onCreate()を読み取ります。mHasActionBar
  • beforemHasActionBarは 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;
}
于 2014-06-10T23:21:24.483 に答える
6

Pierre-Antoine LaFayetteの回答に対する更新された回答として

ActionBarActivity は非推奨です。AppCompatActivity代わりに使用

((AppCompatActivity)getActivity()).getSupportActionBar();
于 2017-04-01T13:59:44.263 に答える
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;
}

お役に立てれば

于 2016-03-26T18:51:29.517 に答える