54

私は最近、Fragmentsを作成するときに、Bundlesに引数を渡すために常にStringのキーを知ることに疲れてしまいました。そこで私はFragmentsのコンストラクタを作って、設定したいパラメータをとり、正しいStringキーを使ってBundlesに入れました。そのため、これらのキーを知る必要があるFragmentsActivitiesの必要性が排除されました。フラグメントを作成する:コンストラクタとnewInstance()

public ImageRotatorFragment() { 
    super(); 
    Log.v(TAG, "ImageRotatorFragment()"); 
} 

public ImageRotatorFragment(int imageResourceId) { 
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)"); 

    // Get arguments passed in, if any 
    Bundle args = getArguments(); 
    if (args == null) { 
     args = new Bundle(); 
    } 
    // Add parameters to the argument bundle 
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId); 
    setArguments(args); 
} 

そして、私はこれらの引数を普通のように引き出します。

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.v(TAG, "onCreate"); 

    // Set incoming parameters 
    Bundle args = getArguments(); 
    if (args != null) { 
     mImageResourceId = args.getInt(KEY_ARG_IMAGE_RES_ID, StaticData.getImageIds()[0]); 
    } 
    else { 
     // Default image resource to the first image 
     mImageResourceId = StaticData.getImageIds()[0]; 
    } 
} 

しかし、リントも、アプリケーションを実行するために@SuppressLint("ValidFragment")を使用するために私を必要とし、他のパラメータを持つコンストラクタを持つFragmentのサブクラスを持っていないと言って、これで問題を取りました。問題は、このコードは完璧に機能していることです。 ImageRotatorFragment(int imageResourceId)または古い学校の方法ImageRotatorFragment()を使用して、setArguments()を手作業で呼び出すことができます。 AndroidがFragment(オリエンテーションの変更またはメモリ不足)を再作成する必要があるときは、ImageRotatorFragment()コンストラクタを呼び出し、同じ値のBundleを渡して正しく設定されます。

私は "提案された"アプローチを探していて、newInstance()を使って多くの例を見て、Fragmentsというパラメータを作成しました。これは私のコンストラクタと同じことをしています。だから、私はそれをテストするために自分自身を作った、そしてそれは前と同じように完璧に動作し、Lintはそれについて泣いている。

public static ImageRotatorFragment newInstance(int imageResourceId) { 
    Log.v(TAG, "newInstance(int imageResourceId)"); 

    ImageRotatorFragment imageRotatorFragment = new ImageRotatorFragment(); 

    // Get arguments passed in, if any 
    Bundle args = imageRotatorFragment.getArguments(); 
    if (args == null) { 
     args = new Bundle(); 
    } 
    // Add parameters to the argument bundle 
    args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId); 
    imageRotatorFragment.setArguments(args); 

    return imageRotatorFragment; 
} 

私は個人的にコンストラクタを使用してnewInstance()を使用するために知っているとパラメータを渡すよりもはるかに一般的に行われていることがわかります。私はあなたがアクティビティでこの同じコンストラクタテクニックを使用することができると信じており、Lintはそれについて不平を言うことはありません。 基本的に私の質問は、なぜGoogleはFragmentsのパラメータを持つコンストラクタを使用したくないのですか?

Fragmentが再作成されたときに設定されない、Bundleを使用せずにインスタンス変数を設定しようとしないようにしてください。 static newInstance()メソッドを使用すると、コンパイラはインスタンス変数にアクセスすることを許可しません。

public ImageRotatorFragment(int imageResourceId) { 
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)"); 

    mImageResourceId = imageResourceId; 
} 

コンストラクタでパラメータの使用を許可しない理由はまだありません。誰もがこれについての洞察を持っていますか?

答えて

59

個人的には、newInstance()とパラメータを渡すことを知っているよりも、コンストラクタを使用するほうがずっと一般的です。

factory method patternは、現代のソフトウェア開発でかなり頻繁に使用されます。

基本的に私の質問は、GoogleがあなたにFragmentsのパラメータを持つコンストラクタを使用したくないということです。あなたはあなた自身の質問答え

を私の唯一の推測では、あなたは、フラグメントが再作成されます時に設定され得ることはありませんこれは、バンドルを使用せずにインスタンス変数を設定しようとしないんです。

正しい。

コンストラクタでパラメータを使用できない理由はまだありません。

あなたの意見は大歓迎です。このLintチェックは、コンストラクタごとまたはワークスペースごとに無効にできます。

0

Androidはデフォルトのコンストラクタを使用して強制終了するフラグメントのみを再作成するため、追加のコンストラクタで行う初期化は失われます.Henceデータは失われます。

関連する問題