中規模のアプリを新しいAndroid navigation
コンポーネントに移行しようとしています。
現在、私のアプリはsingle activity
そして、私はそれを同じに保つことを計画しています(そのことについて)。したがって、私は、基本的に他のすべてのフラグメントからナビゲートできる設定フラグメント(PreferenceFragment
)があるこの問題に直面しています。このナビゲーションはアプリバーのメニューから行われるため、onOptionsItemSelected
(このナビゲーションを含む)がメインアクティビティにあります。
settingsFragment
を他の変数に接続する正しい方法を理解するのに苦労しています。それを他のすべてのものに接続することは、私にとってスパゲッティのようです。
settingsFragment
を別のすべてのフラグメントに接続する必要がありますか?
Googleがそれをサポートする十分な理由(または何らかの理由)を提供していないので、シングルアクティビティアプリケーションアーキテクチャを放棄すべきですか?
問題に対処するには、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
の左側にある矢印のみ):
詳細: https://developer.Android.com/topic/libraries/architecture/navigation/navigation-global-action
ただし、設定が階層的である場合、Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager!
子設定をクリックしたとき。
私はこれに対する解決策をまだ見つけていません。
次の方法を使用して、別のフラグメントまたは設定フラグメントに移動できます。
グローバル設定フラグメント:
<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
コールバックをトリガーすることです。
@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);
}