18

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

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

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

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

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

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

4

5 に答える 5

18

現時点では、 integerstringinferred、およびreference以外の型で安全な引数を使用することはできません。他のタイプを求めるイシューが開かれました。

ただし、 navigate()メソッドを使用して宛先に移動する場合は、プログラムでバンドルを渡します。

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

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

val value = arguments.getString("key")
于 2018-06-19T18:27:04.367 に答える
0

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

私の友人は、アーキテクチャ コンポーネントビューモデルが非常に効率的な方法で解決する問題の 1 つです。ドキュメントの「フラグメント間でデータを共有する」セクションで、使用されている手法を見つけることができます。基本的には、フラグメントにナビゲートされた 2 つ (またはそれ以上) のフラグメント/アクティビティを囲むスコープに代わりにアタッチされるビューモデル インスタンスを作成することがすべてです。そうすれば、ナビゲートされたフラグメントのライフサイクル全体を通して存続します。

以下は、私が本番環境にあるアプリケーションの 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;
}   }

フォームフラグメントで。

    @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() メソッドに送信されるスコープを重要視する必要があります。ビューモデルの宛先フラグメントに送信したいデータを保存してから、宛先フラグメントにナビゲートする前に、宛先フラグメントでビューモデルの同じインスタンスからデータを取得することを知っています。インターフェイスは Android Studio のインテリセンスに使用され、(開発者の観点から) 不要なメソッドを、それが使用されているフラグメントに対応するビューモデルから抽象化します。デリゲートパターン目的のフラグメントに移動する前にビューモデルの目的のフラグメントで一度アクションを実行するようにオブジェクトを設定し、そこにいる間にオブジェクトを取得し、実行するアクションをデリゲートします。String nameこのセットアップでそれを追加したいと思います。変数を intと混同することはほぼ不可能です。

お役に立てれば。

于 2018-12-27T08:02:51.763 に答える
0

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

于 2018-07-18T04:08:46.207 に答える