Est-il possible d'utiliser le nouveau composant d'architecture de navigation avec DialogFragment ? Dois-je créer un navigateur personnalisé ?
J'aimerais beaucoup les utiliser avec les nouvelles fonctionnalités de mon graphique de navigation.
Est-il possible d'utiliser le nouveau composant d'architecture de navigation avec DialogFragment ? Dois-je créer un navigateur personnalisé ?
J'aimerais beaucoup les utiliser avec les nouvelles fonctionnalités de mon graphique de navigation.
Mise à jour de mai 2019 :
DialogFragment sont désormais entièrement pris en charge à partir de l'année 2010.
Navigation 2.1.0
vous pouvez lire la suite aquí y aquí
Ancienne réponse pour Navigation <= 2.1.0-alpha02 :
J'ai procédé de cette façon :
1) Mise à jour Navigation
bibliothèque au moins à la version 2.1.0-alpha01
et copier les deux fichiers de ce Liste modifiée dans votre projet.
2) Ensuite, dans votre fragment d'hôte de navigation, changez le name
à votre projet personnalisé NavHostFragment
<fragment
android:id="@+id/nav_host_fragment"
android:name="com.example.app.navigation.MyNavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
3) Créez votre DialogFragment
et les ajouter à votre nav_graph.xml
avec :
<dialog
android:id="@+id/my_dialog"
android:name="com.example.ui.MyDialogFragment"
tools:layout="@layout/my_dialog" />
4) Maintenant, lancez-les à partir des fragments ou de l'activité avec
findNavController().navigate(R.id.my_dialog)
ou des méthodes similaires.
J'ai essayé avec la dernière version et cela fonctionne mais les animations ne fonctionnent pas pour moi. Je dois les définir dans la classe de dialogue. Est-ce que cela arrive à quelqu'un aussi ?
@Pinakin vous manipulez les résultats directement dans votre personnalisé DialogFragment
par exemple en utilisant le onCreateDialog
et de fixer un setPositiveButton
y setNegativeButton
auditeurs
Non, à partir du 1.0.0-alpha01
il n'y a pas de prise en charge des boîtes de dialogue dans le cadre de votre graphique de navigation. Vous devez simplement continuer à utiliser show() pour montrer un DialogFragment
.
Les demandes de fonctionnalités pour la navigation peuvent être adressées au suivi des questions publiques - Veillez à exposer votre cas d'utilisation et à expliquer pourquoi les dialogues de votre graphique de navigation vous seraient utiles.
@AdamHurwitz - n'hésitez pas à mettre en vedette les problème existant pour les mises à jour.
Oui . Le cadre est conçu de manière à ce que vous puissiez créer une classe prolongeant le modèle Navigator
classe abstraite pour les vues qui ne sont pas fournies par la boîte et l'ajouter à votre NavController
avec la méthode getNavigatorProvider().addNavigator(Navigator navigator)
Si vous utilisez le NavHostFragment
vous devrez également l'étendre pour ajouter le navigateur personnalisé ou simplement créer votre propre navigateur. MyFragment
mise en œuvre de NavHost
interface. Elle est si flexible que vous pouvez créer vos propres paramètres xml avec des attrs personnalisés définis dans le fichier values
comme vous le faites en créant des vues personnalisées. Quelque chose comme ceci (non testé) :
@Navigator.Name("dialog-fragment")
class DialogFragmentNavigator(
val context: Context,
private val fragmentManager: FragmentManager
) : Navigator<DialogFragmentNavigator.Destination>() {
override fun navigate(destination: Destination, args: Bundle?,
navOptions: NavOptions?, navigatorExtras: Extras?
): NavDestination {
val fragment = Class.forName(destination.name).newInstance() as DialogFragment
fragment.show(fragmentManager, destination.id.toString())
return destination
}
override fun createDestination(): Destination = Destination(this)
override fun popBackStack() = fragmentManager.popBackStackImmediate()
class Destination(navigator: DialogFragmentNavigator) : NavDestination(navigator) {
// The value of <dialog-fragment app:name="com.example.MyFragmentDialog"/>
lateinit var name: String
override fun onInflate(context: Context, attrs: AttributeSet) {
super.onInflate(context, attrs)
val a = context.resources.obtainAttributes(
attrs, R.styleable.FragmentNavigator
)
name = a.getString(R.styleable.FragmentNavigator_android_name)
?: throw RuntimeException("Error while inflating XML. " +
"`name` attribute is required")
a.recycle()
}
}
}
ma_navigation.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/navigation_home">
<fragment
android:id="@+id/navigation_assistant"
android:name="com.example.ui.HomeFragment"
tools:layout="@layout/home">
<action
android:id="@+id/action_nav_to_dialog"
app:destination="@id/navigation_dialog" />
</fragment>
<dialog-fragment
android:id="@+id/navigation_dialog"
android:name="com.example.ui.MyDialogFragment"
tools:layout="@layout/my_dialog" />
</navigation>
Le fragment qui va naviguer.
class HomeFragment : Fragment(), NavHost {
private val navControllerInternal: NavController by lazy(LazyThreadSafetyMode.NONE){
NavController(context!!)
}
override fun getNavController(): NavController = navControllerInternal
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Built-in navigator for `fragment` XML tag
navControllerInternal.navigatorProvider.addNavigator(
FragmentNavigator(context!!, childFragmentManager, this.id)
)
// Your custom navigator for `dialog-fragment` XML tag
navControllerInternal.navigatorProvider.addNavigator(
DialogFragmentNavigator(context!!, childFragmentManager)
)
navControllerInternal.setGraph(R.navigation.my_navigation)
}
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
val view = inflater.inflate(R.layout.home)
view.id = this.id
view.button.setOnClickListener{
getNavController().navigate(R.id.action_nav_to_dialog)
}
return view
}
}
J'ai créé un navigateur personnalisé pour DialogFragment.
L'échantillon est aquí .
(C'est juste un échantillon, donc ça peut être n'importe quel problème).
@Navigator.Name("dialog_fragment")
class DialogNavigator(
private val fragmentManager: FragmentManager
) : Navigator<DialogNavigator.Destination>() {
companion object {
private const val TAG = "dialog"
}
override fun navigate(destination: Destination, args: Bundle?,
navOptions: NavOptions?, navigatorExtras: Extras?) {
val fragment = destination.createFragment(args)
fragment.setTargetFragment(fragmentManager.primaryNavigationFragment,
SimpleDialogArgs.fromBundle(args).requestCode)
fragment.show(fragmentManager, TAG)
dispatchOnNavigatorNavigated(destination.id, BACK_STACK_UNCHANGED)
}
override fun createDestination(): Destination {
return Destination(this)
}
override fun popBackStack(): Boolean {
return true
}
class Destination(
navigator: Navigator<out NavDestination>
) : NavDestination(navigator) {
private var fragmentClass: Class<out DialogFragment>? = null
override fun onInflate(context: Context, attrs: AttributeSet) {
super.onInflate(context, attrs)
val a = context.resources.obtainAttributes(attrs,
R.styleable.FragmentNavigator)
a.getString(R.styleable.FragmentNavigator_android_name)
?.let { className ->
fragmentClass = parseClassFromName(context, className,
DialogFragment::class.java)
}
a.recycle()
}
fun createFragment(args: Bundle?): DialogFragment {
val fragment = fragmentClass?.newInstance()
?: throw IllegalStateException("fragment class not set")
args?.let {
fragment.arguments = it
}
return fragment
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.