I have a fragment in a navigation graph with two parameters (ids: List<Int>? and name: String?) - these both have default values set (both set to #null).
I have created a deeplink to this fragment from the pattern mysite.com/{name} but after upgrading to navigation version 2.4.0-alpha08 I get this error when running my app:
Caused by: java.lang.IllegalArgumentException: Deep link mysite.com/{name} can't be used to open destination Destination(com.mysite:id/myFragment) class=com.mysite.MyFragment.
Following required arguments are missing: [ids]
As the exception is thrown when inflating my MainActivity.xml, it seems like the default value for ids is being ignored when validating the deeplink.
This didn't happen in version 2.4.0-alpha06.
Is this a bug in this version of the navigation component (I'll raise a bug if so), or is this just better validation in that component revealing a bug in my code - if so, what's the fix?
Horribly, here's the hack I'm using.
URL parameters are optional if their value has a default set, so my deeplinks in the navigation graph now look like this:
mysite.com/{name}?this_wont_ever_really_happen={ids}
which matches the url mysite.com/{name} because ids has a default value (of #null)
Jetpack Navigation version 2.5.0-alpha04 release note mentions a fix to solve this kind of problem:
Related
I am interested in writing a wrapper library for Jetpack Compose Navigation that handles custom navigation argument types. I have a working prototype that handles any kind of data type leveraging kotlinx Serializable.
There's just one thing that I don't understand - and I will likely need to understand this if I am to write a complete library:- what is the NavType for?
The following articles leverage android Parcelable to achieve similar:-
gitconnected.com, droidcon.com
Both examples go to the trouble of extending NavType, which includes custom methods for serializing and deserializing the argument data, however, from experimentation these methods are never called. In fact, I can comment out the arguments parameter of the composable entry completely and it still works.
The official documentation states "the NavType object denoting the type that can be help in this argument." and then further links on supported types, however, none of this answers my question.
The NavType is needed when you want to add parameters to your navigation. Meaning, whenever you add a navigation parameter to a navigation route your NavHost needs to know what type the parameter has in order to be able to parse it correctly.
So when you want to pass on the username entered in screen A to screen B and you use your NavHost to navigate between them, you need to let the NavHost know that the parameter username is of type String. If the NavHost knows that it can parse it correctly and screen B can show the username entered in screen A.
Generally, the primitive types and arrays of primitive types are supported like described in the documentation.
For custom NavTypes you can check out my medium article ;)
I hope that answers your question.
I want to implement the android.intent.action.SEND as per the developers tutorial with the navigation component.
But when making deep links in the navigation.xml it requires a Uri with the below error message:
Navigation XML document element must contain a app:uri
attribute.
I am using Android Studio 4.1.3 and I do have the option to choose an action. But it just doesn't work without uri.
The docs are leaving some basic questions open:
How to get the intent params like Intent.EXTRA_TEXT
How to provide category and 'data'?
How to provide multiple actions/categories/datas?
I'm writing automated tests for my company's app. The tests use a combination of Espresso and Robotium. Several of those tests are supposed to check whether certain ReactImageView elements are displaying a specific image.
I first tried using hasBackground() as follows:
onView(...).check(matches(hasBackground(R.drawable...)));
However, this returns a NoMatchingViewException.
I then tried Daniele Bottillo's matcher as described here: https://medium.com/#dbottillo/android-ui-test-espresso-matcher-for-imageview-1a28c832626f
onView(allOf(..., new DrawableMatcher(R.drawable....), isDisplayed())).check(matches(isDisplayed()));
But this didn't work either:
java.lang.ClassCastException: com.facebook.drawee.generic.RootDrawable cannot be cast to android.graphics.drawable.BitmapDrawable
Lastly, I tried Frankie Sardo's solution: Android Espresso match BitmapDrawables with different tint
onView(allOf(..., withImageDrawable(R.drawable...), isDisplayed())).check(matches(isDisplayed()));
However, this again throws a NoMatchingViewException. I'm running out of ideas. Is it even possible to check what resource is attached to an image view?
The easiest way would be to use Barista library and its assertHasDrawable(R.id.<imageview_id>, R.drawable.<drawable_id>) assertion function.
I have added vector drawable in my app, and its working fine in activity.
ivTeam.setImageDrawable(ContextCompat.getDrawable(this,R.drawable.ic_home_team))
but when i execute the same code from recycler adapter which is in a fragment, it crashes and gives following error message.
android.content.res.Resources$NotFoundException: File
res/drawable/test.xml from drawable resource ID #0x7f122e
I am passing activity reference to adapter, and also tried following static block.
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
but nothing seems to be working here, i am on androidX, and added following in my my gradle file.
vectorDrawables.useSupportLibrary = true
Gradle Version:
classpath 'com.android.tools.build:gradle:3.4.1'
if you are indeed using Android X I suspect you might not be loading your vector drawables correctly
I have read your question shortly after an article which states:
Load with AndroidX
When loading drawables you need to use methods from AndroidX which provide the backported vector support. The entry point for this is to always load drawables with AppCompatResources.getDrawable. While there are a number of ways to load drawables (because reasons), you must use AppCompatResources if you want to use compat vectors. If you fail to do this, then you won’t hook into the AndroidX code path and your app might crash when trying to use any features not supported by the platform you’re running on.
From your code it appears that you are using ContextCompat.getDrawable instead of AppCompatResources.getDrawable
Using AppCompatResources.getDrawable should correct your issue
We've been using the Navigation component in our project but have stumbled across an issue which seems unique to our project and the JetBrains Android plugin. I can't pinpoint the exact point it started happening but I noticed it after the release of AS 3.2.
The project builds fine however when editing a navigation XML things such as auto-complete and highlighting are broken and the Android Support Plugin throws this error:
java.lang.IllegalArgumentException: Multiple entries with same key: org.jetbrains.android.dom.navigation.NavigationSchema$TypeRef#0=org.jetbrains.android.dom.navigation.NavigationSchema$NavigatorKeyInfo#17d69e53 and org.jetbrains.android.dom.navigation.NavigationSchema$TypeRef#0=org.jetbrains.android.dom.navigation.NavigationSchema$NavigatorKeyInfo#442c4fde
at com.google.common.collect.ImmutableMap.conflictException(ImmutableMap.java:215)
at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:209)
at com.google.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket(RegularImmutableMap.java:147)
at com.google.common.collect.RegularImmutableMap.fromEntryArray(RegularImmutableMap.java:110)
at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:393)
at org.jetbrains.android.dom.navigation.NavigationSchema.buildCacheKeys(NavigationSchema.java:488)
at org.jetbrains.android.dom.navigation.NavigationSchema.init(NavigationSchema.java:479)
at org.jetbrains.android.dom.navigation.NavigationSchema.createIfNecessary(NavigationSchema.java:389)
at org.jetbrains.android.dom.AttributeProcessingUtil.processNavAttributes(AttributeProcessingUtil.java:408)
at org.jetbrains.android.dom.AttributeProcessingUtil.processAttributes(AttributeProcessingUtil.java:596)
at org.jetbrains.android.dom.AndroidDomExtender.registerExtensions(AndroidDomExtender.java:57)
at org.jetbrains.android.dom.AndroidDomExtender.registerExtensions(AndroidDomExtender.java:29)
at com.intellij.util.xml.reflect.DomExtenderEP.extend(DomExtenderEP.java:83)
at com.intellij.util.xml.impl.DynamicGenericInfo.runDomExtenders(DynamicGenericInfo.java:134)
at com.intellij.util.xml.impl.DynamicGenericInfo.lambda$checkInitialized$0(DynamicGenericInfo.java:64)
at com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:98)
at com.intellij.util.xml.impl.DynamicGenericInfo.checkInitialized(DynamicGenericInfo.java:63)
at com.intellij.util.xml.impl.DynamicGenericInfo.getAttributeChildrenDescriptions(DynamicGenericInfo.java:241)
at com.intellij.util.xml.impl.DynamicGenericInfo.processAttributeChildrenDescriptions(DynamicGenericInfo.java:254)
at com.intellij.util.xml.impl.DomSemContributor.lambda$registerSemProviders$5(DomSemContributor.java:199)
at com.intellij.semantic.SemServiceImpl$2.lambda$registerSemElementProvider$0(SemServiceImpl.java:93)
at com.intellij.semantic.SemServiceImpl.createSemElements(SemServiceImpl.java:190)
at com.intellij.semantic.SemServiceImpl.getSemElements(SemServiceImpl.java:161)
at com.intellij.semantic.SemService.getSemElement(SemService.java:37)
at com.intellij.util.xml.impl.DomManagerImpl.getDomHandler(DomManagerImpl.java:390)
at com.intellij.util.xml.impl.GenericValueReferenceProvider.getReferencesByElement(GenericValueReferenceProvider.java:47)
at com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl.getReferences(ReferenceProvidersRegistryImpl.java:135)
at com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl.mapNotEmptyReferencesFromProviders(ReferenceProvidersRegistryImpl.java:123)
at com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl.doGetReferencesFromProviders(ReferenceProvidersRegistryImpl.java:102)
at com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry.getReferencesFromProviders(ReferenceProvidersRegistry.java:50)
at com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry.getReferencesFromProviders(ReferenceProvidersRegistry.java:44)
at com.intellij.psi.impl.source.xml.XmlAttributeValueImpl.getReferences(XmlAttributeValueImpl.java:110)
at com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor.checkReferences(XmlHighlightVisitor.java:439)
at com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor.visitXmlAttributeValue(XmlHighlightVisitor.java:406)
at com.intellij.psi.impl.source.xml.XmlAttributeValueImpl.accept(XmlAttributeValueImpl.java:61)
at com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor.visit(XmlHighlightVisitor.java:587)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.runVisitors(GeneralHighlightingPass.java:353)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.lambda$collectHighlights$5(GeneralHighlightingPass.java:286)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.analyzeByVisitors(GeneralHighlightingPass.java:313)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.lambda$analyzeByVisitors$6(GeneralHighlightingPass.java:316)
at com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor.analyze(XmlHighlightVisitor.java:597)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.analyzeByVisitors(GeneralHighlightingPass.java:316)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.lambda$analyzeByVisitors$6(GeneralHighlightingPass.java:316)
at com.intellij.codeInsight.daemon.impl.DefaultHighlightVisitor.analyze(DefaultHighlightVisitor.java:71)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.analyzeByVisitors(GeneralHighlightingPass.java:316)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectHighlights(GeneralHighlightingPass.java:283)
at com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.collectInformationWithProgress(GeneralHighlightingPass.java:227)
at com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass.doCollectInformation(ProgressableTextEditorHighlightingPass.java:84)
at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:69)
at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$null$1(PassExecutorService.java:423)
at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1171)
at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$doRun$2(PassExecutorService.java:416)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:582)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:532)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:87)
at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.doRun(PassExecutorService.java:415)
at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.lambda$run$0(PassExecutorService.java:391)
at com.intellij.openapi.application.impl.ReadMostlyRWLock.executeByImpatientReader(ReadMostlyRWLock.java:147)
at com.intellij.openapi.application.impl.ApplicationImpl.executeByImpatientReader(ApplicationImpl.java:222)
at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:389)
at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask$1.exec(JobLauncherImpl.java:161)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
We're running the latest version of the navigation component (2.0.0-rc2) and and I've tried all the usual fixes (Invalidate Caches & Restart etc). I've tried using navigation in fresh projects and it seems to work without this error being thrown.
I have tried removing all nav XMLs from our project and then adding in a completely blank XML but it still throws the error. I delved into the source of the plugin and it seems this occurs when the plugin is initially processing the nav file for the design view which doesn't make sense if it's throwing it for a fresh nav file.
I'm currently at a loss as to why this may be happening and any ideas would be greatly appreciated!
The short answer:
I fixed it by moving an anonymous class which extended androidx.navigation.Navigator to a separate class and adding the annotation #Navigator.Name(String name) with a unique name.
If you are also experiencing this issue check that in your project or its dependencies if there are any classes inheriting the Navigator class which are either missing the #Navigator.Name(String name) annotation or using non-unique strings as the name parameter. fragment and activity cannot be used as they are used already within the API.
Further info:
After further delving into the Android Support plugin source code to understand what's going on I've managed to solve the issue on our project.
When initiating the IDE functionality in the Android Support Plugin it goes through your project and any dependencies looking for any class which inherits the Navigator class and gives it a tag for the purpose of managing it in the XML files and design view. This tag is based on an annotation #Navigator.Name(String name). If no annotation is present a default value is used.
These tags have to be unique as they are used as the keys for building an immutable map of tags to navigator types. In our project we had an anonymous class which was extending Navigator class and had no annotation.
There is also an anonymous class extending Navigator within the navigation component source, specifically within the NavDeepLinkBuilder class. As there is only a single default value for the tags any other class inheriting Navigator with no annotation being present in your project or its dependencies will cause this issue.