web-dev-qa-db-ja.com

Androidの新しいナビゲーションコンポーネントで文字列または整数以外の引数を送信することは可能ですか

新しいナビゲーションコンポーネントはすばらしいです。ただし、フラグメント間で「長い」変数を送信したいと思います。

これをナビゲーショングラフファイルに書き込むと機能します。

<argument
        Android:name="discussionId"
        app:type="string" />

これを書いてもコンパイルされません:

<argument
        Android:name="discussionId"
        app:type="long" />

現在、私はそれらを文字列形式との間で解析することを余儀なくされているようです。正常に動作しますが、そのような基本的なアーキテクチャーには、long、byte、shortなどのプリミティブ型を使用できないのは奇妙に思えます。何か不足していますか?このような機能セットは将来開発される予定ですか?

9

現時点では、できないintegerstringinferredおよびreference。他のタイプを要求する issue が開かれました。

しかし、navigate()メソッドを使用して宛先に移動するときに、プログラムでbundleを渡します。

var bundle = bundleOf("key" to amount)
view.findNavController().navigate(R.id.action_id, bundle)

そして、通常のgetArgumentsを使用して、宛先フラグメントのデータを取得できます。

val value = arguments.getString("key")
5
Levi Moreira

バージョン1.0.0-alpha08以降、さまざまなタイプを使用できるため、リストを見つけました here

"integer" -> IntType
"integer[]" -> IntArrayType
"long" -> LongType
"long[]" -> LongArrayType
"float" -> FloatType
"float[]" -> FloatArrayType
"boolean" -> BoolType
"boolean[]" -> BoolArrayType
"reference" -> ReferenceType
"reference[]" -> ReferenceArrayType
"string" -> StringType
"string[]" -> StringArrayType
null -> StringType

ナビゲーショングラフで使用(例:文字列のリスト)

<argument
    Android:name="photo_url"
    app:argType="string[]"
/>
8
Guillaume

プリミティブラッパーを使用してください!どうしたの?

<argument
    Android:name="discussionId"
    app:argType="Java.lang.Long" />

// Java.lang.Double, Java.lang.Float, etc...

すべてのプリミティブラッパーがSerializableを実装しているため、kotlinや安全な引数でさえチャームのように機能します

0
GV_FiQst

デフォルト値を0ではなく0Lに設定し、タイプを「推論」に設定するだけです

0
AfzalivE

これは遅くなる可能性があり、少し異なる方法で問題を解決しますが、ナビゲーション中に引数を送信し、タイプセーフな方法で名目上の大きさに送信する方法に対する質問の要求を感じるため、ここに配置します。

私の友人が問題の1つであること architecture components viewmodel は非常に効率的な方法で解決します。- docs のとおり、「フラグメント間でデータを共有する」セクションでは、使用される技術。基本的に、それは、代わりに、フラグメントにナビゲートされた2つ(またはそれ以上)を囲むフラグメント/アクティビティのスコープにアタッチされるviewmodelインスタンスの作成に関するものです。そうすることで、ナビゲートされたフラグメントのライフサイクル全体を通して存続します。

以下は、本番環境にあるアプリケーションの1つから実際に抽出した小さな例です。

-MainActivity |-NavHostFragment | |-FormFragment(Start destination) | |-ResultFragment( navigated to fragment) | |およびSharedViewModelを使用して、宛先フラグメント間でデータを転送します。

ViewModelCode

public class SharedViewModel extends ViewModel implements ResultFragment.ResultFragmentViewModel, FormFragment.FormFragmentViewModel {
public String name;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}   }

formFragment。

    @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sharedViewModel = ((FormFragmentViewModel) ViewModelProviders.of(this.getActivity()).get(SharedViewModel.class));
}

public void onFabPressed( View view) {
    String text = editText.getText().toString().trim();
    if(text.matches("")) return ;
    sharedViewModel.setName(text);
    Navigation.findNavController(view).navigate(R.id.action_formFragment_to_resultFragment);

}

public interface FormFragmentViewModel {
    public void setName(String string);
}

resultFragmentで、

    @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sharedViewModel = ((ResultFragmentViewModel) ViewModelProviders.of(this.getActivity()).get(SharedViewModel.class));
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_result, container, false);
    FloatingActionButton fab = view.findViewById(R.id.fab);
    ((TextView) view.findViewById(R.id.textview))
        .setText(sharedViewModel.getName());
    fab.setOnClickListener(
            Navigation.createNavigateOnClickListener(R.id.action_global_formFragment)
    );
    return view;
}


public interface ResultFragmentViewModel {
    public String getName();
}

上記のコードでは、両方のフラグメント(FormFragment、ResultFragment)のライフサイクルよりもライフサイクルが長くなるため、囲みアクティビティである両方のフラグメントのViewModelProviders.of()メソッドに送信されるスコープを重要視する必要があります。宛先フラグメントに移動する前に、宛先フラグメントに送信するデータをビューモデルに保存します。宛先フラグメントでビューモデルの同じインスタンスからデータを1回取得することになります。インターフェイスは、Android studio、開発者の観点から)それが使用されているフラグメントにそれぞれ対応するビューモデルから不要なメソッドを抽象化してインテリセンスに使用されます。このセットアップでは、アクションでも delegate pattern のようなものを使用して宛先フラグメントに送信されます。宛先モデルに移動する前にビューモデルの宛先フラグメントで1回アクションを実行するようにオブジェクトを設定し、その間にオブジェクトを取得してデリゲートします。この設定に追加したいのは、intのString name変数を混乱させるのはほぼ不可能です。

お役に立てれば。

0