174

私はアプリを作成してFragmentsいますが、そのうちの1つで、デフォルト以外のコンストラクターを作成し、次の警告が表示されました。

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

なぜこれが良い考えではないのか誰かに教えてもらえますか?

また、私がこれをどのように達成するかを提案できますか?

public static class MenuFragment extends ListFragment {
    public ListView listView1;
    Categories category;

    //this is my "non-default" constructor
    public MenuFragment(Categories category){
        this.category = category;
    }....

デフォルト以外のコンストラクターを使用せずに?

4

6 に答える 6

278

「デフォルト以外のコンストラクターではなく、パラメーターを渡すためにバンドルを使用する理由」に実際に答える答えはないようです。

バンドルを介してパラメータを渡す必要がある理由は、システムがを復元するときにfragment(たとえば、構成の変更時に)、自動的にを復元するためbundleです。

のようなコールバック、onCreateまたはonCreateViewパラメータを読み取る必要があります-このようにして、初期化されたのと同じ状態に正しくbundle状態を復元することが保証されます(この状態はに渡される状態とは異なる場合があることに注意してください)fragmentfragmentonSaveInstanceState bundleonCreate/onCreateView

静的newInstance()メソッドを使用することの推奨は、単なる推奨です。bundleデフォルト以外のコンストラクターを使用できますが、そのコンストラクターの本体の内部に初期化パラメーターを設定するようにしてください。そして、onCreate()またはonCreateView()メソッドでそれらのパラメーターを読み取ります。

于 2013-04-16T16:53:58.417 に答える
112

バンドルオブジェクトを作成し、データ(この例ではCategoryオブジェクト)を挿入します。シリアル化可能でない限り、このオブジェクトをバンドルに直接渡すことはできないことに注意してください。オブジェクトをフラグメントにビルドし、IDまたはその他のものだけをバンドルに入れる方が良いと思います。バンドルを作成して添付するためのコードは次のとおりです。

Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);

その後、フラグメントアクセスデータで:

Type value = getArguments().getType("key");

それで全部です。

于 2012-08-21T22:08:50.620 に答える
52

インスタンス化Fragmentの方法のために、コンストラクターを使用しないでください。FragmentManager必要newInstance()なパラメーターを使用して静的メソッドを定義し、それらをバンドルしてフラグメントの引数として設定する必要があります。これは、後でBundleパラメーターを使用してアクセスできます。

例えば:

public static MyFragment newInstance(int title, String message) {
    MyFragment fragment = new MyFragment();
    Bundle bundle = new Bundle(2);
    bundle.putInt(EXTRA_TITLE, title);
    bundle.putString(EXTRA_MESSAGE, message);
    fragment.setArguments(bundle);
    return fragment ;
}

そして、これらの議論を読んでくださいonCreate

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    title = getArguments().getInt(EXTRA_TITLE);
    message = getArguments().getString(EXTRA_MESSAGE);

    //...
}

このように、デタッチして再アタッチした場合、オブジェクトの状態は、 sbundlesにアタッチされているのと同じように、引数を介して格納できますIntent

于 2013-03-25T09:58:20.000 に答える
9

一部のクラスにパラメータを使用する場合。これを試して

SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
    MyFragment f = new MyFragment();
    f.mSomeInstance = someInstance;
    return f;
}
于 2015-01-16T05:07:59.910 に答える
1

静的コンストラクターと2つのコンストラクター(引数をフラグメントの引数バンドルに格納する空のパラメーター化されたコンストラクター)に違いはないと思います。おそらく、この経験則は、Javaで引数なしのコンストラクターを実装するのを忘れる可能性を減らすために作成されています。 、過負荷が存在する場合は暗黙的に生成されません。

私のプロジェクトでは、Kotlinを使用し、引数のプライマリno-argコンストラクターとセカンダリコンストラクターを使用してフラグメントを実装します。これらはバンドルに格納され、Fragment引数として設定されます。すべてが正常に機能します。

于 2017-07-26T11:07:01.087 に答える
0

構成を変更した後にフラグメントがデフォルト以外のコンストラクターを使用すると、フラグメントはすべてのデータを失います。

于 2020-03-15T21:02:38.637 に答える