web-dev-qa-db-ja.com

ナビゲーションコンポーネントを使用して設定フラグメントに移動する

中規模のアプリを新しいAndroid navigationコンポーネントに移行しようとしています。

現在、私のアプリはsingle activityそして、私はそれを同じに保つことを計画しています(そのことについて)。したがって、私は、基本的に他のすべてのフラグメントからナビゲートできる設定フラグメント(PreferenceFragment)があるこの問題に直面しています。このナビゲーションはアプリバーのメニューから行われるため、onOptionsItemSelected(このナビゲーションを含む)がメインアクティビティにあります。

Navigation graph

settingsFragmentを他の変数に接続する正しい方法を理解するのに苦労しています。それを他のすべてのものに接続することは、私にとってスパゲッティのようです。

  1. settingsFragmentを別のすべてのフラグメントに接続する必要がありますか?

  2. Googleがそれをサポートする十分な理由(または何らかの理由)を提供していないので、シングルアクティビティアプリケーションアーキテクチャを放棄すべきですか?

12
San Mo

問題に対処するには、global actionsを使用できます。それらを使用するには、通常のように<navigation>内ではなく、<fragment>タグ内でアクションを定義する必要があります。あなたのナビゲーショングラフには次のコードが含まれます

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <!--Your other fragments-->


    <!--Settings fragment-->
    <fragment
        Android:id="@+id/settingsFragment"
        Android:name="com.example.oleksii.stackoverflow.SettingsFragment"/>

    <!--Global action-->
    <action Android:id="@+id/open_settings_fragment"
        app:destination="@id/settingsFragment"/>
</navigation>

グラフエディターでは、次のように表示されます(destinationの左側にある矢印のみ):

enter image description here

詳細: https://developer.Android.com/topic/libraries/architecture/navigation/navigation-global-action

10

ただし、設定が階層的である場合、Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager!子設定をクリックしたとき。

私はこれに対する解決策をまだ見つけていません。

2
Simon Kenyon

次の方法を使用して、別のフラグメントまたは設定フラグメントに移動できます。

グローバル設定フラグメント:

<PreferenceCategory
    app:title="@string/global_settings_header">
    <Preference
        app:key="fragment_a"
        app:title="A"
        app:fragment="....settings.SettingsFragmentA" />
    <Preference
        app:key="fragment_b"
        app:title="B"
        app:fragment=".....settings.SettingsFragmentB" />
</PreferenceCategory>

アクティビティにPreferenceFragmentCompat.OnPreferenceStartFragmentCallbackを実装しました。

public class MainActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
....

@Override
public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
    NavController navController = Navigation.findNavController(MainActivity.this, R.id.nav_Host_fragment);
    if (pref.getKey().equals("fragment_a")) {
        navController.navigate(R.id.nav_settings_fragment_a);
    } else if (pref.getKey().equals("fragment_b")) {
        navController.navigate(R.id.nav_settings_fragment_b);
    }
    return true;
}

....
}

NavControllerを使用して、ナビゲーショングラフで定義されている任意のフラグメントに移動することもできます。

フラグメントはapp:fragment=".....settings.SettingsFragment"で使用できます。アイデアは、onPreferenceStartFragmentコールバックをトリガーすることです。

0
Patriotic

@Alexeyからの回答に基づいて、グローバルアクションを呼び出すには、次のようなコードを使用できます。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id == R.id.action_settings) {
        Navigation.findNavController(this, R.id.nav_Host_fragment).navigate(R.id.settingsFragment);
    }
    return super.onOptionsItemSelected(item);
}
0
jon