Repository: Kotlin/anko Branch: master Commit: 37893764c0f2 Files: 396 Total size: 2.8 MB Directory structure: gitextract_fw5cbrlj/ ├── .gitignore ├── .idea/ │ └── runConfigurations/ │ └── Android_Studio.xml ├── CHANGELOG.md ├── GOODBYE.md ├── LICENSE ├── README.md ├── anko/ │ ├── idea-plugin/ │ │ ├── attrs/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── android/ │ │ │ └── Attrs.kt │ │ ├── build.gradle │ │ ├── idea-runner/ │ │ │ └── build.gradle │ │ ├── intentions/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── anko/ │ │ │ └── idea/ │ │ │ └── intentions/ │ │ │ ├── AnkoIntention.kt │ │ │ ├── FindViewByIdIntention.kt │ │ │ ├── ReplaceColorGrayOpaqueIntention.kt │ │ │ └── ToastMakeTextShowIntention.kt │ │ ├── plugin-classpath/ │ │ │ └── build.gradle │ │ ├── preview/ │ │ │ ├── build.gradle │ │ │ ├── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── plugin.xml │ │ │ │ └── intentionDescriptions/ │ │ │ │ ├── FindViewByIdIntention/ │ │ │ │ │ ├── after.kt.template │ │ │ │ │ ├── before.kt.template │ │ │ │ │ └── description.html │ │ │ │ ├── ReplaceColorGrayOpaqueIntention/ │ │ │ │ │ ├── after.kt.template │ │ │ │ │ ├── before.kt.template │ │ │ │ │ └── description.html │ │ │ │ └── ToastMakeTextShowIntention/ │ │ │ │ ├── after.kt.template │ │ │ │ ├── before.kt.template │ │ │ │ └── description.html │ │ │ └── src/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── android/ │ │ │ └── dslpreview/ │ │ │ ├── AnkoNlPreviewManager.kt │ │ │ ├── AnkoViewLoaderExtension.kt │ │ │ ├── DslPreviewClassResolver.kt │ │ │ ├── LayoutPsiFile.kt │ │ │ ├── PreviewClassDescription.kt │ │ │ ├── SourceFileModificationTracker.kt │ │ │ └── UpdateActivityNameTask.kt │ │ └── xml-converter/ │ │ ├── build.gradle │ │ ├── resources/ │ │ │ ├── attrs.json │ │ │ └── views.json │ │ ├── src/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── android/ │ │ │ └── xmlconverter/ │ │ │ ├── AttributeOptimizer.kt │ │ │ ├── AttributeParser.kt │ │ │ ├── ConvertAction.kt │ │ │ ├── LayoutAttributeRenderer.kt │ │ │ ├── Util.kt │ │ │ ├── ViewAttributeRenderer.kt │ │ │ └── XmlConverter.kt │ │ ├── test/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── kotlin/ │ │ │ └── android/ │ │ │ └── xmlconverter/ │ │ │ ├── BaseXmlConverterTest.java │ │ │ └── XmlConverterTest.kt │ │ └── testData/ │ │ ├── attributes/ │ │ │ ├── layout.kt │ │ │ └── layout.xml │ │ ├── dimensions/ │ │ │ ├── layout.kt │ │ │ └── layout.xml │ │ ├── linearLayout/ │ │ │ ├── layout.kt │ │ │ └── layout.xml │ │ ├── relativeLayout/ │ │ │ ├── layout.kt │ │ │ └── layout.xml │ │ └── simple/ │ │ ├── layout.kt │ │ └── layout.xml │ ├── library/ │ │ ├── generated/ │ │ │ ├── anko/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── appcompat-v7/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ └── Views.kt │ │ │ ├── appcompat-v7-commons/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── appcompat-v7-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── appcompat-v7-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── cardview-v7/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ └── Views.kt │ │ │ ├── common/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── commons/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── constraint-layout/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ └── Views.kt │ │ │ ├── coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── bg.kt │ │ │ │ └── weakReferenceSupport.kt │ │ │ ├── design/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ └── Views.kt │ │ │ ├── design-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── design-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── gridlayout-v7/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ └── Views.kt │ │ │ ├── percent/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ └── Views.kt │ │ │ ├── recyclerview-v7/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ └── Views.kt │ │ │ ├── recyclerview-v7-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── recyclerview-v7-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk15/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk15-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk15-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk19/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk19-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk19-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk21/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk21-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk21-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk23/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk23-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk23-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk25/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk25-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk25-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk27/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk27-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk27-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sdk28/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Services.kt │ │ │ │ └── Views.kt │ │ │ ├── sdk28-coroutines/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ListenersWithCoroutines.kt │ │ │ ├── sdk28-listeners/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Listeners.kt │ │ │ ├── sqlite/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── SqlParserHelpers.kt │ │ │ ├── support-v4/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── Layouts.kt │ │ │ │ ├── Listeners.kt │ │ │ │ └── Views.kt │ │ │ └── support-v4-commons/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── AndroidManifest.xml │ │ ├── generator/ │ │ │ ├── build.gradle │ │ │ ├── src/ │ │ │ │ └── org/ │ │ │ │ └── jetbrains/ │ │ │ │ └── android/ │ │ │ │ └── anko/ │ │ │ │ ├── ClassProcessor.kt │ │ │ │ ├── annotations/ │ │ │ │ │ ├── AnnotationManager.kt │ │ │ │ │ └── annotationProviders.kt │ │ │ │ ├── artifact/ │ │ │ │ │ └── Artifact.kt │ │ │ │ ├── config/ │ │ │ │ │ ├── AnkoConfiguration.kt │ │ │ │ │ ├── AnkoFile.kt │ │ │ │ │ ├── ArtifactType.kt │ │ │ │ │ ├── ConfigurationKey.kt │ │ │ │ │ ├── DefaultAnkoConfiguration.kt │ │ │ │ │ ├── GeneratorContext.kt │ │ │ │ │ ├── Logger.kt │ │ │ │ │ ├── Props.kt │ │ │ │ │ └── configurationKeys.kt │ │ │ │ ├── generator/ │ │ │ │ │ ├── GenerationState.kt │ │ │ │ │ ├── LayoutGenerator.kt │ │ │ │ │ ├── ListenerGenerator.kt │ │ │ │ │ ├── PropertyGenerator.kt │ │ │ │ │ ├── ServiceGenerator.kt │ │ │ │ │ ├── dslElements.kt │ │ │ │ │ ├── layoutParamsUtils.kt │ │ │ │ │ └── viewClassGenerators.kt │ │ │ │ ├── main.kt │ │ │ │ ├── render/ │ │ │ │ │ ├── LayoutRenderer.kt │ │ │ │ │ ├── ListenerRenderer.kt │ │ │ │ │ ├── PropertyRenderer.kt │ │ │ │ │ ├── RenderFacade.kt │ │ │ │ │ ├── ServiceRenderer.kt │ │ │ │ │ ├── SqlParserHelperRenderer.kt │ │ │ │ │ ├── viewConstructorUtils.kt │ │ │ │ │ └── viewRenderers.kt │ │ │ │ ├── sources/ │ │ │ │ │ ├── SourceManager.kt │ │ │ │ │ └── sourceProviders.kt │ │ │ │ ├── templates/ │ │ │ │ │ ├── JtwigTemplateProvider.kt │ │ │ │ │ ├── MustacheTemplateProvider.kt │ │ │ │ │ └── TemplateManager.kt │ │ │ │ ├── utils/ │ │ │ │ │ ├── Buffer.kt │ │ │ │ │ ├── ClassInfo.kt │ │ │ │ │ ├── ClassTree.kt │ │ │ │ │ ├── ClassTreeUtils.kt │ │ │ │ │ ├── ImportList.kt │ │ │ │ │ ├── KMethod.kt │ │ │ │ │ ├── KType.kt │ │ │ │ │ ├── KVariable.kt │ │ │ │ │ ├── MethodInfo.kt │ │ │ │ │ ├── Property.kt │ │ │ │ │ ├── ReflectionUtils.kt │ │ │ │ │ ├── SignatureParser.kt │ │ │ │ │ ├── Types.kt │ │ │ │ │ ├── stringUtils.kt │ │ │ │ │ └── utils.kt │ │ │ │ └── writer/ │ │ │ │ ├── AbstractWriter.kt │ │ │ │ ├── GeneratorWriter.kt │ │ │ │ └── VerifyWriter.kt │ │ │ └── test/ │ │ │ └── org/ │ │ │ └── jetbrains/ │ │ │ └── android/ │ │ │ └── anko/ │ │ │ └── ClassTreeTest.java │ │ ├── library.gradle │ │ ├── robolectricTests/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── local.properties │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── AndroidLayoutParamsTestActivity.kt │ │ │ │ ├── AndroidLayoutsTestActivity.kt │ │ │ │ ├── AndroidListenerHelpersTestActivity.kt │ │ │ │ ├── AndroidMultiMethodListenersActivity.kt │ │ │ │ ├── AndroidPropertiesTestActivity.kt │ │ │ │ ├── AndroidSimpleTestActivity.kt │ │ │ │ ├── AndroidWidgetTestActivity.kt │ │ │ │ └── README.md │ │ │ └── test/ │ │ │ └── java/ │ │ │ ├── AnkoLoggerTest.kt │ │ │ ├── AnkoSQliteTest.kt │ │ │ ├── AttemptTest.kt │ │ │ ├── BuildSpannedTest.kt │ │ │ ├── BundleOfTest.kt │ │ │ ├── ChildrenSequenceTest.kt │ │ │ ├── ClassParserTest.kt │ │ │ ├── CollectionsTest.kt │ │ │ ├── CreateIntentTest.kt │ │ │ ├── DialogsTest.kt │ │ │ ├── FindViewTest.kt │ │ │ ├── IntentForTest.kt │ │ │ ├── RelativeLayoutHelpersTest.kt │ │ │ ├── ServiceTest.kt │ │ │ ├── SimpleTest.kt │ │ │ ├── SparseArraysTest.kt │ │ │ └── WithArgumentsTest.kt │ │ ├── static/ │ │ │ ├── appcompatV7/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── SupportAlertBuilder.kt │ │ │ ├── commons/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── AnkoContext.kt │ │ │ │ ├── Async.kt │ │ │ │ ├── ContextUtils.kt │ │ │ │ ├── Custom.kt │ │ │ │ ├── Deprecated.kt │ │ │ │ ├── Dimensions.kt │ │ │ │ ├── Helpers.kt │ │ │ │ ├── Intents.kt │ │ │ │ ├── Internals.kt │ │ │ │ ├── Logging.kt │ │ │ │ ├── RelativeLayoutLayoutParamsHelpers.kt │ │ │ │ ├── SharedPreferences.kt │ │ │ │ ├── Theme.kt │ │ │ │ ├── Ui.kt │ │ │ │ ├── buildSpanned.kt │ │ │ │ ├── collections/ │ │ │ │ │ ├── Arrays.kt │ │ │ │ │ ├── Collections.kt │ │ │ │ │ └── SparseArrays.kt │ │ │ │ ├── dialogs/ │ │ │ │ │ ├── AlertBuilder.kt │ │ │ │ │ ├── AlertDialogBuilder.kt │ │ │ │ │ ├── AndroidAlertBuilder.kt │ │ │ │ │ ├── AndroidDialogs.kt │ │ │ │ │ ├── AndroidSelectors.kt │ │ │ │ │ ├── Dialogs.kt │ │ │ │ │ ├── Selectors.kt │ │ │ │ │ └── Toasts.kt │ │ │ │ ├── menuItemsSequences.kt │ │ │ │ └── viewChildrenSequences.kt │ │ │ ├── constraint-layout/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── ConstraintLayout.kt │ │ │ ├── design/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ └── Snackbar.kt │ │ │ ├── platform/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── CustomLayoutProperties.kt │ │ │ │ ├── CustomServices.kt │ │ │ │ ├── CustomViewProperties.kt │ │ │ │ ├── CustomViews.kt │ │ │ │ ├── InputConstraints.kt │ │ │ │ └── Menus.kt │ │ │ ├── sqlite/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java/ │ │ │ │ ├── ClassParser.kt │ │ │ │ ├── Database.kt │ │ │ │ ├── SelectQueryBuilder.kt │ │ │ │ ├── SqlParsers.kt │ │ │ │ ├── UpdateQueryBuilder.kt │ │ │ │ ├── org/ │ │ │ │ │ └── jetbrains/ │ │ │ │ │ └── anko/ │ │ │ │ │ └── db/ │ │ │ │ │ └── JavaSqliteUtils.java │ │ │ │ └── sqlTypes.kt │ │ │ └── supportV4/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ ├── Support.kt │ │ │ ├── SupportAsync.kt │ │ │ ├── SupportContextUtils.kt │ │ │ ├── SupportDialogs.kt │ │ │ ├── SupportDimensions.kt │ │ │ └── SupportIntents.kt │ │ ├── stubs/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── Stubs.kt │ │ └── testUtils/ │ │ ├── build.gradle │ │ └── src/ │ │ ├── com/ │ │ │ └── intellij/ │ │ │ └── rt/ │ │ │ └── execution/ │ │ │ └── junit/ │ │ │ ├── FileComparisonFailure.java │ │ │ └── KnownException.kt │ │ └── org/ │ │ └── jetbrains/ │ │ └── anko/ │ │ └── test/ │ │ └── testUtils.kt │ └── props/ │ ├── annotations/ │ │ └── android/ │ │ ├── support/ │ │ │ └── v7/ │ │ │ └── widget/ │ │ │ └── annotations.xml │ │ ├── view/ │ │ │ └── annotations.xml │ │ └── widget/ │ │ └── annotations.xml │ ├── configuration.json │ ├── excluded_methods.txt │ ├── excluded_properties.txt │ ├── helper_constructors.txt │ ├── imports_properties.txt │ ├── imports_sqliteparserhelpers.txt │ ├── imports_views.txt │ ├── kotlin-android-sdk-annotations-1.0.0.jar │ ├── properties_without_getters.txt │ └── templates/ │ ├── complex_listener.twig │ ├── complex_listener_coroutines.twig │ ├── layout.twig │ ├── services.twig │ ├── simple_listener.mustache │ ├── simple_listener_coroutines.twig │ ├── sql_parser_helpers.twig │ └── view.mustache ├── build.gradle ├── download_android_sdk.xml ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── update_dependencies.xml └── update_dependencies_idea.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ /dependencies/ /ideaSDK/ build/ .DS_Store *.iml .gradle /out .idea/* !.idea/runConfigurations local.properties ================================================ FILE: .idea/runConfigurations/Android_Studio.xml ================================================ ================================================ FILE: CHANGELOG.md ================================================ ## Change Log ### Anko 0.10.5 *(2018-04-28)* - [DSL for ConstraintLayout](https://github.com/Kotlin/anko/wiki/ConstraintLayout) - Preview plugin compatibility with Android Studio 3.1 C6 ### Anko 0.10.3 *(2017-11-22)* #### Bugfixes - Anko support plugin compatibility with Kotlin 1.1.60+ - Fix Xml to Dsl converter ([#370](https://github.com/Kotlin/anko/issues/370)) - `lparams` for `CollapsingToolbarLayout`, now returns correct LayoutParams ([#275](https://github.com/Kotlin/anko/issues/275), [#269](https://github.com/Kotlin/anko/issues/269)) - `Context.clipboardManager` now returns new `ClipboardManager` instead of deprecated one ([#180](https://github.com/Kotlin/anko/issues/180)) - Generate layout wrapper for `CardView` ([#269](https://github.com/Kotlin/anko/issues/269), [#357](https://github.com/Kotlin/anko/issues/357)) - Fix ClassParser's Boolean parser when type is Long ([#464](https://github.com/Kotlin/anko/issues/464)) #### Breaking Changes - Removed Dsl for classes from `android.support.design.internal.*` as they shouldn't be used outside of support library #### Other Changes - `TextInputEditText` added to anko-design ([#205](https://github.com/Kotlin/anko/issues/205)) - Anko commons dialog extensions now accept `CharSequence` instead of `String` ([#422](https://github.com/Kotlin/anko/issues/422)) - Add start and end rules to RelativeLayout.LayoutParams extensions ([#497](https://github.com/Kotlin/anko/pull/497)) - Add `allCaps` and `ems` properties to TextView ([#459](https://github.com/Kotlin/anko/pull/459)) - Add snackbar helpers with indefinite duration [(#454](https://github.com/Kotlin/anko/pull/454)) - Allow nullable values in `createIntent` and `startActivity` ([#465](https://github.com/Kotlin/anko/pull/465)) - Add extensions for `View::backgroundColorResource` and `TextView::textColorResource` ([#254](https://github.com/Kotlin/anko/pull/254)) - Return `ComponentName` from `startService` methods ([#435](https://github.com/Kotlin/anko/issues/435)) - Allow alerts to be cancelable ([#405](https://github.com/Kotlin/anko/pull/405)) - Add intent helpers for stopping services ([#509](https://github.com/Kotlin/anko/pull/509)) - Return toast object in toast helper functions ([#512](https://github.com/Kotlin/anko/pull/512)) ### Anko 0.10.2 *(2017-10-17)* - Fixed Anko Support IDE plugin compatibility with Android Studio 3.0 RC1 - `Fragment.indeterminateProgressDialog` now shows indeterminate progress dialog instead of classic ([#487](https://github.com/Kotlin/anko/pull/487)) - Added methods for creating and dropping a index for SQLiteDatabase ([#472](https://github.com/Kotlin/anko/pull/472)) ### Anko 0.10.1 *(2017-05-31)* #### Bugfixes - Fix assertion in the Anko Support IDE plugin ([#387](https://github.com/Kotlin/anko/issues/387)); - Update `kotlinx.coroutines.android` dependency (the old one fails to resolve in Android Studio 3.0) )[#381](https://github.com/Kotlin/anko/issues/381)); - Fix inconsistency between `hasNext()` and `next()` in `childrenRecursiveSequence()` ([#388](https://github.com/Kotlin/anko/pull/388)). ### Anko 0.10 *(2017-05-17)* #### 🐧 Notable changes: - Coroutines and `DslMarker` annotation support; - Anko Support IDE plugin updated for Android Studio 2.4. #### Breaking changes: - `DslMarker` annotation support (calling `lparams()` inside View blocks is finally forbidden); - DSL listeners moved to `anko--listeners` artifacts (e.g. `anko-sdk25-listeners`); - View blocks with the `theme` parameter renamed to `themed…()` to avoid disambiguation; - Removed `AnkoLogger(clazz: KClass<*>)` and `AnkoLogger(obj: Any)`. #### New API: - `anko--coroutines` (e.g. `anko-sdk25-coroutines`) artifacts with the new listener helpers with coroutines support; - `bg()` function that executes code in background (wrapper on top of [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines)); - `AlertBuilder` interface with *core* and *appcompat* implementations. `AlertDialogBuilder` is deprecated; - `Snackbar` helpers #203; - `Dialog.find()` method #351; - `foreach()` extensions for `SparseArray` #255; - Reified version for `AnkoLogger` (`AnkoLogger()`); - `isError` and `hasValue` to `AttemptResult`. #### Other changes: - Anko Support IDE plugin upated in order to support Android Studio 2.4; - Added meta-artifact `org.jetbrains.anko:anko`; - Added *Anko Commons* artifacts for Android support libraries (`anko-support-v4-commons`, `anko-appcompat-v7-commons`) #158; - New Android SDK target: `sdk-25`; - Updated Android Support library dependencies; - `anko-common` artifact renamed to `anko-commons` to reflect the naming changes. `anko-common` is deprecated; - `ClassParser` now accepts all primitive types #320; - Synthetic properties (such as `act` or `ctx`) are now `inline`; - `lparams` functions are now `inline` #338; - Removed `TextView.enabled` generated property #245; - Accessing setter-only property values is now forbidden. #### Bugfixes: - Fix `NoSuchMethodError` on accessing `act` property from the support Fragment #311; - Fix compatibility with Proguard #235; - Require the relative view `id` to be set in `RelativeView` helpers #363. ### Anko 0.10 Beta 2 *(2017-03-22)* #### Breaking changes: - DSL listeners moved to `anko--listeners` (e.g. `anko-sdk15-listeners`) artifacts; - The custom `async()` function introduced in 0.10.0-beta1 was removed (use `async()` from [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines)); - `AnkoLogger(clazz: KClass<*>)` and `AnkoLogger(obj: Any)` functions are removed; #### Other changes: - `anko--coroutines` (e.g. `anko-sdk15-coroutines`) artifacts with the new listener helpers with coroutines support; - `lparams` functions are now `inline` #338; - `bg()` function that executes code in a background thread and returns `Deferred`; - `AnkoLogger` now has the reified version: `AnkoLogger()`; ### Anko 0.10 Beta 1 *(2017-03-06)* **Anko 0.10 requires Kotlin 1.1.** #### Breaking changes: - View DSL functions that accept the `theme` parameter are renamed to `themed…()` to avoid disambiguation; - `DslMarker` support (`lparams` inside the View lambda are now forbidden); #### Other changes: - Add `anko-coroutines` artifact with the Kotlin 1.1 coroutines support (`async` / `bg`); - New Android SDK target: `sdk-25`; - Android Support library dependencies updated; - `AlertBuilder` interface with core and app-compat implementations. `AlertDialogBuilder` is deprecated; - `ClassParser` now accepts all primitive types #320; - New artifacts: `anko-support-v4-common` and `anko-appcompat-v7-common` (with basic helpers, without the DSL functionality) #158; - Synthetic properties (such as `act` or `ctx`) are now `inline`; - `TextView.enabled` generated property is removed #245; - Accessing setter-only property values is forbidden; - SAM View listener setter functions are now `inline`; - Add `isError` and `hasValue` to `AttemptResult`; - Fix `NoSuchMethodError` on accessing `act` property from the support Fragment #311. ### Anko 0.9.1 *(2016-12-14)* - Allow to use `AnkoLogger` as an instance #262; - `FOREIGN_KEY` now returns `Pair` #258 #219; - Fix `SparseArray` as sequence returns list which doesn't match its size #243 #240; - Allow ManagedSQLiteOpenHelper to accept null for database name #228; - Fix ProGuard warning (can't find referenced method 'int getThemeResId()' in library class android.view.ContextThemeWrapper). #206; - Add `LayoutParams.baselineOf()` #213; - Allow nullable values in `intentFor` #211; - Migrate Anko build to Gradle. ### Anko 0.9 *(2016-06-07)* - Update to Kotlin 1.0.2 and IDEA 2016.1 #161 #177; - Support styles in DSL #16 #143; - Add KDoc comments for most of Anko utilities #168; - Rename `async()` to `doAsync()`, `onUiThread()` to `runOnUiThread()` for `Fragment` and `Context`; - Add `AnkoAsyncContext.onComplete()` #181; - `uiThread()` now returns `false` if code was not executed; - Ability to add an exception handler to `doAsync()` #182; - Add `newTask` parameter to `browse()` #186; - Add `sendSMS()` #171; - Add `makeStyle()` #132; - Add `Activity.contentView` property #157; - Add `horizontalProgressBar()` #23; - Add `doFromSdk()` and `doIfSdk()` #118; - Add `alignStart()` and `alignEnd()` to `RelativeLayout.LayoutParams` extensions; - `AlertDialogBuilder`: make the `dialog` property public #140; - Add `okButton()`, `yesButton()`, `cancelButton()`, `noButton()` to `AlertDialogBuilder`; - Add nullable values to SQLite helpers #154; - Add `editText()` with input constraints #25; - Add `attempt()` #182; - Change semantics of `Intent.clearTask()` and similar functions, now add flags, not set (replace old) #173; - Rename `forEachReversed` to `forEachReversedByIndex()`; - Rename `style()` to `applyRecursively()`; - Allow the database to be pluggable for query builders #187; - Fix `NOT_NULL` SQL type modifier #175; - Fix `startActivityForResult` called on wrong object (for Fragments) #76; - Fix `include` doesn't set LayoutParams from the XML #149; - `View.backgroundDrawable` is nullable now #169; - `classParser` has always not accessible constructor #136 #145. ### Anko 0.8.3 *(2016-03-02)* Built for Kotlin 1.0. * Remove deprecated `android.support.v4.Fragment.addView()` function. ### Anko 0.8.2 *(2016-02-04)* Built for Kotlin 1.0 RC. * `forEachChild()`, `forEachChildWithIndex()`, `firstChild()`, `firstChildOrNull()` are inlined now [#134](https://github.com/Kotlin/anko/pull/134); * `Int.withAlpha` [#125](https://github.com/Kotlin/anko/pull/125); * `ContextWrapper` is now supported by `AnkoContext`; * Anko library size and method count was slightly reduced. ### Anko 0.8.1 *(2015-12-09)* Built for Koltin Beta 3 (1.0.0-beta-3595). * SQLite helpers are moved to `anko-sqlite` artifact; * Fixed "Implicit setContentView in onCreate doesn't work in 0.8" [#114](https://github.com/Kotlin/anko/issues/114); * Fixed "Anko DSL Preview plugin 0.8 crashes" [#115](https://github.com/Kotlin/anko/issues/115); * Add intention: `0xffefefef.toInt()` → `0xef.gray.opaque`; * Add `forEachChild()`, `firstChild()`, `firstChildOrNull()` helpers. ### Anko 0.8 *(2015-12-01)* Built for Kotlin Beta 2 (1.0.0-beta-2423). * `AnkoComponent` interface for writing reusable components; * New DSL preview plugin: much more fast and stable :rocket:; * Add `TextView.gravity` [#96](https://github.com/JetBrains/anko/issues/96) and `ImageView.imageResource` [#102](https://github.com/JetBrains/anko/issues/102) properties; * `Cancel` is the default negative button name [#112](https://github.com/JetBrains/anko/issues/112); * Fix `AnkoLogger.wtf`; * Remove deprecated `__dslAddView` functions. ### Anko 0.7.3 *(2015-11-02)* Built for Kotlin **Beta Candidate** (`1.0.0-beta-1103`). ### Anko 0.7.2 *(2015-10-22)* Built for Kotlin **Beta Candidate**. ### Anko 0.7.1 *(2015-10-01)* Built for Kotlin M14 (0.14.449). * [#86](https://github.com/JetBrains/anko/pull/86) New: Allow getting MenuItems as a Sequence. * New: Added `findOptional` for `View`, `Activity` and `Fragment`. * Fix: An exception in DSL Preview plugin in Android Studio 1.4. ### Anko 0.7 *(2015-09-17)* Built for Kotlin M13 (0.13.1513). * Anko is now split to several components: * `anko-common` contains some basic helpers (such as `async`, `toast` or SQLite parsers). Does not contain any of view DSL). * `anko-sdk15` (also `19`, `21`, `23`) contains DSL bindings for the corresponding Android SDK version. * `anko-support-v4`, `anko-appcompat-v7` and others - additional DSL bindings for the Android support library widgets. * [#78](https://github.com/JetBrains/anko/issues/78) Changed `async` logic. * Most of extension properties for Views are removed because Kotlin now supports this seamlessly. * [#74](https://github.com/JetBrains/anko/issues/74) New: Ability to iterate children views lazily using sequences. * [#77](https://github.com/JetBrains/anko/issues/77) New: Extension functions for the optimized Android collections and arrays. * `layoutParams` property is renamed to `lparams` (due to the clash with `View.getLayoutParams`). ### Anko 0.6.3 *(2015-07-10)* Built for Kotlin M12.1 (0.12.613). * New: Tinted (appcompat) widgets support. * Deprecated extension properties for `RSSurfaceView`, `RSTextureView`, `WebView` are removed. * Intentions for `Toast.makeText(...).show()` and `findViewById()` in IDEA plugin. * [#54](https://github.com/JetBrains/anko/issues/54) Fix: LayoutParams resolving for some widgets. * [#60](https://github.com/JetBrains/anko/issues/60) Support more types in `intentFor`. * [#65](https://github.com/JetBrains/anko/issues/65) Fix: `AnkoLogger` can't now be used as a delegate. * Fix: `InterfaceWorkarounds` fields. * DSL Preview plugin is updated to Robolectric 3.0 rc3. * DSL generator refactoring. ### Anko 0.6.2 *(2015-05-29)* Built for Kotlin M12 (0.12.200). * Sensible listener argument names. * Some listener arguments and properties are now not-null. * New: Added `bundleOf` function. * New: Added `getBuilder` in `AlertDialogBuilder`. * [#42](https://github.com/JetBrains/anko/pull/42) New: Added `Context.startService` extension. * [#46](https://github.com/JetBrains/anko/pull/46) Fix: `IllegalArgumentException` in `AnkoLogger`. * [#44](https://github.com/JetBrains/anko/pull/44) Fix: Wrong return type for `include`. * [#42](https://github.com/JetBrains/anko/pull/42) Fix: `INTEGER` `SqlType` instead of `INT`. * [#31](https://github.com/JetBrains/anko/issues/31) Fix: Added `withArguments` for `android.support.v4.Fragment`. * [#45](https://github.com/JetBrains/anko/issues/45) Fix: `SingleColumnParser` and `ScalarColumnParser`. * [#38](https://github.com/JetBrains/anko/issues/38) Fix: `SQLiteDatabase.dropTable` signature. ### Anko 0.6.1 *(2015-05-06)* Built for Kotlin M11 (0.11.91.4). * [#30](https://github.com/JetBrains/anko/issues/30) Fix: Arguments in `intentFor`. * [#29](https://github.com/JetBrains/anko/issues/29) New: `android.support.v4.app.Fragment.withArguments` function. * [#26](https://github.com/JetBrains/anko/issues/26) New: More extension properties (including `emptyView` for `AdapterView`). * [#21](https://github.com/JetBrains/anko/issues/21) Fix: Supported String resources with `progressDialog` and `indeterminateProgressDialog`. ### Anko 0.6 *(2015-04-29)* Built for Kotlin M11 (0.11.91.2). * **Breaking:** package name change (kotlinx.android.anko → org.jetbrains.anko). * **Breaking:** [new syntax](https://github.com/JetBrains/anko#listeners) for multi-method listeners. * New: Supported Configuration qualifiers. * New: Custom views creation. * New: Supported `appcompat.v7` views and properties. * Top-level DSL functions for simple views are removed. * New: `startActivityForResult`, `dimen` extension functions. * New: `uiThread` property for `Context` and `Fragment`. ### Anko 0.5 *(2015-04-02)* Built for Koltin M11 (0.11.91.1). * Rebranding: Koan → Anko! :sparkles: * **Preview plugin** is available for IntelliJ IDEA and Android Studio. ================================================ FILE: GOODBYE.md ================================================ # Discontinuing Anko Over the last few months, we have received quite a few questions from our users regarding the future of Anko. So today, we are going to make things clear and officially deprecate the library. ## Why are you deprecating Anko? Anko was born as a type-safe DSL for building Android layouts. It not only allowed creating layouts in a type-safe way, but it made the layouts more adaptable, dynamic, reusable, and also performant, as there was no need for expensive layout inflation. During the evolution of Anko, it became clear that not only the layout part of the Android framework could benefit from providing Kotlin extensions. That is why we created Anko Commons, a toolbox of utility functions and classes for different parts of the Android framework. While Anko was quite popular among Kotlin users, we have to admit that the experience was not 100% perfect. Until recently, Android View APIs were highly optimized for inflation, and sometimes it wasn't possible to set some of the attributes programmatically. As a result, the DSL had to rely on hacks or workarounds. Also, it was non-trivial to emulate the reflective approach of widget loading needed for supporting AppCompat. We didn't have enough resources to fix all corner cases in a timely manner. However, things have changed substantially during the last few years. Google officially supported Kotlin, and later even made Kotlin the preferred language for Android application development. Thanks to JetPack, an extensive set of libraries, the rough edges of the SDK were smoothed over. Anko is a successful project, and it has played its role in establishing a better Android developer experience with Kotlin. However, there are modern alternatives today, and we feel it's time to say goodbye to Anko. ## What should I use instead of Anko? ### Layout DSL - Jetpack Compose. A reactive View DSL for Kotlin, backed by Google. - Splitties – [Views DSL](https://github.com/LouisCAD/Splitties/tree/master/modules/views-dsl). An extensible View DSL which resembles Anko. ### Generic utilities - [Android KTX](https://developer.android.com/kotlin/ktx). A set of Kotlin extensions for different purposes, backed by Google. - [Splitties](https://github.com/LouisCAD/Splitties). A lot of micro-libraries for all occasions. ### SQLite helpers - [Room](https://developer.android.com/topic/libraries/architecture/room). An annotation-based framework for SQLite database access, backed by Google. - [SQLDelight](https://github.com/cashapp/sqldelight) A type-safe API generator for SQL queries. * * * We would like to thank you for your support throughout these years. If you have any questions, please contact us on Slack or via the forum. You can find the links on our [community overview](https://kotlinlang.org/community/) page. ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ [![obsolete JetBrains project](https://jb.gg/badges/obsolete.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![Download](https://api.bintray.com/packages/jetbrains/anko/anko/images/download.svg) ](https://bintray.com/jetbrains/anko/anko/_latestVersion) [![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) Anko logo :warning: Anko is deprecated. Please see [this page](/GOODBYE.md) for more information. * * * Anko is a [Kotlin](https://www.kotlinlang.org/) library which makes Android application development faster and easier. It makes your code clean and easy to read, and lets you forget about rough edges of the Android SDK for Java. Anko consists of several parts: * *Anko Commons*: a lightweight library full of helpers for intents, dialogs, logging and so on; * *Anko Layouts*: a fast and type-safe way to write dynamic Android layouts; * *Anko SQLite*: a query DSL and parser collection for Android SQLite; * *Anko Coroutines*: utilities based on the [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) library. ## Anko Commons *Anko Commons* is a "toolbox" for Kotlin Android developer. The library contains a lot of helpers for Android SDK, including, but not limited to: * Intents ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Commons-–-Intents)); * Dialogs and toasts ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Commons-–-Dialogs)); * Logging ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Commons-–-Logging)); * Resources and dimensions ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Commons-–-Misc)). ## Anko Layouts ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Layouts)) *Anko Layouts* is a DSL for writing dynamic Android layouts. Here is a simple UI written with Anko DSL: ```kotlin verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } ``` The code above creates a button inside a `LinearLayout` and attaches an `OnClickListener` to that button. Moreover, `onClick` accepts a [`suspend` lambda](https://kotlinlang.org/docs/reference/coroutines.html), so you can write your asynchronous code right inside the listener! Note that this is the complete layout code. No XML is required! Anko has a [DSL for ConstraintLayout](https://github.com/Kotlin/anko/wiki/ConstraintLayout) since v0.10.4 Hello world There is also a [plugin](https://github.com/Kotlin/anko/wiki/Anko-Layouts#anko-support-plugin) for Android Studio that supports previewing Anko DSL layouts. ## Anko SQLite ([wiki](https://github.com/Kotlin/anko/wiki/Anko-SQLite)) Have you ever been tired of parsing SQLite query results using Android cursors? *Anko SQLite* provides lots of helpers to simplify working with SQLite databases. For example, here is how you can fetch the list of users with a particular name: ```kotlin fun getUsers(db: ManagedSQLiteOpenHelper): List = db.use { db.select("Users") .whereSimple("family_name = ?", "John") .doExec() .parseList(UserParser) } ``` ## Anko Coroutines ([wiki](https://github.com/Kotlin/anko/wiki/Anko-Coroutines)) *Anko Coroutines* is based on the [`kotlinx.coroutines`](https://github.com/kotlin/kotlinx.coroutines) library and provides: * [`bg()`](https://github.com/Kotlin/anko/wiki/Anko-Coroutines#bg) function that executes your code in a common pool. * [`asReference()`](https://github.com/Kotlin/anko/wiki/Anko-Coroutines#asreference) function which creates a weak reference wrapper. By default, a coroutine holds references to captured objects until it is finished or canceled. If your asynchronous framework does not support cancellation, the values you use inside the asynchronous block can be leaked. `asReference()` protects you from this. ## Using Anko ### Gradle-based project Anko has a meta-dependency which plugs in all available features (including Commons, Layouts, SQLite) into your project at once: ```gradle dependencies { implementation "org.jetbrains.anko:anko:$anko_version" } ``` Make sure that you have the ```$anko_version``` settled in your gradle file at the project level: ``` ext.anko_version='0.10.8' ``` If you only need some of the features, you can reference any of Anko's parts: ```gradle dependencies { // Anko Commons implementation "org.jetbrains.anko:anko-commons:$anko_version" // Anko Layouts implementation "org.jetbrains.anko:anko-sdk25:$anko_version" // sdk15, sdk19, sdk21, sdk23 are also available implementation "org.jetbrains.anko:anko-appcompat-v7:$anko_version" // Coroutine listeners for Anko Layouts implementation "org.jetbrains.anko:anko-sdk25-coroutines:$anko_version" implementation "org.jetbrains.anko:anko-appcompat-v7-coroutines:$anko_version" // Anko SQLite implementation "org.jetbrains.anko:anko-sqlite:$anko_version" } ``` There are also a number of artifacts for the Android support libraries: ```gradle dependencies { // Appcompat-v7 (only Anko Commons) implementation "org.jetbrains.anko:anko-appcompat-v7-commons:$anko_version" // Appcompat-v7 (Anko Layouts) implementation "org.jetbrains.anko:anko-appcompat-v7:$anko_version" implementation "org.jetbrains.anko:anko-coroutines:$anko_version" // CardView-v7 implementation "org.jetbrains.anko:anko-cardview-v7:$anko_version" // Design implementation "org.jetbrains.anko:anko-design:$anko_version" implementation "org.jetbrains.anko:anko-design-coroutines:$anko_version" // GridLayout-v7 implementation "org.jetbrains.anko:anko-gridlayout-v7:$anko_version" // Percent implementation "org.jetbrains.anko:anko-percent:$anko_version" // RecyclerView-v7 implementation "org.jetbrains.anko:anko-recyclerview-v7:$anko_version" implementation "org.jetbrains.anko:anko-recyclerview-v7-coroutines:$anko_version" // Support-v4 (only Anko Commons) implementation "org.jetbrains.anko:anko-support-v4-commons:$anko_version" // Support-v4 (Anko Layouts) implementation "org.jetbrains.anko:anko-support-v4:$anko_version" // ConstraintLayout implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version" } ``` There is an [example project](https://github.com/kotlin/anko-example) showing how to include Anko library into your Android Gradle project. ### IntelliJ IDEA project If your project is not based on Gradle, just attach the required JARs from the [jcenter repository](https://jcenter.bintray.com/org/jetbrains/anko/) as the library dependencies and that's it. ## Contributing The best way to submit a patch is to send us a [pull request](https://help.github.com/articles/about-pull-requests/). Before submitting the pull request, make sure all existing tests are passing, and add the new test if it is required. If you want to add new functionality, please file a new *proposal* issue first to make sure that it is not in progress already. If you have any questions, feel free to create a *question* issue. Instructions for building Anko are available in the [Wiki](https://github.com/Kotlin/anko/wiki/Building-Anko). ================================================ FILE: anko/idea-plugin/attrs/build.gradle ================================================ apply plugin: 'kotlin' sourceSets { main { java.srcDirs = ['src'] kotlin.srcDirs = ['src'] } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile project(':ide:plugin-classpath') } ================================================ FILE: anko/idea-plugin/attrs/src/org/jetbrains/kotlin/android/Attrs.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.attrs import java.io.File data class NameValue( val name: String = "", val value: String = "") data class Attr( val name: String = "", val format: List = emptyList(), val flags: List? = null, val enum: List? = null) val NoAttr: Attr = Attr() data class Styleable( val name: String = "", val attrs: List = emptyList()) data class Attrs( val free: List = emptyList(), val styleables: Map = emptyMap()) fun readResource(filename: String): String { return Attrs::class.java.classLoader.getResourceAsStream(filename)?.reader()?.readText() ?: File(filename).readText() } ================================================ FILE: anko/idea-plugin/build.gradle ================================================ subprojects { apply plugin: 'kotlin' sourceSets { main { java.srcDirs = ['src', 'resources'] kotlin.srcDirs = ['src'] resources.srcDirs = ['resources'] } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } } ================================================ FILE: anko/idea-plugin/idea-runner/build.gradle ================================================ apply plugin: 'java' dependencies { compile fileTree(dir: new File(project.rootDir, "ideaSDK/lib"), include: ['*.jar']) } ================================================ FILE: anko/idea-plugin/intentions/build.gradle ================================================ apply plugin: 'kotlin' sourceSets { main { java.srcDirs = ['src'] kotlin.srcDirs = ['src'] } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile project(':ide:plugin-classpath') } ================================================ FILE: anko/idea-plugin/intentions/src/org/jetbrains/anko/idea/intentions/AnkoIntention.kt ================================================ package org.jetbrains.anko.idea.intentions import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.intentions.SelfTargetingIntention import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass import org.jetbrains.kotlin.types.lowerIfFlexible abstract class AnkoIntention( elementType: Class, text: String, familyName: String = text ) : SelfTargetingIntention(elementType, text, familyName) { final override fun isApplicableTo(element: TElement, caretOffset: Int): Boolean { val file = element.containingFile as? KtFile ?: return false val moduleDescriptor = file.findModuleDescriptor() moduleDescriptor.resolveTopLevelClass(ANKO_INTERNALS_FQNAME, NoLookupLocation.FROM_IDE) ?: return false return isApplicable(element, caretOffset) } abstract fun isApplicable(element: TElement, caretOffset: Int): Boolean private fun isTypeOf(descriptor: ClassifierDescriptor, vararg fqName: String): Boolean { val resolvedName = DescriptorUtils.getFqNameSafe(descriptor).asString() return fqName.any { it == resolvedName } } protected fun KtCallExpression.isValueParameterTypeOf( parameterIndex: Int, resolvedCall: ResolvedCall<*>?, vararg fqName: String ): Boolean { val ctxArgumentDescriptor = (resolvedCall ?: getResolvedCall(analyze()))?.resultingDescriptor ?.valueParameters?.get(parameterIndex)?.type?.lowerIfFlexible() ?.constructor?.declarationDescriptor ?: return false return isTypeOf(ctxArgumentDescriptor, *fqName) } protected fun KtCallExpression.isReceiverParameterTypeOf( resolvedCall: ResolvedCall<*>?, vararg fqName: String ): Boolean { val receiverDescriptor = (resolvedCall ?: getResolvedCall(analyze()))?.resultingDescriptor ?.dispatchReceiverParameter?.type?.lowerIfFlexible() ?.constructor?.declarationDescriptor ?: return false return isTypeOf(receiverDescriptor, *fqName) } protected val KtDotQualifiedExpression.receiver: KtExpression? get() = receiverExpression protected val KtDotQualifiedExpression.selector: KtExpression? get() = selectorExpression protected val KtBinaryExpressionWithTypeRHS.operation: KtSimpleNameExpression get() = operationReference protected inline fun PsiElement?.require(name: String? = null, sub: E.() -> Boolean): Boolean { return require(name) && (this as E).sub() } inline fun require(cond: Boolean, sub: () -> Boolean): Boolean { if (cond) sub() return cond } protected inline fun PsiElement?.require(name: String? = null): Boolean { if (this !is E) return false if (name != null && name != this.text) return false return true } protected inline fun PsiElement?.requireCall( functionName: String? = null, argCount: Int? = null, sub: KtCallExpression.() -> Boolean ): Boolean { return requireCall(functionName, argCount) && (this as KtCallExpression).sub() } @Suppress("NOTHING_TO_INLINE") protected inline fun PsiElement?.requireCall(functionName: String? = null, argCount: Int? = null): Boolean { if (this !is KtCallExpression) return false if (functionName != null && functionName != calleeExpression?.text) return false if (argCount != null && argCount != valueArguments.size) return false return true } abstract fun replaceWith(element: TElement, psiFactory: KtPsiFactory): NewElement? final override fun applyTo(element: TElement, editor: Editor?) { val project = editor?.project ?: return val file = element.containingFile as? KtFile ?: return val moduleDescriptor = file.findModuleDescriptor() val resolutionFacade = file.getResolutionFacade() val psiFactory = KtPsiFactory(project) val (newElement, fqNamesToImport) = replaceWith(element, psiFactory) ?: return val newExpression = newElement ImportInsertHelper.getInstance(project).apply { fqNamesToImport .flatMap { val fqName = FqName(if ('.' in it) it else "$ANKO_PACKAGE$it") resolutionFacade.resolveImportReference(moduleDescriptor, fqName) } .forEach { if (it.importableFqName != null) importDescriptor(file, it) } } element.replace(newExpression) } private companion object { private val ANKO_PACKAGE = "org.jetbrains.anko." private val ANKO_INTERNALS_FQNAME = FqName("org.jetbrains.anko.internals.AnkoInternals") } } object FqNames { val ACTIVITY_FQNAME = "android.app.Activity" val CONTEXT_FQNAME = "android.content.Context" val VIEW_FQNAME = "android.view.View" } class NewElement(val element: KtExpression, vararg val newNames: String) { operator fun component1() = element operator fun component2() = newNames //fqName or name in anko package } abstract class A { open fun test(a: CharSequence) {} } class B : A() { override fun test(a: CharSequence) {} } ================================================ FILE: anko/idea-plugin/intentions/src/org/jetbrains/anko/idea/intentions/FindViewByIdIntention.kt ================================================ package org.jetbrains.anko.idea.intentions import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall class FindViewByIdIntention : AnkoIntention( KtExpression::class.java, "Simplify findViewById() with Anko" ) { override fun isApplicable(element: KtExpression, caretOffset: Int): Boolean { fun PsiElement?.requireFindViewByIdCall() = requireCall(FIND_VIEW_BY_ID, 1) { val resolvedCall = getResolvedCall(analyze()) isValueParameterTypeOf(0, resolvedCall, "kotlin.Int") && isReceiverParameterTypeOf(resolvedCall, FqNames.ACTIVITY_FQNAME, FqNames.VIEW_FQNAME) } return element.require() { operation.require("as") && (left.requireFindViewByIdCall() || left.require { selector.requireFindViewByIdCall() }) } } override fun replaceWith(element: KtExpression, psiFactory: KtPsiFactory): NewElement? { fun KtCallExpression.createElement(type: String, receiver: String? = null): NewElement { val id = valueArguments[0].text val receiverWithDot = if (receiver == null) "" else "$receiver." val newExpression = psiFactory.createExpression("${receiverWithDot}find<$type>($id)") return NewElement(newExpression, "find") } element.require() { val type = right?.text ?: return null left.requireCall(FIND_VIEW_BY_ID) { return createElement(type) } left.require { selector.requireCall(FIND_VIEW_BY_ID) { return createElement(type, receiver?.text) } } } return null } private companion object { val FIND_VIEW_BY_ID = "findViewById" } } ================================================ FILE: anko/idea-plugin/intentions/src/org/jetbrains/anko/idea/intentions/ReplaceColorGrayOpaqueIntention.kt ================================================ package org.jetbrains.anko.idea.intentions import org.jetbrains.kotlin.psi.* class ReplaceColorGrayOpaqueIntention : AnkoIntention( KtExpression::class.java, "Simplify color numeric literal with Anko" ) { override fun isApplicable(element: KtExpression, caretOffset: Int): Boolean { return element.require { receiver.require { text.matches(COLOR_REGEX) } && selector.requireCall("toInt", 0) } || element.require { text.matches(COLOR_REGEX) && (this != (parent as? KtDotQualifiedExpression)?.receiver) } } override fun replaceWith(element: KtExpression, psiFactory: KtPsiFactory): NewElement? { fun createNewElement(colorText: String): NewElement? { val color = ARGB(colorText) if (color.isOpaque) { return if (color.isTransparent) { NewElement(psiFactory.createExpression("Color.TRANSPARENT"), ANDROID_GRAPHICS_COLOR) } else if (color.color in COLORS) { NewElement(psiFactory.createExpression("Color.${COLORS[color.color]}"), ANDROID_GRAPHICS_COLOR) } else if (color.isGray) { NewElement(psiFactory.createExpression(color.getGrayOpaque()), GRAY, OPAQUE) } else { return NewElement(psiFactory.createExpression(color.getOpaque()), OPAQUE) } } return null } element.require { receiver.require { text.matches(COLOR_REGEX) } && selector.requireCall("toInt", 0) { return createNewElement(receiver!!.text) } } || element.require { require(text.matches(COLOR_REGEX) && (this != (parent as? KtDotQualifiedExpression)?.receiver)) { return createNewElement(text) } } return null } private data class ARGB(val color: String, val a: String, val r: String, val g: String, val b: String) { @JvmField val A = a.toUpperCase() @JvmField val R = r.toUpperCase() @JvmField val G = g.toUpperCase() @JvmField val B = b.toUpperCase() constructor(color: String) : this(color.drop(2).toUpperCase(), color.substring(2, 4), color.substring(4, 6), color.substring(6, 8), color.substring(8, 10)) val isGray: Boolean get() = R == G && G == B val isTransparent: Boolean get() = A == "00" val isOpaque: Boolean get() = A == "FF" fun getGrayOpaque() = "0x$r.gray.opaque" fun getOpaque() = "0x$r$g$b.opaque" } private companion object { val COLOR_REGEX = "^0x[0-9A-Fa-f]{8}$".toRegex() val GRAY = "gray" val OPAQUE = "opaque" val ANDROID_GRAPHICS_COLOR = "android.graphics.Color" val COLORS = mapOf( "FFFFFFFF" to "WHITE", "FF000000" to "BLACK", "FF888888" to "GRAY", "FFCCCCCC" to "LTGRAY", "FFFF0000" to "RED", "FF00FF00" to "GREEN", "FF0000FF" to "BLUE", "FFFFFF00" to "YELLOW", "FF00FFFF" to "CYAN", "FFFF00FF" to "MAGENTA") } } ================================================ FILE: anko/idea-plugin/intentions/src/org/jetbrains/anko/idea/intentions/ToastMakeTextShowIntention.kt ================================================ /* * Copyright 2010-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.anko.idea.intentions import org.jetbrains.kotlin.psi.* class ToastMakeTextShowIntention : AnkoIntention( KtExpression::class.java, "Simplify Toast.makeText().show() with Anko" ) { override fun isApplicable(element: KtExpression, caretOffset: Int): Boolean { return element.require { receiver.require { receiver.require("Toast") && selector.requireCall("makeText", 3) { isLongToast() != null && isValueParameterTypeOf(0, null, FqNames.CONTEXT_FQNAME) } } && selector.requireCall("show", 0) } } private fun KtCallExpression.isLongToast(): Boolean? { return when (valueArguments[2].text) { "Toast.LENGTH_SHORT", "LENGTH_SHORT" -> false "Toast.LENGTH_LONG", "LENGTH_LONG" -> true else -> null } } override fun replaceWith(element: KtExpression, psiFactory: KtPsiFactory): NewElement? { element.require { receiver.require { selector.requireCall("makeText") { val args = valueArguments val ctxArg = args[0].text val textArg = args[1].text val funName = if (isLongToast()!!) "longToast" else "toast" val receiver = if (ctxArg == "this") "" else "$ctxArg." val newExpression = psiFactory.createExpression("$receiver$funName($textArg)") return NewElement(newExpression, funName) } } } return null } } ================================================ FILE: anko/idea-plugin/plugin-classpath/build.gradle ================================================ apply plugin: 'java' dependencies { compile fileTree(dir: new File(project.rootDir, "ideaSDK/lib"), include: ['*.jar']) compile fileTree(dir: new File(project.rootDir, "ideaSDK/plugins/android/lib"), include: ['*.jar']) compile fileTree(dir: new File(project.rootDir, "ideaSDK/plugins/Kotlin/lib"), include: ['kotlin-plugin.jar']) } ================================================ FILE: anko/idea-plugin/preview/build.gradle ================================================ apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'kotlin' sourceSets { main { java.srcDirs = ['src'] kotlin.srcDirs = ['src'] } } configurations { shadow compile.extendsFrom shadow } dependencies { compile project(':ide:plugin-classpath') compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" shadow "org.jetbrains.kotlinx:kotlinx.dom:$kotlinx_dom_version" shadow(project(':ide:attrs')) { transitive = false } shadow(project(':ide:intentions')) { transitive = false } shadow(project(':ide:xml-converter')) { transitive = false } } shadowJar { configurations = [project.configurations.shadow] } ================================================ FILE: anko/idea-plugin/preview/resources/META-INF/plugin.xml ================================================ org.jetbrains.kotlin.android.dsl Anko Support Anko Android library support. 0.10.8 JetBrains s.r.o. org.jetbrains.kotlin org.jetbrains.android org.jetbrains.anko.idea.intentions.ToastMakeTextShowIntention Anko org.jetbrains.anko.idea.intentions.FindViewByIdIntention Anko org.jetbrains.anko.idea.intentions.ReplaceColorGrayOpaqueIntention Anko org.jetbrains.kotlin.android.dslpreview.AnkoNlPreviewManager ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/FindViewByIdIntention/after.kt.template ================================================ find(R.id.name) ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/FindViewByIdIntention/before.kt.template ================================================ findViewById(R.id.name) as TextView ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/FindViewByIdIntention/description.html ================================================ This intention replaces 'findViewById() as T' method call with 'find' that is available in Anko. ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ReplaceColorGrayOpaqueIntention/after.kt.template ================================================ 0xCC.gray.opaque ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ReplaceColorGrayOpaqueIntention/before.kt.template ================================================ 0xFFCCCCCC.toInt() ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ReplaceColorGrayOpaqueIntention/description.html ================================================ This intention replaces numeric literals representing Android colors with ones that use Anko `gray` and `opaque` extension properties. ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ToastMakeTextShowIntention/after.kt.template ================================================ toast("Message") ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ToastMakeTextShowIntention/before.kt.template ================================================ Toast.makeText(this, "Message", Toast.LENGTH_SHORT).show() ================================================ FILE: anko/idea-plugin/preview/resources/intentionDescriptions/ToastMakeTextShowIntention/description.html ================================================ This intention replaces 'Toast.makeText(ctx, text, length).show()' method call with 'toast(text)' or 'longToast(text)' that is available in Anko. ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/AnkoNlPreviewManager.kt ================================================ package org.jetbrains.kotlin.android.dslpreview import com.android.tools.idea.common.model.NlModel import com.android.tools.idea.gradle.project.GradleProjectInfo import com.android.tools.idea.gradle.project.build.invoker.GradleBuildInvoker import com.android.tools.idea.project.AndroidProjectInfo import com.android.tools.idea.uibuilder.editor.NlPreviewForm import com.android.tools.idea.uibuilder.editor.NlPreviewManager import com.intellij.ide.highlighter.XmlFileType import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.fileEditor.TextEditor import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleUtilCore import com.intellij.openapi.project.Project import com.intellij.openapi.ui.ComboBox import com.intellij.openapi.util.Computable import com.intellij.openapi.wm.ToolWindow import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiFileFactory import com.intellij.psi.xml.XmlFile import com.intellij.util.Alarm import org.jetbrains.android.uipreview.ViewLoaderExtension import org.jetbrains.kotlin.idea.util.InfinitePeriodicalTask import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.awt.BorderLayout import java.awt.event.ItemEvent import javax.swing.ComboBoxModel import javax.swing.DefaultComboBoxModel import javax.swing.JPanel class AnkoNlPreviewManager( project: Project, fileEditorManager: FileEditorManager? ) : NlPreviewManager(project, fileEditorManager), Disposable { internal val classResolver = DslPreviewClassResolver(project) internal var myActivityListModel: DefaultComboBoxModel = DefaultComboBoxModel() private val viewLoaderExtension by lazy { val area = Extensions.getArea(project) if (area.hasExtensionPoint(ViewLoaderExtension.EP_NAME.name)) { area.getExtensionPoint(ViewLoaderExtension.EP_NAME).extensions.firstIsInstanceOrNull() } else { null } } init { ApplicationManager.getApplication().invokeLater { val task = Computable { UpdateActivityNameTask(this) } InfinitePeriodicalTask(1000, Alarm.ThreadToUse.SWING_THREAD, this@AnkoNlPreviewManager, task).start() } GradleBuildInvoker.getInstance(project).add { ApplicationManager.getApplication().invokeLater { refresh() } } } override fun getToolWindowId() = "Anko Layout Preview" override fun getComponentName() = "AnkoNlPreviewManager" public override fun getToolWindow() = super.getToolWindow() override fun getBoundXmlFile(file: PsiFile?): XmlFile? { if (file is XmlFile) { return file } else if (file !is KtFile) { return null } val ankoPreviewFrom = previewForm as? AnkoPreviewForm ?: return null val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return null return if (refresh() || ankoPreviewFrom.xmlFile == null) { generateStubXmlFile(module, file).also { ankoPreviewFrom.xmlFile = it } } else { ankoPreviewFrom.xmlFile } } private fun getActiveTextEditor(): TextEditor? { if (!ApplicationManager.getApplication().isReadAccessAllowed) { return ApplicationManager.getApplication().runReadAction(Computable { getActiveTextEditor() }) } ApplicationManager.getApplication().assertReadAccessAllowed() val fileEditors = fileEditorManager?.selectedEditors if (fileEditors != null && fileEditors.isNotEmpty() && fileEditors[0] is TextEditor) { val textEditor = fileEditors[0] as TextEditor if (isApplicableEditor(textEditor, null)) { return textEditor } } return null } private fun generateStubXmlFile(module: Module, originalFile: KtFile): LayoutPsiFile { val filename = "anko_preview.xml" val content = """ <__anko.preview.View xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"/>""" val psiFile = PsiFileFactory.getInstance(project).createFileFromText(filename, XmlFileType.INSTANCE, content) return LayoutPsiFile(psiFile as XmlFile, originalFile, module) } private fun refresh(): Boolean { val toolWindow: ToolWindow = toolWindow ?: return false if (!toolWindow.isVisible) return false val viewLoaderExtension = this.viewLoaderExtension ?: return false val description = myActivityListModel.selectedItem as? PreviewClassDescription ?: classResolver.getOnCursorPreviewClassDescription() if (description != null && viewLoaderExtension.description != description) { viewLoaderExtension.description = description return true } return false } override fun isApplicableEditor(textEditor: TextEditor, file: PsiFile?): Boolean { val psiFile = file ?: PsiDocumentManager.getInstance(project).getPsiFile(textEditor.editor.document) ?: return false if (!GradleProjectInfo.getInstance(project).isBuildWithGradle && !AndroidProjectInfo.getInstance(project).isLegacyIdeaAndroidProject) { return false } return psiFile is KtFile } private val fileEditorManager: FileEditorManager? get() = with(NlPreviewManager::class.java.getDeclaredField("myFileEditorManager")) { val oldAccessible = isAccessible try { isAccessible = true get(this@AnkoNlPreviewManager) as? FileEditorManager } finally { isAccessible = oldAccessible } } override fun initToolWindow() { super.initToolWindow() resolveAvailableClasses() } override fun createPreviewForm(): NlPreviewForm = AnkoPreviewForm(this) internal fun updatePreview() { getActiveTextEditor()?.let { notifyFileShown(it, true) } } fun resolveAvailableClasses() { val activityClasses = classResolver .getAncestors(DslPreviewClassResolver.ANKO_COMPONENT_CLASS_NAME) .filter { classResolver.isClassApplicableForPreview(it.ktClass) } with(myActivityListModel) { selectedItem = null removeAllElements() val items = activityClasses items.sortedBy { it.toString() }.forEach { addElement(it) } } } override fun isUseInteractiveSelector() = false override fun dispose() {} } class AnkoPreviewForm(private val ankoPreviewManager: AnkoNlPreviewManager) : NlPreviewForm(ankoPreviewManager) { var xmlFile: XmlFile? = null override fun setActiveModel(model: NlModel?) { super.setActiveModel(model) if (model != null) { (this.toolbarComponent as? JPanel)?.let { addLayoutComboBox(it) } } } private fun addLayoutComboBox(panel: JPanel) { if (panel.components.firstIsInstanceOrNull() != null) { return } val comboBox = PreviewCandidateComboBox(ankoPreviewManager.myActivityListModel) comboBox.addItemListener { itemEvent -> if (itemEvent.stateChange == ItemEvent.SELECTED) { ankoPreviewManager.updatePreview() } } panel.add(comboBox, BorderLayout.SOUTH) } } class PreviewCandidateComboBox(model: ComboBoxModel) : ComboBox(model) ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/AnkoViewLoaderExtension.kt ================================================ package org.jetbrains.kotlin.android.dslpreview import org.jetbrains.android.uipreview.ViewLoaderExtension import org.jetbrains.org.objectweb.asm.ClassWriter import org.jetbrains.org.objectweb.asm.Opcodes import java.net.URL import java.net.URLClassLoader class AnkoViewLoaderExtension : ViewLoaderExtension { internal var description: PreviewClassDescription? = null override fun loadClass(className: String, delegateClassLoader: ClassLoader): Class<*>? { val description = this.description if (className == "__anko.preview.View" && description != null) { val clazz = generateStubViewClass(delegateClassLoader, description) if (clazz != null) return clazz } return null } private fun generateStubViewClass(delegateClassLoader: ClassLoader, description: PreviewClassDescription): Class<*>? { val uiInternalName = description.internalName val viewFqName = "__anko.preview.View" val viewInternalName = viewFqName.replace('.', '/') val superClassInternalName = "android/widget/FrameLayout" val bytes = with (ClassWriter(0)) { visit(49, Opcodes.ACC_PUBLIC, viewInternalName, null, superClassInternalName, null) visitSource(null, null) fun visitConstructor(vararg params: String) { val signature = "(${params.joinToString("")})V" with (visitMethod(Opcodes.ACC_PUBLIC, "", signature, null, null)) { visitVarInsn(Opcodes.ALOAD, 0) params.forEachIndexed { i, param -> when (param) { "I" -> visitVarInsn(Opcodes.ILOAD, i + 1) else -> visitVarInsn(Opcodes.ALOAD, i + 1) } } visitMethodInsn(Opcodes.INVOKESPECIAL, superClassInternalName, "", signature) visitVarInsn(Opcodes.ALOAD, 0) visitMethodInsn(Opcodes.INVOKEVIRTUAL, viewInternalName, "init", "()V") visitInsn(Opcodes.RETURN) visitMaxs(1 + params.size /*max stack*/, 1 + params.size /*max locals*/) visitEnd() } } visitConstructor("Landroid/content/Context;") visitConstructor("Landroid/content/Context;", "Landroid/util/AttributeSet;") visitConstructor("Landroid/content/Context;", "Landroid/util/AttributeSet;", "I") /* private fun init() { addView(MainActivityUi().createView(AnkoContext.create(getContext()))) } */ with (visitMethod(Opcodes.ACC_PRIVATE, "init", "()V", null, null)) { visitVarInsn(Opcodes.ALOAD, 0) visitTypeInsn(Opcodes.NEW, uiInternalName) visitInsn(Opcodes.DUP) visitMethodInsn(Opcodes.INVOKESPECIAL, uiInternalName, "", "()V") visitFieldInsn(Opcodes.GETSTATIC, "org/jetbrains/anko/AnkoContext", "Companion", "Lorg/jetbrains/anko/AnkoContext" + '$' + "Companion;") visitVarInsn(Opcodes.ALOAD, 0) visitMethodInsn(Opcodes.INVOKEVIRTUAL, viewInternalName, "getContext", "()Landroid/content/Context;") visitInsn(Opcodes.ICONST_0) visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/jetbrains/anko/AnkoContext" + '$' + "Companion", "create", "(Landroid/content/Context;Z)Lorg/jetbrains/anko/AnkoContext;") visitMethodInsn(Opcodes.INVOKEVIRTUAL, uiInternalName, "createView", "(Lorg/jetbrains/anko/AnkoContext;)Landroid/view/View;") visitMethodInsn(Opcodes.INVOKEVIRTUAL, viewInternalName, "addView", "(Landroid/view/View;)V") visitInsn(Opcodes.RETURN) visitMaxs(5 /*max stack*/, 1 /*max locals*/) visitEnd() } visitEnd() toByteArray() } return loadClass(viewFqName, bytes, delegateClassLoader) } private fun loadClass(fqName: String, bytes: ByteArray, delegateClassLoader: ClassLoader): Class<*>? { class ByteClassLoader( urls: Array?, parent: ClassLoader?, private var extraClasses: MutableMap ) : URLClassLoader(urls, parent) { override fun findClass(name: String): Class<*>? { return extraClasses.remove(name)?.let { defineClass(name, it, 0, it.size) } ?: super.findClass(name) } } try { val classLoader = ByteClassLoader(emptyArray(), delegateClassLoader, hashMapOf(fqName to bytes)) return Class.forName(fqName, false, classLoader) } catch (e: Throwable) { return null } } } ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/DslPreviewClassResolver.kt ================================================ package org.jetbrains.kotlin.android.dslpreview import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.ex.EditorEx import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.IndexNotReadyException import com.intellij.openapi.project.Project import com.intellij.openapi.util.Computable import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.searches.ClassInheritorsSearch import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtConstructor import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.types.typeUtil.supertypes import java.util.* internal class DslPreviewClassResolver(private val project: Project) { private fun getKtClass(psiElement: PsiElement?): KtClass? { return if (psiElement is KtLightElement<*, *>) { getKtClass(psiElement.kotlinOrigin) } else if (psiElement is KtClass && !psiElement.isEnum() && !psiElement.isInterface() && !psiElement.isAnnotation() && !psiElement.isSealed()) { psiElement } else { val parent = psiElement?.parent ?: return null return getKtClass(parent) } } fun getOnCursorPreviewClassDescription(): PreviewClassDescription? { val editor = ApplicationManager.getApplication().runReadAction(Computable { FileEditorManager.getInstance(project).selectedTextEditor }) ?: return null val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.document) if (psiFile !is KtFile || editor !is EditorEx) return null val selectionStart = editor.caretModel.primaryCaret.selectionStart val psiElement = psiFile.findElementAt(selectionStart) ?: return null val cacheService = KotlinCacheService.getInstance(project) return resolveClassDescription(psiElement, cacheService) } fun getAncestors(baseClassName: String): Collection { if (DumbService.isDumb(project)) return emptyList() val baseClasses = JavaPsiFacade.getInstance(project) .findClasses(baseClassName, GlobalSearchScope.allScope(project)) if (baseClasses.isEmpty()) return emptyList() return try { val cacheService = KotlinCacheService.getInstance(project) val previewClasses = ArrayList(0) for (element in ClassInheritorsSearch.search(baseClasses[0]).findAll()) { resolveClassDescription(element, cacheService)?.let { previewClasses += it } } previewClasses } catch (e: IndexNotReadyException) { emptyList() } } private fun isZeroParameterConstructor(constructor: KtConstructor<*>?): Boolean { if (constructor == null) return false val parameters = constructor.getValueParameters() return parameters.isEmpty() || parameters.all { it.hasDefaultValue() } } fun isClassApplicableForPreview(clazz: KtClass): Boolean { val primaryConstructor = clazz.primaryConstructor val secondaryConstructors = clazz.secondaryConstructors return (primaryConstructor == null && secondaryConstructors.isEmpty()) || isZeroParameterConstructor(primaryConstructor) || secondaryConstructors.any(this::isZeroParameterConstructor) } fun resolveClassDescription(element: PsiElement, cacheService: KotlinCacheService): PreviewClassDescription? { if (DumbService.isDumb(element.project)) return null val ktClass = getKtClass(element) ?: return null if (!isClassApplicableForPreview(ktClass)) return null val resolveSession = cacheService.getResolutionFacade(listOf(ktClass)) .getFrontendService(ResolveSession::class.java) val classDescriptor = resolveSession.getClassDescriptor(ktClass, NoLookupLocation.FROM_IDE) if (!classDescriptor.defaultType.supertypes().any { val fqName = it.constructor.declarationDescriptor?.fqNameUnsafe?.asString() ?: "" fqName == ANKO_COMPONENT_CLASS_NAME }) { return null } val typeMapper = createTypeMapper(resolveSession.bindingContext) return PreviewClassDescription(ktClass, classDescriptor.fqNameSafe.asString(), typeMapper.mapType(classDescriptor).internalName) } companion object { val ANKO_COMPONENT_CLASS_NAME = "org.jetbrains.anko.AnkoComponent" private fun createTypeMapper(bindingContext: BindingContext): KotlinTypeMapper { // TODO: Add stable constructor to KotlinTypeMapper val typeMapperConstructor7 = KotlinTypeMapper::class.java.constructors.find { it.parameterCount == 7 } if (typeMapperConstructor7 != null) { if (typeMapperConstructor7.parameterTypes[4].isAssignableFrom(JvmTarget::class.java)) return typeMapperConstructor7 .newInstance( bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, "main", JvmTarget.DEFAULT, false, false) as KotlinTypeMapper else return typeMapperConstructor7 .newInstance( bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, "main", false, false, false) as KotlinTypeMapper } val typeMapperConstructor6 = KotlinTypeMapper::class.java.constructors.find { it.parameterCount == 6 } if (typeMapperConstructor6 != null) { return typeMapperConstructor6 .newInstance( bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, "main", false, false) as KotlinTypeMapper } return KotlinTypeMapper( bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, "main", false) } } } ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/LayoutPsiFile.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @file:Suppress("UNREACHABLE_CODE", "OverridingDeprecatedMember", "DEPRECATION") package org.jetbrains.kotlin.android.dslpreview import com.intellij.injected.editor.DocumentWindow import com.intellij.injected.editor.VirtualFileWindow import com.intellij.lang.ASTNode import com.intellij.lang.FileASTNode import com.intellij.lang.Language import com.intellij.navigation.ItemPresentation import com.intellij.openapi.Disposable import com.intellij.openapi.editor.Document import com.intellij.openapi.editor.RangeMarker import com.intellij.openapi.editor.event.DocumentListener import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.util.Iconable.IconFlags import com.intellij.openapi.util.Key import com.intellij.openapi.util.Segment import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.UserDataHolderBase import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.* import com.intellij.psi.impl.PsiDocumentManagerImpl import com.intellij.psi.impl.PsiManagerEx import com.intellij.psi.scope.PsiScopeProcessor import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiElementProcessor import com.intellij.psi.search.SearchScope import com.intellij.psi.xml.XmlFile import com.intellij.testFramework.LightVirtualFile import com.intellij.util.IncorrectOperationException import org.jetbrains.android.facet.AndroidFacet import org.jetbrains.android.resourceManagers.ModuleResourceManagers import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.psi.KtFile import java.beans.PropertyChangeListener import javax.swing.Icon /* Reason for these stubs: Android Preview checks that the xml file is placed inside "layout-*" directory. TODO: Implement some kind of stable api in Android plugin for this */ class LayoutPsiFile(private val myPsiFile: XmlFile, val originalFile: KtFile, module: Module) : XmlFile { private val myPsiDirectory: PsiDirectory = LayoutPsiDirectory(module) private val myViewProvider: FileViewProvider = object : FileViewProvider by myPsiFile.viewProvider { override fun getPsi(p0: Language): PsiFile = this@LayoutPsiFile } private val myVirtualFile: VirtualFile by lazy { LayoutLightVirtualFile(myPsiFile.name, myPsiFile.text).also { virtualFile -> (myPsiFile.manager as? PsiManagerEx)?.fileManager?.setViewProvider(virtualFile, myViewProvider) } } override fun getParent() = myPsiDirectory override fun getDocument() = myPsiFile.document override fun getRootTag() = myPsiFile.rootTag override fun getVirtualFile(): VirtualFile? = myVirtualFile override fun getContainingDirectory() = myPsiDirectory override fun getModificationStamp() = myPsiFile.modificationStamp override fun getOriginalFile() = this override fun getFileType() = myPsiFile.fileType override fun getViewProvider() = myViewProvider override fun getNode(): FileASTNode? = myPsiFile.node override fun getPsiRoots(): Array = myPsiFile.psiRoots override fun subtreeChanged() = myPsiFile.subtreeChanged() override fun isDirectory() = myPsiFile.isDirectory override fun getName() = myPsiFile.name override fun checkSetName(s: String) = myPsiFile.checkSetName(s) override fun setName(s: String): PsiElement = myPsiFile.setName(s) override fun getProject() = myPsiFile.project override fun getLanguage() = myPsiFile.language override fun getManager(): PsiManager? = myPsiFile.manager override fun getChildren(): Array = myPsiFile.children override fun getFirstChild(): PsiElement? = myPsiFile.firstChild override fun getLastChild(): PsiElement? = myPsiFile.lastChild override fun getNextSibling(): PsiElement? = myPsiFile.nextSibling override fun getPrevSibling(): PsiElement? = myPsiFile.prevSibling override fun getContainingFile(): PsiFile? = myPsiFile.containingFile override fun getTextRange(): TextRange? = myPsiFile.textRange override fun getStartOffsetInParent() = myPsiFile.startOffsetInParent override fun getTextLength() = myPsiFile.textLength override fun findElementAt(i: Int) = myPsiFile.findElementAt(i) override fun findReferenceAt(i: Int) = myPsiFile.findReferenceAt(i) override fun getTextOffset() = myPsiFile.textOffset override fun getText(): String? = myPsiFile.text override fun textToCharArray() = myPsiFile.textToCharArray() override fun getNavigationElement(): PsiElement? = myPsiFile.navigationElement override fun getOriginalElement(): PsiElement? = myPsiFile.originalElement override fun textMatches(charSequence: CharSequence) = myPsiFile.textMatches(charSequence) override fun textMatches(psiElement: PsiElement) = myPsiFile.textMatches(psiElement) override fun textContains(c: Char) = myPsiFile.textContains(c) override fun accept(psiElementVisitor: PsiElementVisitor) = myPsiFile.accept(psiElementVisitor) override fun acceptChildren(psiElementVisitor: PsiElementVisitor) = myPsiFile.acceptChildren(psiElementVisitor) override fun copy(): PsiElement? = myPsiFile.copy() override fun add(psiElement: PsiElement): PsiElement? = myPsiFile.add(psiElement) override fun processChildren(psiFileSystemItemPsiElementProcessor: PsiElementProcessor?): Boolean { return myPsiFile.processChildren(psiFileSystemItemPsiElementProcessor) } override fun addBefore(psiElement: PsiElement, psiElement2: PsiElement?): PsiElement? = myPsiFile.addBefore(psiElement, psiElement2) override fun addAfter(psiElement: PsiElement, psiElement2: PsiElement?): PsiElement? = myPsiFile.addAfter(psiElement, psiElement2) override fun checkAdd(psiElement: PsiElement) = myPsiFile.checkAdd(psiElement) override fun addRange(psiElement: PsiElement, psiElement2: PsiElement): PsiElement? { return myPsiFile.addRange(psiElement, psiElement2) } override fun addRangeBefore(psiElement: PsiElement, psiElement2: PsiElement, psiElement3: PsiElement): PsiElement? { return myPsiFile.addRangeBefore(psiElement, psiElement2, psiElement3) } override fun addRangeAfter(psiElement: PsiElement, psiElement2: PsiElement, psiElement3: PsiElement): PsiElement? { return myPsiFile.addRangeAfter(psiElement, psiElement2, psiElement3) } override fun delete() = myPsiFile.delete() override fun checkDelete() = myPsiFile.checkDelete() override fun deleteChildRange(psiElement: PsiElement, psiElement2: PsiElement) = myPsiFile.deleteChildRange(psiElement, psiElement2) override fun replace(psiElement: PsiElement): PsiElement? = myPsiFile.replace(psiElement) override fun isValid() = myPsiFile.isValid override fun isWritable() = myPsiFile.isWritable override fun getReference() = myPsiFile.reference override fun getReferences(): Array = myPsiFile.references override fun getCopyableUserData(tKey: Key) = myPsiFile.getCopyableUserData(tKey) override fun putCopyableUserData(tKey: Key, t: T?) = myPsiFile.putCopyableUserData(tKey, t) override fun processDeclarations( psiScopeProcessor: PsiScopeProcessor, resolveState: ResolveState, psiElement: PsiElement?, psiElement2: PsiElement ): Boolean { return myPsiFile.processDeclarations(psiScopeProcessor, resolveState, psiElement, psiElement2) } override fun getContext() = myPsiFile.context override fun isPhysical() = myPsiFile.isPhysical override fun getResolveScope() = myPsiFile.resolveScope override fun getUseScope() = myPsiFile.useScope override fun toString() = myPsiFile.toString() override fun isEquivalentTo(psiElement: PsiElement) = myPsiFile.isEquivalentTo(psiElement) override fun getUserData(tKey: Key) = myPsiFile.getUserData(tKey) override fun putUserData(tKey: Key, t: T?) = myPsiFile.putUserData(tKey, t) override fun getIcon(i: Int): Icon = myPsiFile.getIcon(i) override fun getPresentation() = myPsiFile.presentation override fun navigate(b: Boolean) = myPsiFile.navigate(b) override fun canNavigate() = myPsiFile.canNavigate() override fun canNavigateToSource() = myPsiFile.canNavigateToSource() override fun getFileResolveScope() = myPsiFile.fileResolveScope override fun ignoreReferencedElementAccessibility() = myPsiFile.ignoreReferencedElementAccessibility() override fun processElements(psiElementProcessor: PsiElementProcessor, psiElement: PsiElement): Boolean { return myPsiFile.processElements(psiElementProcessor, psiElement) } private class LayoutPsiDirectory(val module: Module) : PsiDirectory { private val parentDir by lazy { val facet = AndroidFacet.getInstance(module) ?: return@lazy null val dir = ModuleResourceManagers.getInstance(facet).localResourceManager.resourceDirs .firstOrNull() ?: return@lazy null PsiManager.getInstance(module.project).findDirectory(dir) } override fun getName(): String { return "layout" } override fun getVirtualFile(): VirtualFile { return null!! } @Throws(IncorrectOperationException::class) override fun setName(s: String): PsiElement { return null!! } override fun getParentDirectory(): PsiDirectory? = parentDir override fun getParent() = parentDir override fun getSubdirectories(): Array { return arrayOfNulls(0) } override fun getFiles(): Array { return arrayOfNulls(0) } override fun findSubdirectory(s: String): PsiDirectory? { return null } override fun findFile(@NonNls s: String): PsiFile? { return null } @Throws(IncorrectOperationException::class) override fun createSubdirectory(s: String): PsiDirectory { return null!! } @Throws(IncorrectOperationException::class) override fun checkCreateSubdirectory(s: String) { } @Throws(IncorrectOperationException::class) override fun createFile(@NonNls s: String): PsiFile { return null!! } @Throws(IncorrectOperationException::class) override fun copyFileFrom(s: String, psiFile: PsiFile): PsiFile { return null!! } @Throws(IncorrectOperationException::class) override fun checkCreateFile(s: String) { } override fun isDirectory(): Boolean { return true } override fun processChildren(psiFileSystemItemPsiElementProcessor: PsiElementProcessor): Boolean { return false } override fun getPresentation(): ItemPresentation? { return null } override fun navigate(b: Boolean) { } override fun canNavigate(): Boolean { return false } override fun canNavigateToSource(): Boolean { return false } @Throws(IncorrectOperationException::class) override fun checkSetName(s: String) { } @Throws(PsiInvalidElementAccessException::class) override fun getProject(): Project { return null!! } override fun getLanguage(): Language { return null!! } override fun getManager(): PsiManager? { return null } override fun getChildren(): Array { return arrayOfNulls(0) } override fun getFirstChild(): PsiElement? { return null } override fun getLastChild(): PsiElement? { return null } override fun getNextSibling(): PsiElement? { return null } override fun getPrevSibling(): PsiElement? { return null } @Throws(PsiInvalidElementAccessException::class) override fun getContainingFile(): PsiFile? { return null } override fun getTextRange(): TextRange? { return null } override fun getStartOffsetInParent(): Int { return 0 } override fun getTextLength(): Int { return 0 } override fun findElementAt(i: Int): PsiElement? { return null } override fun findReferenceAt(i: Int): PsiReference? { return null } override fun getTextOffset(): Int { return 0 } override fun getText(): String? { return null } override fun textToCharArray(): CharArray { return CharArray(0) } override fun getNavigationElement(): PsiElement? { return null } override fun getOriginalElement(): PsiElement? { return null } override fun textMatches(@NonNls charSequence: CharSequence): Boolean { return false } override fun textMatches(psiElement: PsiElement): Boolean { return false } override fun textContains(c: Char): Boolean { return false } override fun accept(psiElementVisitor: PsiElementVisitor) { } override fun acceptChildren(psiElementVisitor: PsiElementVisitor) { } override fun copy(): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun add(psiElement: PsiElement): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun addBefore(psiElement: PsiElement, psiElement2: PsiElement?): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun addAfter(psiElement: PsiElement, psiElement2: PsiElement?): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun checkAdd(psiElement: PsiElement) { } @Throws(IncorrectOperationException::class) override fun addRange(psiElement: PsiElement, psiElement2: PsiElement): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun addRangeBefore(psiElement: PsiElement, psiElement2: PsiElement, psiElement3: PsiElement): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun addRangeAfter(psiElement: PsiElement, psiElement2: PsiElement, psiElement3: PsiElement): PsiElement? { return null } @Throws(IncorrectOperationException::class) override fun delete() { } @Throws(IncorrectOperationException::class) override fun checkDelete() { } @Throws(IncorrectOperationException::class) override fun deleteChildRange(psiElement: PsiElement, psiElement2: PsiElement) { } @Throws(IncorrectOperationException::class) override fun replace(psiElement: PsiElement): PsiElement? { return null } override fun isValid(): Boolean { return false } override fun isWritable(): Boolean { return false } override fun getReference(): PsiReference? { return null } override fun getReferences(): Array { return arrayOfNulls(0) } override fun getCopyableUserData(tKey: Key): T? { return null } override fun putCopyableUserData(tKey: Key, t: T?) { } override fun processDeclarations( psiScopeProcessor: PsiScopeProcessor, resolveState: ResolveState, psiElement: PsiElement?, psiElement2: PsiElement ): Boolean { return false } override fun getContext(): PsiElement? { return null } override fun isPhysical(): Boolean { return false } override fun getResolveScope(): GlobalSearchScope { return null!! } override fun getUseScope(): SearchScope { return null!! } override fun getNode(): ASTNode? { return null } override fun isEquivalentTo(psiElement: PsiElement): Boolean { return false } override fun getIcon(@IconFlags i: Int): Icon? { return null } override fun getUserData(tKey: Key): T? { return null } override fun putUserData(tKey: Key, t: T?) { } } inner class LayoutLightVirtualFile(name: String, text: String) : LightVirtualFile(name, text), VirtualFileWindow { /* * This hack is needed to force PsiDocumentManager return our LayoutPsiFile for LayoutLightVirtualFile */ override fun getDocumentWindow(): DocumentWindow { val documentManager = PsiDocumentManager.getInstance(project) val documentWindowStub = object : UserDataHolderBase(), DocumentWindow { override fun hostToInjectedUnescaped(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun isOneLine(): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun removeDocumentListener(p0: DocumentListener) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun deleteString(p0: Int, p1: Int) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getTextLength(): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getHostRanges(): Array { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getText(): String { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getText(p0: TextRange): String { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getLineStartOffset(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun createRangeMarker(p0: Int, p1: Int): RangeMarker { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun createRangeMarker(p0: Int, p1: Int, p2: Boolean): RangeMarker { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun createRangeMarker(p0: TextRange): RangeMarker { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun insertString(p0: Int, p1: CharSequence) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun setText(p0: CharSequence) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun startGuardedBlockChecking() { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getHostRange(p0: Int): TextRange? { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getChars(): CharArray { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getLineCount(): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun stopGuardedBlockChecking() { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun areRangesEqual(p0: DocumentWindow): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun isValid(): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun removeGuardedBlock(p0: RangeMarker) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getLineSeparatorLength(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun injectedToHostLine(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun addPropertyChangeListener(p0: PropertyChangeListener) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun createGuardedBlock(p0: Int, p1: Int): RangeMarker { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun replaceString(p0: Int, p1: Int, p2: CharSequence) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getModificationStamp(): Long { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun setReadOnly(p0: Boolean) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun intersectWithEditable(p0: TextRange): TextRange? { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun fireReadOnlyModificationAttempt() { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getLineNumber(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun setCyclicBufferSize(p0: Int) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun hostToInjected(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getImmutableCharSequence(): CharSequence { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getOffsetGuard(p0: Int): RangeMarker? { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun isWritable(): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getLineEndOffset(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getCharsSequence(): CharSequence { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getDelegate(): Document { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun containsRange(p0: Int, p1: Int): Boolean { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun addDocumentListener(p0: DocumentListener) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun addDocumentListener(p0: DocumentListener, p1: Disposable) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun removePropertyChangeListener(p0: PropertyChangeListener) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun getRangeGuard(p0: Int, p1: Int): RangeMarker? { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun injectedToHost(p0: Int): Int { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun injectedToHost(p0: TextRange): TextRange { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } } (documentManager as PsiDocumentManagerImpl).associatePsi(documentWindowStub, this@LayoutPsiFile) return documentWindowStub } override fun getDelegate(): VirtualFile = this@LayoutPsiFile.originalFile.virtualFile override fun getParent() = object : LightVirtualFile("layout") { override fun isDirectory() = true } } } ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/PreviewClassDescription.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.dslpreview import org.jetbrains.kotlin.psi.KtClass class PreviewClassDescription(val ktClass: KtClass, val fqName: String, val internalName: String) { val packageName = fqName.substringBeforeLast('.') val name = fqName.substringAfterLast('.') override fun toString(): String { return if (packageName.isNotBlank()) "$packageName.$name" else "$name" } override fun equals(other: Any?): Boolean{ if (this === other) return true if (other?.javaClass != javaClass) return false other as PreviewClassDescription if (fqName != other.fqName) return false if (internalName != other.internalName) return false return true } override fun hashCode(): Int{ var result = fqName.hashCode() result += 31 * result + internalName.hashCode() return result } } ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/SourceFileModificationTracker.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.dslpreview import com.intellij.openapi.util.ModificationTracker import com.intellij.psi.PsiJavaFile import com.intellij.psi.impl.PsiTreeChangeEventImpl import com.intellij.psi.impl.PsiTreeChangePreprocessor import org.jetbrains.kotlin.psi.KtFile import java.util.concurrent.atomic.AtomicLong class SourceFileModificationTracker : PsiTreeChangePreprocessor, ModificationTracker { private val counter = AtomicLong() companion object { private val HANDLED_EVENTS = setOf( PsiTreeChangeEventImpl.PsiEventType.CHILD_ADDED, PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED, PsiTreeChangeEventImpl.PsiEventType.CHILD_REMOVED, PsiTreeChangeEventImpl.PsiEventType.CHILD_REPLACED, PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED) } override fun treeChanged(event: PsiTreeChangeEventImpl) { if (event.code in HANDLED_EVENTS) { val file = event.file if (file is KtFile || file is PsiJavaFile) counter.incrementAndGet() } } override fun getModificationCount() = counter.get() } ================================================ FILE: anko/idea-plugin/preview/src/org/jetbrains/kotlin/android/dslpreview/UpdateActivityNameTask.kt ================================================ package org.jetbrains.kotlin.android.dslpreview import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.wm.ToolWindow import com.intellij.psi.PsiElement import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.idea.internal.Location import org.jetbrains.kotlin.idea.util.LongRunningReadTask import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import javax.swing.DefaultComboBoxModel class UpdateActivityNameTask( val previewManager: AnkoNlPreviewManager ) : LongRunningReadTask() { override fun prepareRequestInfo(): PsiElement? = with (previewManager) { val toolWindow: ToolWindow = toolWindow ?: return null if (!toolWindow.isVisible) return null val editor = FileEditorManager.getInstance(project).selectedTextEditor val location = Location.fromEditor(editor, project) if (location.editor == null) return null val file = location.kFile if (file == null || !ProjectRootsUtil.isInProjectSource(file)) return null val psiElement = file.findElementAt(location.startOffset) ?: return null return psiElement } override fun cloneRequestInfo(requestInfo: PsiElement): PsiElement { val newRequestInfo = super.cloneRequestInfo(requestInfo) assert(requestInfo == newRequestInfo) { "cloneRequestInfo should generate same location object" } return newRequestInfo } override fun hideResultOnInvalidLocation() { } override fun processRequest(element: PsiElement): PreviewClassDescription? { val cacheService = KotlinCacheService.getInstance(previewManager.project) return previewManager.classResolver.resolveClassDescription(element, cacheService) } private fun indexOf(model: DefaultComboBoxModel, description: PreviewClassDescription): Int? { for (i in 0..(model.size - 1)) { val item = model.getElementAt(i) as? PreviewClassDescription ?: continue if (item == description) return i } return null } private fun setSelection(model: DefaultComboBoxModel, description: PreviewClassDescription): Boolean { val index = indexOf(model, description) ?: return false model.selectedItem = model.getElementAt(index) return true } override fun onResultReady(requestInfo: PsiElement, description: PreviewClassDescription?) = with (previewManager) { if (description == null) return val model = myActivityListModel if (!setSelection(model, description)) { resolveAvailableClasses() setSelection(model, description) } } } ================================================ FILE: anko/idea-plugin/xml-converter/build.gradle ================================================ apply plugin: 'kotlin' sourceSets { main { java.srcDirs = ['src'] kotlin.srcDirs = ['src'] } test { java.srcDirs = ['test'] kotlin.srcDirs = ['test'] } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlinx:kotlinx.dom:$kotlinx_dom_version" compile project(':ide:plugin-classpath') compile project(':ide:attrs') } ================================================ FILE: anko/idea-plugin/xml-converter/resources/attrs.json ================================================ { "free": [ { "name": "textSize", "format": [ "dimension" ] }, { "name": "fontFamily", "format": [ "string" ] }, { "name": "typeface", "format": [ "enum" ], "enum": [ { "name": "normal", "value": "0" }, { "name": "sans", "value": "1" }, { "name": "serif", "value": "2" }, { "name": "monospace", "value": "3" } ] }, { "name": "textStyle", "format": [ "flags" ], "flags": [ { "name": "normal", "value": "0" }, { "name": "bold", "value": "1" }, { "name": "italic", "value": "2" } ] }, { "name": "textColor", "format": [ "reference", "color" ] }, { "name": "textColorHighlight", "format": [ "reference", "color" ] }, { "name": "textColorHint", "format": [ "reference", "color" ] }, { "name": "textColorLink", "format": [ "reference", "color" ] }, { "name": "textCursorDrawable", "format": [ "reference" ] }, { "name": "textIsSelectable", "format": [ "boolean" ] }, { "name": "ellipsize", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "start", "value": "1" }, { "name": "middle", "value": "2" }, { "name": "end", "value": "3" }, { "name": "marquee", "value": "4" } ] }, { "name": "inputType", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0x00000000" }, { "name": "text", "value": "0x00000001" }, { "name": "textCapCharacters", "value": "0x00001001" }, { "name": "textCapWords", "value": "0x00002001" }, { "name": "textCapSentences", "value": "0x00004001" }, { "name": "textAutoCorrect", "value": "0x00008001" }, { "name": "textAutoComplete", "value": "0x00010001" }, { "name": "textMultiLine", "value": "0x00020001" }, { "name": "textImeMultiLine", "value": "0x00040001" }, { "name": "textNoSuggestions", "value": "0x00080001" }, { "name": "textUri", "value": "0x00000011" }, { "name": "textEmailAddress", "value": "0x00000021" }, { "name": "textEmailSubject", "value": "0x00000031" }, { "name": "textShortMessage", "value": "0x00000041" }, { "name": "textLongMessage", "value": "0x00000051" }, { "name": "textPersonName", "value": "0x00000061" }, { "name": "textPostalAddress", "value": "0x00000071" }, { "name": "textPassword", "value": "0x00000081" }, { "name": "textVisiblePassword", "value": "0x00000091" }, { "name": "textWebEditText", "value": "0x000000a1" }, { "name": "textFilter", "value": "0x000000b1" }, { "name": "textPhonetic", "value": "0x000000c1" }, { "name": "textWebEmailAddress", "value": "0x000000d1" }, { "name": "textWebPassword", "value": "0x000000e1" }, { "name": "number", "value": "0x00000002" }, { "name": "numberSigned", "value": "0x00001002" }, { "name": "numberDecimal", "value": "0x00002002" }, { "name": "numberPassword", "value": "0x00000012" }, { "name": "phone", "value": "0x00000003" }, { "name": "datetime", "value": "0x00000004" }, { "name": "date", "value": "0x00000014" }, { "name": "time", "value": "0x00000024" } ] }, { "name": "imeOptions", "format": [ "flags" ], "flags": [ { "name": "normal", "value": "0x00000000" }, { "name": "actionUnspecified", "value": "0x00000000" }, { "name": "actionNone", "value": "0x00000001" }, { "name": "actionGo", "value": "0x00000002" }, { "name": "actionSearch", "value": "0x00000003" }, { "name": "actionSend", "value": "0x00000004" }, { "name": "actionNext", "value": "0x00000005" }, { "name": "actionDone", "value": "0x00000006" }, { "name": "actionPrevious", "value": "0x00000007" }, { "name": "flagNoFullscreen", "value": "0x2000000" }, { "name": "flagNavigatePrevious", "value": "0x4000000" }, { "name": "flagNavigateNext", "value": "0x8000000" }, { "name": "flagNoExtractUi", "value": "0x10000000" }, { "name": "flagNoAccessoryAction", "value": "0x20000000" }, { "name": "flagNoEnterAction", "value": "0x40000000" }, { "name": "flagForceAscii", "value": "0x80000000" } ] }, { "name": "x", "format": [ "dimension" ] }, { "name": "y", "format": [ "dimension" ] }, { "name": "gravity", "format": [ "flags" ], "flags": [ { "name": "top", "value": "0x30" }, { "name": "bottom", "value": "0x50" }, { "name": "left", "value": "0x03" }, { "name": "right", "value": "0x05" }, { "name": "center_vertical", "value": "0x10" }, { "name": "fill_vertical", "value": "0x70" }, { "name": "center_horizontal", "value": "0x01" }, { "name": "fill_horizontal", "value": "0x07" }, { "name": "center", "value": "0x11" }, { "name": "fill", "value": "0x77" }, { "name": "clip_vertical", "value": "0x80" }, { "name": "clip_horizontal", "value": "0x08" }, { "name": "start", "value": "0x00800003" }, { "name": "end", "value": "0x00800005" } ] }, { "name": "autoLink", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0x00" }, { "name": "web", "value": "0x01" }, { "name": "email", "value": "0x02" }, { "name": "phone", "value": "0x04" }, { "name": "map", "value": "0x08" }, { "name": "all", "value": "0x0f" } ] }, { "name": "entries", "format": [ "reference" ] }, { "name": "layout_gravity", "format": [ "flags" ], "flags": [ { "name": "top", "value": "0x30" }, { "name": "bottom", "value": "0x50" }, { "name": "left", "value": "0x03" }, { "name": "right", "value": "0x05" }, { "name": "center_vertical", "value": "0x10" }, { "name": "fill_vertical", "value": "0x70" }, { "name": "center_horizontal", "value": "0x01" }, { "name": "fill_horizontal", "value": "0x07" }, { "name": "center", "value": "0x11" }, { "name": "fill", "value": "0x77" }, { "name": "clip_vertical", "value": "0x80" }, { "name": "clip_horizontal", "value": "0x08" }, { "name": "start", "value": "0x00800003" }, { "name": "end", "value": "0x00800005" } ] }, { "name": "orientation", "format": [ "enum" ], "enum": [ { "name": "horizontal", "value": "0" }, { "name": "vertical", "value": "1" } ] }, { "name": "alignmentMode", "format": [ "enum" ], "enum": [ { "name": "alignBounds", "value": "0" }, { "name": "alignMargins", "value": "1" } ] }, { "name": "keycode", "format": [ "enum" ], "enum": [ { "name": "KEYCODE_UNKNOWN", "value": "0" }, { "name": "KEYCODE_SOFT_LEFT", "value": "1" }, { "name": "KEYCODE_SOFT_RIGHT", "value": "2" }, { "name": "KEYCODE_HOME", "value": "3" }, { "name": "KEYCODE_BACK", "value": "4" }, { "name": "KEYCODE_CALL", "value": "5" }, { "name": "KEYCODE_ENDCALL", "value": "6" }, { "name": "KEYCODE_0", "value": "7" }, { "name": "KEYCODE_1", "value": "8" }, { "name": "KEYCODE_2", "value": "9" }, { "name": "KEYCODE_3", "value": "10" }, { "name": "KEYCODE_4", "value": "11" }, { "name": "KEYCODE_5", "value": "12" }, { "name": "KEYCODE_6", "value": "13" }, { "name": "KEYCODE_7", "value": "14" }, { "name": "KEYCODE_8", "value": "15" }, { "name": "KEYCODE_9", "value": "16" }, { "name": "KEYCODE_STAR", "value": "17" }, { "name": "KEYCODE_POUND", "value": "18" }, { "name": "KEYCODE_DPAD_UP", "value": "19" }, { "name": "KEYCODE_DPAD_DOWN", "value": "20" }, { "name": "KEYCODE_DPAD_LEFT", "value": "21" }, { "name": "KEYCODE_DPAD_RIGHT", "value": "22" }, { "name": "KEYCODE_DPAD_CENTER", "value": "23" }, { "name": "KEYCODE_VOLUME_UP", "value": "24" }, { "name": "KEYCODE_VOLUME_DOWN", "value": "25" }, { "name": "KEYCODE_POWER", "value": "26" }, { "name": "KEYCODE_CAMERA", "value": "27" }, { "name": "KEYCODE_CLEAR", "value": "28" }, { "name": "KEYCODE_A", "value": "29" }, { "name": "KEYCODE_B", "value": "30" }, { "name": "KEYCODE_C", "value": "31" }, { "name": "KEYCODE_D", "value": "32" }, { "name": "KEYCODE_E", "value": "33" }, { "name": "KEYCODE_F", "value": "34" }, { "name": "KEYCODE_G", "value": "35" }, { "name": "KEYCODE_H", "value": "36" }, { "name": "KEYCODE_I", "value": "37" }, { "name": "KEYCODE_J", "value": "38" }, { "name": "KEYCODE_K", "value": "39" }, { "name": "KEYCODE_L", "value": "40" }, { "name": "KEYCODE_M", "value": "41" }, { "name": "KEYCODE_N", "value": "42" }, { "name": "KEYCODE_O", "value": "43" }, { "name": "KEYCODE_P", "value": "44" }, { "name": "KEYCODE_Q", "value": "45" }, { "name": "KEYCODE_R", "value": "46" }, { "name": "KEYCODE_S", "value": "47" }, { "name": "KEYCODE_T", "value": "48" }, { "name": "KEYCODE_U", "value": "49" }, { "name": "KEYCODE_V", "value": "50" }, { "name": "KEYCODE_W", "value": "51" }, { "name": "KEYCODE_X", "value": "52" }, { "name": "KEYCODE_Y", "value": "53" }, { "name": "KEYCODE_Z", "value": "54" }, { "name": "KEYCODE_COMMA", "value": "55" }, { "name": "KEYCODE_PERIOD", "value": "56" }, { "name": "KEYCODE_ALT_LEFT", "value": "57" }, { "name": "KEYCODE_ALT_RIGHT", "value": "58" }, { "name": "KEYCODE_SHIFT_LEFT", "value": "59" }, { "name": "KEYCODE_SHIFT_RIGHT", "value": "60" }, { "name": "KEYCODE_TAB", "value": "61" }, { "name": "KEYCODE_SPACE", "value": "62" }, { "name": "KEYCODE_SYM", "value": "63" }, { "name": "KEYCODE_EXPLORER", "value": "64" }, { "name": "KEYCODE_ENVELOPE", "value": "65" }, { "name": "KEYCODE_ENTER", "value": "66" }, { "name": "KEYCODE_DEL", "value": "67" }, { "name": "KEYCODE_GRAVE", "value": "68" }, { "name": "KEYCODE_MINUS", "value": "69" }, { "name": "KEYCODE_EQUALS", "value": "70" }, { "name": "KEYCODE_LEFT_BRACKET", "value": "71" }, { "name": "KEYCODE_RIGHT_BRACKET", "value": "72" }, { "name": "KEYCODE_BACKSLASH", "value": "73" }, { "name": "KEYCODE_SEMICOLON", "value": "74" }, { "name": "KEYCODE_APOSTROPHE", "value": "75" }, { "name": "KEYCODE_SLASH", "value": "76" }, { "name": "KEYCODE_AT", "value": "77" }, { "name": "KEYCODE_NUM", "value": "78" }, { "name": "KEYCODE_HEADSETHOOK", "value": "79" }, { "name": "KEYCODE_FOCUS", "value": "80" }, { "name": "KEYCODE_PLUS", "value": "81" }, { "name": "KEYCODE_MENU", "value": "82" }, { "name": "KEYCODE_NOTIFICATION", "value": "83" }, { "name": "KEYCODE_SEARCH", "value": "84" }, { "name": "KEYCODE_MEDIA_PLAY_PAUSE", "value": "85" }, { "name": "KEYCODE_MEDIA_STOP", "value": "86" }, { "name": "KEYCODE_MEDIA_NEXT", "value": "87" }, { "name": "KEYCODE_MEDIA_PREVIOUS", "value": "88" }, { "name": "KEYCODE_MEDIA_REWIND", "value": "89" }, { "name": "KEYCODE_MEDIA_FAST_FORWARD", "value": "90" }, { "name": "KEYCODE_MUTE", "value": "91" }, { "name": "KEYCODE_PAGE_UP", "value": "92" }, { "name": "KEYCODE_PAGE_DOWN", "value": "93" }, { "name": "KEYCODE_PICTSYMBOLS", "value": "94" }, { "name": "KEYCODE_SWITCH_CHARSET", "value": "95" }, { "name": "KEYCODE_BUTTON_A", "value": "96" }, { "name": "KEYCODE_BUTTON_B", "value": "97" }, { "name": "KEYCODE_BUTTON_C", "value": "98" }, { "name": "KEYCODE_BUTTON_X", "value": "99" }, { "name": "KEYCODE_BUTTON_Y", "value": "100" }, { "name": "KEYCODE_BUTTON_Z", "value": "101" }, { "name": "KEYCODE_BUTTON_L1", "value": "102" }, { "name": "KEYCODE_BUTTON_R1", "value": "103" }, { "name": "KEYCODE_BUTTON_L2", "value": "104" }, { "name": "KEYCODE_BUTTON_R2", "value": "105" }, { "name": "KEYCODE_BUTTON_THUMBL", "value": "106" }, { "name": "KEYCODE_BUTTON_THUMBR", "value": "107" }, { "name": "KEYCODE_BUTTON_START", "value": "108" }, { "name": "KEYCODE_BUTTON_SELECT", "value": "109" }, { "name": "KEYCODE_BUTTON_MODE", "value": "110" }, { "name": "KEYCODE_ESCAPE", "value": "111" }, { "name": "KEYCODE_FORWARD_DEL", "value": "112" }, { "name": "KEYCODE_CTRL_LEFT", "value": "113" }, { "name": "KEYCODE_CTRL_RIGHT", "value": "114" }, { "name": "KEYCODE_CAPS_LOCK", "value": "115" }, { "name": "KEYCODE_SCROLL_LOCK", "value": "116" }, { "name": "KEYCODE_META_LEFT", "value": "117" }, { "name": "KEYCODE_META_RIGHT", "value": "118" }, { "name": "KEYCODE_FUNCTION", "value": "119" }, { "name": "KEYCODE_SYSRQ", "value": "120" }, { "name": "KEYCODE_BREAK", "value": "121" }, { "name": "KEYCODE_MOVE_HOME", "value": "122" }, { "name": "KEYCODE_MOVE_END", "value": "123" }, { "name": "KEYCODE_INSERT", "value": "124" }, { "name": "KEYCODE_FORWARD", "value": "125" }, { "name": "KEYCODE_MEDIA_PLAY", "value": "126" }, { "name": "KEYCODE_MEDIA_PAUSE", "value": "127" }, { "name": "KEYCODE_MEDIA_CLOSE", "value": "128" }, { "name": "KEYCODE_MEDIA_EJECT", "value": "129" }, { "name": "KEYCODE_MEDIA_RECORD", "value": "130" }, { "name": "KEYCODE_F1", "value": "131" }, { "name": "KEYCODE_F2", "value": "132" }, { "name": "KEYCODE_F3", "value": "133" }, { "name": "KEYCODE_F4", "value": "134" }, { "name": "KEYCODE_F5", "value": "135" }, { "name": "KEYCODE_F6", "value": "136" }, { "name": "KEYCODE_F7", "value": "137" }, { "name": "KEYCODE_F8", "value": "138" }, { "name": "KEYCODE_F9", "value": "139" }, { "name": "KEYCODE_F10", "value": "140" }, { "name": "KEYCODE_F11", "value": "141" }, { "name": "KEYCODE_F12", "value": "142" }, { "name": "KEYCODE_NUM_LOCK", "value": "143" }, { "name": "KEYCODE_NUMPAD_0", "value": "144" }, { "name": "KEYCODE_NUMPAD_1", "value": "145" }, { "name": "KEYCODE_NUMPAD_2", "value": "146" }, { "name": "KEYCODE_NUMPAD_3", "value": "147" }, { "name": "KEYCODE_NUMPAD_4", "value": "148" }, { "name": "KEYCODE_NUMPAD_5", "value": "149" }, { "name": "KEYCODE_NUMPAD_6", "value": "150" }, { "name": "KEYCODE_NUMPAD_7", "value": "151" }, { "name": "KEYCODE_NUMPAD_8", "value": "152" }, { "name": "KEYCODE_NUMPAD_9", "value": "153" }, { "name": "KEYCODE_NUMPAD_DIVIDE", "value": "154" }, { "name": "KEYCODE_NUMPAD_MULTIPLY", "value": "155" }, { "name": "KEYCODE_NUMPAD_SUBTRACT", "value": "156" }, { "name": "KEYCODE_NUMPAD_ADD", "value": "157" }, { "name": "KEYCODE_NUMPAD_DOT", "value": "158" }, { "name": "KEYCODE_NUMPAD_COMMA", "value": "159" }, { "name": "KEYCODE_NUMPAD_ENTER", "value": "160" }, { "name": "KEYCODE_NUMPAD_EQUALS", "value": "161" }, { "name": "KEYCODE_NUMPAD_LEFT_PAREN", "value": "162" }, { "name": "KEYCODE_NUMPAD_RIGHT_PAREN", "value": "163" }, { "name": "KEYCODE_VOLUME_MUTE", "value": "164" }, { "name": "KEYCODE_INFO", "value": "165" }, { "name": "KEYCODE_CHANNEL_UP", "value": "166" }, { "name": "KEYCODE_CHANNEL_DOWN", "value": "167" }, { "name": "KEYCODE_ZOOM_IN", "value": "168" }, { "name": "KEYCODE_ZOOM_OUT", "value": "169" }, { "name": "KEYCODE_TV", "value": "170" }, { "name": "KEYCODE_WINDOW", "value": "171" }, { "name": "KEYCODE_GUIDE", "value": "172" }, { "name": "KEYCODE_DVR", "value": "173" }, { "name": "KEYCODE_BOOKMARK", "value": "174" }, { "name": "KEYCODE_CAPTIONS", "value": "175" }, { "name": "KEYCODE_SETTINGS", "value": "176" }, { "name": "KEYCODE_TV_POWER", "value": "177" }, { "name": "KEYCODE_TV_INPUT", "value": "178" }, { "name": "KEYCODE_STB_POWER", "value": "179" }, { "name": "KEYCODE_STB_INPUT", "value": "180" }, { "name": "KEYCODE_AVR_POWER", "value": "181" }, { "name": "KEYCODE_AVR_INPUT", "value": "182" }, { "name": "KEYCODE_PROG_GRED", "value": "183" }, { "name": "KEYCODE_PROG_GREEN", "value": "184" }, { "name": "KEYCODE_PROG_YELLOW", "value": "185" }, { "name": "KEYCODE_PROG_BLUE", "value": "186" }, { "name": "KEYCODE_APP_SWITCH", "value": "187" }, { "name": "KEYCODE_BUTTON_1", "value": "188" }, { "name": "KEYCODE_BUTTON_2", "value": "189" }, { "name": "KEYCODE_BUTTON_3", "value": "190" }, { "name": "KEYCODE_BUTTON_4", "value": "191" }, { "name": "KEYCODE_BUTTON_5", "value": "192" }, { "name": "KEYCODE_BUTTON_6", "value": "193" }, { "name": "KEYCODE_BUTTON_7", "value": "194" }, { "name": "KEYCODE_BUTTON_8", "value": "195" }, { "name": "KEYCODE_BUTTON_9", "value": "196" }, { "name": "KEYCODE_BUTTON_10", "value": "197" }, { "name": "KEYCODE_BUTTON_11", "value": "198" }, { "name": "KEYCODE_BUTTON_12", "value": "199" }, { "name": "KEYCODE_BUTTON_13", "value": "200" }, { "name": "KEYCODE_BUTTON_14", "value": "201" }, { "name": "KEYCODE_BUTTON_15", "value": "202" }, { "name": "KEYCODE_BUTTON_16", "value": "203" }, { "name": "KEYCODE_LANGUAGE_SWITCH", "value": "204" }, { "name": "KEYCODE_MANNER_MODE", "value": "205" }, { "name": "KEYCODE_3D_MODE", "value": "206" }, { "name": "KEYCODE_CONTACTS", "value": "207" }, { "name": "KEYCODE_CALENDAR", "value": "208" }, { "name": "KEYCODE_MUSIC", "value": "209" }, { "name": "KEYCODE_CALCULATOR", "value": "210" }, { "name": "KEYCODE_ZENKAKU_HANKAKU", "value": "211" }, { "name": "KEYCODE_EISU", "value": "212" }, { "name": "KEYCODE_MUHENKAN", "value": "213" }, { "name": "KEYCODE_HENKAN", "value": "214" }, { "name": "KEYCODE_KATAKANA_HIRAGANA", "value": "215" }, { "name": "KEYCODE_YEN", "value": "216" }, { "name": "KEYCODE_RO", "value": "217" }, { "name": "KEYCODE_KANA", "value": "218" }, { "name": "KEYCODE_ASSIST", "value": "219" }, { "name": "KEYCODE_BRIGHTNESS_DOWN", "value": "220" }, { "name": "KEYCODE_BRIGHTNESS_UP", "value": "221" }, { "name": "KEYCODE_MEDIA_AUDIO_TRACK", "value": "222" } ] }, { "name": "layout_childType", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "widget", "value": "1" }, { "name": "challenge", "value": "2" }, { "name": "userSwitcher", "value": "3" }, { "name": "scrim", "value": "4" }, { "name": "widgets", "value": "5" }, { "name": "expandChallengeHandle", "value": "6" }, { "name": "pageDeleteDropTarget", "value": "7" } ] } ], "styleables": { "Theme": { "name": "Theme", "attrs": [ { "name": "colorForeground", "format": [ "color" ] }, { "name": "colorForegroundInverse", "format": [ "color" ] }, { "name": "colorBackground", "format": [ "color" ] }, { "name": "colorBackgroundCacheHint", "format": [ "color" ] }, { "name": "colorPressedHighlight", "format": [ "color" ] }, { "name": "colorLongPressedHighlight", "format": [ "color" ] }, { "name": "colorFocusedHighlight", "format": [ "color" ] }, { "name": "colorActivatedHighlight", "format": [ "color" ] }, { "name": "colorMultiSelectHighlight", "format": [ "color" ] }, { "name": "disabledAlpha", "format": [ "float" ] }, { "name": "backgroundDimAmount", "format": [ "float" ] }, { "name": "backgroundDimEnabled", "format": [ "boolean" ] }, { "name": "textAppearance", "format": [ "reference" ] }, { "name": "textAppearanceInverse", "format": [ "reference" ] }, { "name": "textColorPrimary", "format": [ "reference", "color" ] }, { "name": "textColorSecondary", "format": [ "reference", "color" ] }, { "name": "textColorTertiary", "format": [ "reference", "color" ] }, { "name": "textColorPrimaryInverse", "format": [ "reference", "color" ] }, { "name": "textColorSecondaryInverse", "format": [ "reference", "color" ] }, { "name": "textColorTertiaryInverse", "format": [ "reference", "color" ] }, { "name": "textColorHintInverse", "format": [ "reference", "color" ] }, { "name": "textColorPrimaryDisableOnly", "format": [ "reference", "color" ] }, { "name": "textColorPrimaryInverseDisableOnly", "format": [ "reference", "color" ] }, { "name": "textColorPrimaryNoDisable", "format": [ "reference", "color" ] }, { "name": "textColorSecondaryNoDisable", "format": [ "reference", "color" ] }, { "name": "textColorPrimaryInverseNoDisable", "format": [ "reference", "color" ] }, { "name": "textColorSecondaryInverseNoDisable", "format": [ "reference", "color" ] }, { "name": "textColorSearchUrl", "format": [ "reference", "color" ] }, { "name": "textColorHighlightInverse", "format": [ "reference", "color" ] }, { "name": "textColorLinkInverse", "format": [ "reference", "color" ] }, { "name": "textColorAlertDialogListItem", "format": [ "reference", "color" ] }, { "name": "searchWidgetCorpusItemBackground", "format": [ "reference", "color" ] }, { "name": "textAppearanceLarge", "format": [ "reference" ] }, { "name": "textAppearanceMedium", "format": [ "reference" ] }, { "name": "textAppearanceSmall", "format": [ "reference" ] }, { "name": "textAppearanceLargeInverse", "format": [ "reference" ] }, { "name": "textAppearanceMediumInverse", "format": [ "reference" ] }, { "name": "textAppearanceSmallInverse", "format": [ "reference" ] }, { "name": "textAppearanceSearchResultTitle", "format": [ "reference" ] }, { "name": "textAppearanceSearchResultSubtitle", "format": [ "reference" ] }, { "name": "textAppearanceButton", "format": [ "reference" ] }, { "name": "textAppearanceLargePopupMenu", "format": [ "reference" ] }, { "name": "textAppearanceSmallPopupMenu", "format": [ "reference" ] }, { "name": "textAppearanceEasyCorrectSuggestion", "format": [ "reference" ] }, { "name": "textAppearanceMisspelledSuggestion", "format": [ "reference" ] }, { "name": "textAppearanceAutoCorrectionSuggestion", "format": [ "reference" ] }, { "name": "textUnderlineColor", "format": [ "reference", "color" ] }, { "name": "textUnderlineThickness", "format": [ "reference", "dimension" ] }, { "name": "editTextColor", "format": [ "reference", "color" ] }, { "name": "editTextBackground", "format": [ "reference" ] }, { "name": "errorMessageBackground", "format": [ "reference" ] }, { "name": "errorMessageAboveBackground", "format": [ "reference" ] }, { "name": "candidatesTextStyleSpans", "format": [ "reference", "string" ] }, { "name": "textCheckMark", "format": [ "reference" ] }, { "name": "textCheckMarkInverse", "format": [ "reference" ] }, { "name": "listChoiceIndicatorMultiple", "format": [ "reference" ] }, { "name": "listChoiceIndicatorSingle", "format": [ "reference" ] }, { "name": "listChoiceBackgroundIndicator", "format": [ "reference" ] }, { "name": "activatedBackgroundIndicator", "format": [ "reference" ] }, { "name": "buttonStyle", "format": [ "reference" ] }, { "name": "buttonStyleSmall", "format": [ "reference" ] }, { "name": "buttonStyleInset", "format": [ "reference" ] }, { "name": "buttonStyleToggle", "format": [ "reference" ] }, { "name": "galleryItemBackground", "format": [ "reference" ] }, { "name": "listPreferredItemHeight", "format": [ "dimension" ] }, { "name": "listPreferredItemHeightSmall", "format": [ "dimension" ] }, { "name": "listPreferredItemHeightLarge", "format": [ "dimension" ] }, { "name": "searchResultListItemHeight", "format": [ "dimension" ] }, { "name": "listPreferredItemPaddingLeft", "format": [ "dimension" ] }, { "name": "listPreferredItemPaddingRight", "format": [ "dimension" ] }, { "name": "textAppearanceListItem", "format": [ "reference" ] }, { "name": "textAppearanceListItemSmall", "format": [ "reference" ] }, { "name": "listDivider", "format": [ "reference" ] }, { "name": "listDividerAlertDialog", "format": [ "reference" ] }, { "name": "listSeparatorTextViewStyle", "format": [ "reference" ] }, { "name": "expandableListPreferredItemPaddingLeft", "format": [ "dimension" ] }, { "name": "expandableListPreferredChildPaddingLeft", "format": [ "dimension" ] }, { "name": "expandableListPreferredItemIndicatorLeft", "format": [ "dimension" ] }, { "name": "expandableListPreferredItemIndicatorRight", "format": [ "dimension" ] }, { "name": "expandableListPreferredChildIndicatorLeft", "format": [ "dimension" ] }, { "name": "expandableListPreferredChildIndicatorRight", "format": [ "dimension" ] }, { "name": "dropdownListPreferredItemHeight", "format": [ "dimension" ] }, { "name": "listPreferredItemPaddingStart", "format": [ "dimension" ] }, { "name": "listPreferredItemPaddingEnd", "format": [ "dimension" ] }, { "name": "windowBackground", "format": [ "reference" ] }, { "name": "windowFrame", "format": [ "reference" ] }, { "name": "windowNoTitle", "format": [ "boolean" ] }, { "name": "windowFullscreen", "format": [ "boolean" ] }, { "name": "windowOverscan", "format": [ "boolean" ] }, { "name": "windowIsFloating", "format": [ "boolean" ] }, { "name": "windowIsTranslucent", "format": [ "boolean" ] }, { "name": "windowShowWallpaper", "format": [ "boolean" ] }, { "name": "windowContentOverlay", "format": [ "reference" ] }, { "name": "windowTitleSize", "format": [ "dimension" ] }, { "name": "windowTitleStyle", "format": [ "reference" ] }, { "name": "windowTitleBackgroundStyle", "format": [ "reference" ] }, { "name": "windowAnimationStyle", "format": [ "reference" ] }, { "name": "windowActionBar", "format": [ "boolean" ] }, { "name": "windowActionBarOverlay", "format": [ "boolean" ] }, { "name": "windowActionModeOverlay", "format": [ "boolean" ] }, { "name": "windowSplitActionBar", "format": [ "boolean" ] }, { "name": "windowSoftInputMode", "format": [ "flags" ], "flags": [ { "name": "stateUnspecified", "value": "0" }, { "name": "stateUnchanged", "value": "1" }, { "name": "stateHidden", "value": "2" }, { "name": "stateAlwaysHidden", "value": "3" }, { "name": "stateVisible", "value": "4" }, { "name": "stateAlwaysVisible", "value": "5" }, { "name": "adjustUnspecified", "value": "0x00" }, { "name": "adjustResize", "value": "0x10" }, { "name": "adjustPan", "value": "0x20" }, { "name": "adjustNothing", "value": "0x30" } ] }, { "name": "windowDisablePreview", "format": [ "boolean" ] }, { "name": "windowNoDisplay", "format": [ "boolean" ] }, { "name": "windowEnableSplitTouch", "format": [ "boolean" ] }, { "name": "windowCloseOnTouchOutside", "format": [ "boolean" ] }, { "name": "windowTranslucentStatus", "format": [ "boolean" ] }, { "name": "windowTranslucentNavigation", "format": [ "boolean" ] }, { "name": "alertDialogStyle", "format": [ "reference" ] }, { "name": "alertDialogButtonGroupStyle", "format": [ "reference" ] }, { "name": "alertDialogCenterButtons", "format": [ "boolean" ] }, { "name": "detailsElementBackground", "format": [ "reference" ] }, { "name": "panelBackground", "format": [ "reference", "color" ] }, { "name": "panelFullBackground", "format": [ "reference", "color" ] }, { "name": "panelColorForeground", "format": [ "reference", "color" ] }, { "name": "panelColorBackground", "format": [ "reference", "color" ] }, { "name": "panelTextAppearance", "format": [ "reference" ] }, { "name": "panelMenuIsCompact", "format": [ "boolean" ] }, { "name": "panelMenuListWidth", "format": [ "dimension" ] }, { "name": "panelMenuListTheme", "format": [ "reference" ] }, { "name": "absListViewStyle", "format": [ "reference" ] }, { "name": "autoCompleteTextViewStyle", "format": [ "reference" ] }, { "name": "checkboxStyle", "format": [ "reference" ] }, { "name": "checkedTextViewStyle", "format": [ "reference" ] }, { "name": "dropDownListViewStyle", "format": [ "reference" ] }, { "name": "editTextStyle", "format": [ "reference" ] }, { "name": "expandableListViewStyle", "format": [ "reference" ] }, { "name": "expandableListViewWhiteStyle", "format": [ "reference" ] }, { "name": "galleryStyle", "format": [ "reference" ] }, { "name": "gestureOverlayViewStyle", "format": [ "reference" ] }, { "name": "gridViewStyle", "format": [ "reference" ] }, { "name": "imageButtonStyle", "format": [ "reference" ] }, { "name": "imageWellStyle", "format": [ "reference" ] }, { "name": "listViewStyle", "format": [ "reference" ] }, { "name": "listViewWhiteStyle", "format": [ "reference" ] }, { "name": "popupWindowStyle", "format": [ "reference" ] }, { "name": "progressBarStyle", "format": [ "reference" ] }, { "name": "progressBarStyleHorizontal", "format": [ "reference" ] }, { "name": "progressBarStyleSmall", "format": [ "reference" ] }, { "name": "progressBarStyleSmallTitle", "format": [ "reference" ] }, { "name": "progressBarStyleLarge", "format": [ "reference" ] }, { "name": "progressBarStyleInverse", "format": [ "reference" ] }, { "name": "progressBarStyleSmallInverse", "format": [ "reference" ] }, { "name": "progressBarStyleLargeInverse", "format": [ "reference" ] }, { "name": "seekBarStyle", "format": [ "reference" ] }, { "name": "ratingBarStyle", "format": [ "reference" ] }, { "name": "ratingBarStyleIndicator", "format": [ "reference" ] }, { "name": "ratingBarStyleSmall", "format": [ "reference" ] }, { "name": "radioButtonStyle", "format": [ "reference" ] }, { "name": "scrollViewStyle", "format": [ "reference" ] }, { "name": "horizontalScrollViewStyle", "format": [ "reference" ] }, { "name": "spinnerStyle", "format": [ "reference" ] }, { "name": "dropDownSpinnerStyle", "format": [ "reference" ] }, { "name": "actionDropDownStyle", "format": [ "reference" ] }, { "name": "actionButtonStyle", "format": [ "reference" ] }, { "name": "starStyle", "format": [ "reference" ] }, { "name": "tabWidgetStyle", "format": [ "reference" ] }, { "name": "textViewStyle", "format": [ "reference" ] }, { "name": "webTextViewStyle", "format": [ "reference" ] }, { "name": "webViewStyle", "format": [ "reference" ] }, { "name": "dropDownItemStyle", "format": [ "reference" ] }, { "name": "spinnerDropDownItemStyle", "format": [ "reference" ] }, { "name": "dropDownHintAppearance", "format": [ "reference" ] }, { "name": "spinnerItemStyle", "format": [ "reference" ] }, { "name": "mapViewStyle", "format": [ "reference" ] }, { "name": "quickContactBadgeOverlay", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleWindowSmall", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleWindowMedium", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleWindowLarge", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleSmallWindowSmall", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleSmallWindowMedium", "format": [ "reference" ] }, { "name": "quickContactBadgeStyleSmallWindowLarge", "format": [ "reference" ] }, { "name": "textSelectHandleWindowStyle", "format": [ "reference" ] }, { "name": "textSuggestionsWindowStyle", "format": [ "reference" ] }, { "name": "listPopupWindowStyle", "format": [ "reference" ] }, { "name": "popupMenuStyle", "format": [ "reference" ] }, { "name": "stackViewStyle", "format": [ "reference" ] }, { "name": "numberPickerStyle", "format": [ "reference" ] }, { "name": "calendarViewStyle", "format": [ "reference" ] }, { "name": "timePickerStyle", "format": [ "reference" ] }, { "name": "datePickerStyle", "format": [ "reference" ] }, { "name": "activityChooserViewStyle", "format": [ "reference" ] }, { "name": "fastScrollThumbDrawable", "format": [ "reference" ] }, { "name": "fastScrollPreviewBackgroundRight", "format": [ "reference" ] }, { "name": "fastScrollPreviewBackgroundLeft", "format": [ "reference" ] }, { "name": "fastScrollTrackDrawable", "format": [ "reference" ] }, { "name": "fastScrollOverlayPosition", "format": [ "enum" ], "enum": [ { "name": "floating", "value": "0" }, { "name": "atThumb", "value": "1" } ] }, { "name": "fastScrollTextColor", "format": [ "color" ] }, { "name": "actionBarTabStyle", "format": [ "reference" ] }, { "name": "actionBarTabBarStyle", "format": [ "reference" ] }, { "name": "actionBarTabTextStyle", "format": [ "reference" ] }, { "name": "actionOverflowButtonStyle", "format": [ "reference" ] }, { "name": "actionBarStyle", "format": [ "reference" ] }, { "name": "actionBarSplitStyle", "format": [ "reference" ] }, { "name": "actionBarWidgetTheme", "format": [ "reference" ] }, { "name": "actionBarSize", "format": [ "dimension", "enum" ], "enum": [ { "name": "wrap_content", "value": "0" } ] }, { "name": "actionBarDivider", "format": [ "reference" ] }, { "name": "actionBarItemBackground", "format": [ "reference" ] }, { "name": "actionMenuTextAppearance", "format": [ "reference" ] }, { "name": "actionMenuTextColor", "format": [ "color", "reference" ] }, { "name": "actionModeStyle", "format": [ "reference" ] }, { "name": "actionModeCloseButtonStyle", "format": [ "reference" ] }, { "name": "actionModeBackground", "format": [ "reference" ] }, { "name": "actionModeSplitBackground", "format": [ "reference" ] }, { "name": "actionModeCloseDrawable", "format": [ "reference" ] }, { "name": "actionModeCutDrawable", "format": [ "reference" ] }, { "name": "actionModeCopyDrawable", "format": [ "reference" ] }, { "name": "actionModePasteDrawable", "format": [ "reference" ] }, { "name": "actionModeSelectAllDrawable", "format": [ "reference" ] }, { "name": "actionModeShareDrawable", "format": [ "reference" ] }, { "name": "actionModeFindDrawable", "format": [ "reference" ] }, { "name": "actionModeWebSearchDrawable", "format": [ "reference" ] }, { "name": "actionModePopupWindowStyle", "format": [ "reference" ] }, { "name": "preferenceScreenStyle", "format": [ "reference" ] }, { "name": "preferenceFragmentStyle", "format": [ "reference" ] }, { "name": "preferenceCategoryStyle", "format": [ "reference" ] }, { "name": "preferenceStyle", "format": [ "reference" ] }, { "name": "preferenceInformationStyle", "format": [ "reference" ] }, { "name": "checkBoxPreferenceStyle", "format": [ "reference" ] }, { "name": "yesNoPreferenceStyle", "format": [ "reference" ] }, { "name": "dialogPreferenceStyle", "format": [ "reference" ] }, { "name": "editTextPreferenceStyle", "format": [ "reference" ] }, { "name": "ringtonePreferenceStyle", "format": [ "reference" ] }, { "name": "preferenceLayoutChild", "format": [ "reference" ] }, { "name": "preferencePanelStyle", "format": [ "reference" ] }, { "name": "preferenceHeaderPanelStyle", "format": [ "reference" ] }, { "name": "preferenceListStyle", "format": [ "reference" ] }, { "name": "preferenceFragmentListStyle", "format": [ "reference" ] }, { "name": "preferenceFragmentPaddingSide", "format": [ "dimension" ] }, { "name": "switchPreferenceStyle", "format": [ "reference" ] }, { "name": "textSelectHandleLeft", "format": [ "reference" ] }, { "name": "textSelectHandleRight", "format": [ "reference" ] }, { "name": "textSelectHandle", "format": [ "reference" ] }, { "name": "textEditPasteWindowLayout", "format": [ "reference" ] }, { "name": "textEditNoPasteWindowLayout", "format": [ "reference" ] }, { "name": "textEditSidePasteWindowLayout", "format": [ "reference" ] }, { "name": "textEditSideNoPasteWindowLayout", "format": [ "reference" ] }, { "name": "textEditSuggestionItemLayout", "format": [ "reference" ] }, { "name": "dialogTheme", "format": [ "reference" ] }, { "name": "dialogTitleIconsDecorLayout", "format": [ "reference" ] }, { "name": "dialogCustomTitleDecorLayout", "format": [ "reference" ] }, { "name": "dialogTitleDecorLayout", "format": [ "reference" ] }, { "name": "alertDialogTheme", "format": [ "reference" ] }, { "name": "alertDialogIcon", "format": [ "reference" ] }, { "name": "presentationTheme", "format": [ "reference" ] }, { "name": "dividerVertical", "format": [ "reference" ] }, { "name": "dividerHorizontal", "format": [ "reference" ] }, { "name": "buttonBarStyle", "format": [ "reference" ] }, { "name": "buttonBarButtonStyle", "format": [ "reference" ] }, { "name": "segmentedButtonStyle", "format": [ "reference" ] }, { "name": "selectableItemBackground", "format": [ "reference" ] }, { "name": "borderlessButtonStyle", "format": [ "reference" ] }, { "name": "toastFrameBackground", "format": [ "reference" ] }, { "name": "searchDropdownBackground", "format": [ "reference" ] }, { "name": "searchViewCloseIcon", "format": [ "reference" ] }, { "name": "searchViewGoIcon", "format": [ "reference" ] }, { "name": "searchViewSearchIcon", "format": [ "reference" ] }, { "name": "searchViewVoiceIcon", "format": [ "reference" ] }, { "name": "searchViewEditQuery", "format": [ "reference" ] }, { "name": "searchViewEditQueryBackground", "format": [ "reference" ] }, { "name": "searchViewTextField", "format": [ "reference" ] }, { "name": "searchViewTextFieldRight", "format": [ "reference" ] }, { "name": "searchDialogTheme", "format": [ "reference" ] }, { "name": "homeAsUpIndicator", "format": [ "reference" ] }, { "name": "preferenceFrameLayoutStyle", "format": [ "reference" ] }, { "name": "switchStyle", "format": [ "reference" ] }, { "name": "mediaRouteButtonStyle", "format": [ "reference" ] }, { "name": "pointerStyle", "format": [ "reference" ] }, { "name": "accessibilityFocusedDrawable", "format": [ "reference" ] }, { "name": "findOnPageNextDrawable", "format": [ "reference" ] }, { "name": "findOnPagePreviousDrawable", "format": [ "reference" ] } ] }, "Window": { "name": "Window", "attrs": [ { "name": "windowBackground", "format": [] }, { "name": "windowContentOverlay", "format": [] }, { "name": "windowFrame", "format": [] }, { "name": "windowNoTitle", "format": [] }, { "name": "windowFullscreen", "format": [] }, { "name": "windowOverscan", "format": [] }, { "name": "windowIsFloating", "format": [] }, { "name": "windowIsTranslucent", "format": [] }, { "name": "windowShowWallpaper", "format": [] }, { "name": "windowAnimationStyle", "format": [] }, { "name": "windowSoftInputMode", "format": [] }, { "name": "windowDisablePreview", "format": [] }, { "name": "windowNoDisplay", "format": [] }, { "name": "textColor", "format": [] }, { "name": "backgroundDimEnabled", "format": [] }, { "name": "backgroundDimAmount", "format": [] }, { "name": "windowActionBar", "format": [] }, { "name": "windowActionModeOverlay", "format": [] }, { "name": "windowActionBarOverlay", "format": [] }, { "name": "windowSplitActionBar", "format": [] }, { "name": "windowEnableSplitTouch", "format": [] }, { "name": "windowCloseOnTouchOutside", "format": [] }, { "name": "windowTranslucentStatus", "format": [] }, { "name": "windowTranslucentNavigation", "format": [] }, { "name": "windowMinWidthMajor", "format": [ "dimension", "fraction" ] }, { "name": "windowMinWidthMinor", "format": [ "dimension", "fraction" ] }, { "name": "windowFixedWidthMajor", "format": [ "dimension", "fraction" ] }, { "name": "windowFixedHeightMinor", "format": [ "dimension", "fraction" ] }, { "name": "windowFixedWidthMinor", "format": [ "dimension", "fraction" ] }, { "name": "windowFixedHeightMajor", "format": [ "dimension", "fraction" ] } ] }, "AlertDialog": { "name": "AlertDialog", "attrs": [ { "name": "fullDark", "format": [ "reference", "color" ] }, { "name": "topDark", "format": [ "reference", "color" ] }, { "name": "centerDark", "format": [ "reference", "color" ] }, { "name": "bottomDark", "format": [ "reference", "color" ] }, { "name": "fullBright", "format": [ "reference", "color" ] }, { "name": "topBright", "format": [ "reference", "color" ] }, { "name": "centerBright", "format": [ "reference", "color" ] }, { "name": "bottomBright", "format": [ "reference", "color" ] }, { "name": "bottomMedium", "format": [ "reference", "color" ] }, { "name": "centerMedium", "format": [ "reference", "color" ] }, { "name": "layout", "format": [] }, { "name": "listLayout", "format": [ "reference" ] }, { "name": "multiChoiceItemLayout", "format": [ "reference" ] }, { "name": "singleChoiceItemLayout", "format": [ "reference" ] }, { "name": "listItemLayout", "format": [ "reference" ] }, { "name": "progressLayout", "format": [ "reference" ] }, { "name": "horizontalProgressLayout", "format": [ "reference" ] } ] }, "FragmentAnimation": { "name": "FragmentAnimation", "attrs": [ { "name": "fragmentOpenEnterAnimation", "format": [ "reference" ] }, { "name": "fragmentOpenExitAnimation", "format": [ "reference" ] }, { "name": "fragmentCloseEnterAnimation", "format": [ "reference" ] }, { "name": "fragmentCloseExitAnimation", "format": [ "reference" ] }, { "name": "fragmentFadeEnterAnimation", "format": [ "reference" ] }, { "name": "fragmentFadeExitAnimation", "format": [ "reference" ] } ] }, "WindowAnimation": { "name": "WindowAnimation", "attrs": [ { "name": "windowEnterAnimation", "format": [ "reference" ] }, { "name": "windowExitAnimation", "format": [ "reference" ] }, { "name": "windowShowAnimation", "format": [ "reference" ] }, { "name": "windowHideAnimation", "format": [ "reference" ] }, { "name": "activityOpenEnterAnimation", "format": [ "reference" ] }, { "name": "activityOpenExitAnimation", "format": [ "reference" ] }, { "name": "activityCloseEnterAnimation", "format": [ "reference" ] }, { "name": "activityCloseExitAnimation", "format": [ "reference" ] }, { "name": "taskOpenEnterAnimation", "format": [ "reference" ] }, { "name": "taskOpenExitAnimation", "format": [ "reference" ] }, { "name": "taskCloseEnterAnimation", "format": [ "reference" ] }, { "name": "taskCloseExitAnimation", "format": [ "reference" ] }, { "name": "taskToFrontEnterAnimation", "format": [ "reference" ] }, { "name": "taskToFrontExitAnimation", "format": [ "reference" ] }, { "name": "taskToBackEnterAnimation", "format": [ "reference" ] }, { "name": "taskToBackExitAnimation", "format": [ "reference" ] }, { "name": "wallpaperOpenEnterAnimation", "format": [ "reference" ] }, { "name": "wallpaperOpenExitAnimation", "format": [ "reference" ] }, { "name": "wallpaperCloseEnterAnimation", "format": [ "reference" ] }, { "name": "wallpaperCloseExitAnimation", "format": [ "reference" ] }, { "name": "wallpaperIntraOpenEnterAnimation", "format": [ "reference" ] }, { "name": "wallpaperIntraOpenExitAnimation", "format": [ "reference" ] }, { "name": "wallpaperIntraCloseEnterAnimation", "format": [ "reference" ] }, { "name": "wallpaperIntraCloseExitAnimation", "format": [ "reference" ] } ] }, "View": { "name": "View", "attrs": [ { "name": "id", "format": [ "reference" ] }, { "name": "tag", "format": [ "string" ] }, { "name": "scrollX", "format": [ "dimension" ] }, { "name": "scrollY", "format": [ "dimension" ] }, { "name": "background", "format": [ "reference", "color" ] }, { "name": "padding", "format": [ "dimension" ] }, { "name": "paddingLeft", "format": [ "dimension" ] }, { "name": "paddingTop", "format": [ "dimension" ] }, { "name": "paddingRight", "format": [ "dimension" ] }, { "name": "paddingBottom", "format": [ "dimension" ] }, { "name": "paddingStart", "format": [ "dimension" ] }, { "name": "paddingEnd", "format": [ "dimension" ] }, { "name": "focusable", "format": [ "boolean" ] }, { "name": "focusableInTouchMode", "format": [ "boolean" ] }, { "name": "visibility", "format": [ "enum" ], "enum": [ { "name": "visible", "value": "0" }, { "name": "invisible", "value": "1" }, { "name": "gone", "value": "2" } ] }, { "name": "fitsSystemWindows", "format": [ "boolean" ] }, { "name": "scrollbars", "format": [ "flags" ], "flags": [ { "name": "horizontal", "value": "0x00000100" }, { "name": "vertical", "value": "0x00000200" } ] }, { "name": "scrollbarStyle", "format": [ "enum" ], "enum": [ { "name": "insideOverlay", "value": "0x0" }, { "name": "insideInset", "value": "0x01000000" }, { "name": "outsideOverlay", "value": "0x02000000" }, { "name": "outsideInset", "value": "0x03000000" } ] }, { "name": "isScrollContainer", "format": [ "boolean" ] }, { "name": "fadeScrollbars", "format": [ "boolean" ] }, { "name": "scrollbarFadeDuration", "format": [ "integer" ] }, { "name": "scrollbarDefaultDelayBeforeFade", "format": [ "integer" ] }, { "name": "scrollbarSize", "format": [ "dimension" ] }, { "name": "scrollbarThumbHorizontal", "format": [ "reference" ] }, { "name": "scrollbarThumbVertical", "format": [ "reference" ] }, { "name": "scrollbarTrackHorizontal", "format": [ "reference" ] }, { "name": "scrollbarTrackVertical", "format": [ "reference" ] }, { "name": "scrollbarAlwaysDrawHorizontalTrack", "format": [ "boolean" ] }, { "name": "scrollbarAlwaysDrawVerticalTrack", "format": [ "boolean" ] }, { "name": "fadingEdge", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0x00000000" }, { "name": "horizontal", "value": "0x00001000" }, { "name": "vertical", "value": "0x00002000" } ] }, { "name": "requiresFadingEdge", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0x00000000" }, { "name": "horizontal", "value": "0x00001000" }, { "name": "vertical", "value": "0x00002000" } ] }, { "name": "fadingEdgeLength", "format": [ "dimension" ] }, { "name": "nextFocusLeft", "format": [ "reference" ] }, { "name": "nextFocusRight", "format": [ "reference" ] }, { "name": "nextFocusUp", "format": [ "reference" ] }, { "name": "nextFocusDown", "format": [ "reference" ] }, { "name": "nextFocusForward", "format": [ "reference" ] }, { "name": "clickable", "format": [ "boolean" ] }, { "name": "longClickable", "format": [ "boolean" ] }, { "name": "saveEnabled", "format": [ "boolean" ] }, { "name": "filterTouchesWhenObscured", "format": [ "boolean" ] }, { "name": "drawingCacheQuality", "format": [ "enum" ], "enum": [ { "name": "auto", "value": "0" }, { "name": "low", "value": "1" }, { "name": "high", "value": "2" } ] }, { "name": "keepScreenOn", "format": [ "boolean" ] }, { "name": "duplicateParentState", "format": [ "boolean" ] }, { "name": "minHeight", "format": [] }, { "name": "minWidth", "format": [] }, { "name": "soundEffectsEnabled", "format": [ "boolean" ] }, { "name": "hapticFeedbackEnabled", "format": [ "boolean" ] }, { "name": "contentDescription", "format": [ "string" ] }, { "name": "onClick", "format": [ "string" ] }, { "name": "overScrollMode", "format": [ "enum" ], "enum": [ { "name": "always", "value": "0" }, { "name": "ifContentScrolls", "value": "1" }, { "name": "never", "value": "2" } ] }, { "name": "alpha", "format": [ "float" ] }, { "name": "translationX", "format": [ "dimension" ] }, { "name": "translationY", "format": [ "dimension" ] }, { "name": "transformPivotX", "format": [ "dimension" ] }, { "name": "transformPivotY", "format": [ "dimension" ] }, { "name": "rotation", "format": [ "float" ] }, { "name": "rotationX", "format": [ "float" ] }, { "name": "rotationY", "format": [ "float" ] }, { "name": "scaleX", "format": [ "float" ] }, { "name": "scaleY", "format": [ "float" ] }, { "name": "verticalScrollbarPosition", "format": [ "enum" ], "enum": [ { "name": "defaultPosition", "value": "0" }, { "name": "left", "value": "1" }, { "name": "right", "value": "2" } ] }, { "name": "layerType", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "software", "value": "1" }, { "name": "hardware", "value": "2" } ] }, { "name": "layoutDirection", "format": [ "enum" ], "enum": [ { "name": "ltr", "value": "0" }, { "name": "rtl", "value": "1" }, { "name": "inherit", "value": "2" }, { "name": "locale", "value": "3" } ] }, { "name": "textDirection", "format": [ "integer", "enum" ], "enum": [ { "name": "inherit", "value": "0" }, { "name": "firstStrong", "value": "1" }, { "name": "anyRtl", "value": "2" }, { "name": "ltr", "value": "3" }, { "name": "rtl", "value": "4" }, { "name": "locale", "value": "5" } ] }, { "name": "textAlignment", "format": [ "integer", "enum" ], "enum": [ { "name": "inherit", "value": "0" }, { "name": "gravity", "value": "1" }, { "name": "textStart", "value": "2" }, { "name": "textEnd", "value": "3" }, { "name": "center", "value": "4" }, { "name": "viewStart", "value": "5" }, { "name": "viewEnd", "value": "6" } ] }, { "name": "importantForAccessibility", "format": [ "integer", "enum" ], "enum": [ { "name": "auto", "value": "0" }, { "name": "yes", "value": "1" }, { "name": "no", "value": "2" }, { "name": "noHideDescendants", "value": "4" } ] }, { "name": "accessibilityLiveRegion", "format": [ "integer", "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "polite", "value": "1" }, { "name": "assertive", "value": "2" } ] }, { "name": "labelFor", "format": [ "integer" ] } ] }, "ViewGroup": { "name": "ViewGroup", "attrs": [ { "name": "animateLayoutChanges", "format": [ "boolean" ] }, { "name": "clipChildren", "format": [ "boolean" ] }, { "name": "clipToPadding", "format": [ "boolean" ] }, { "name": "layoutAnimation", "format": [ "reference" ] }, { "name": "animationCache", "format": [ "boolean" ] }, { "name": "persistentDrawingCache", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0x0" }, { "name": "animation", "value": "0x1" }, { "name": "scrolling", "value": "0x2" }, { "name": "all", "value": "0x3" } ] }, { "name": "alwaysDrawnWithCache", "format": [ "boolean" ] }, { "name": "addStatesFromChildren", "format": [ "boolean" ] }, { "name": "descendantFocusability", "format": [ "enum" ], "enum": [ { "name": "beforeDescendants", "value": "0" }, { "name": "afterDescendants", "value": "1" }, { "name": "blocksDescendants", "value": "2" } ] }, { "name": "splitMotionEvents", "format": [ "boolean" ] }, { "name": "layoutMode", "format": [ "enum" ], "enum": [ { "name": "clipBounds", "value": "0" }, { "name": "opticalBounds", "value": "1" } ] } ] }, "ViewStub": { "name": "ViewStub", "attrs": [ { "name": "layout", "format": [ "reference" ] }, { "name": "inflatedId", "format": [ "reference" ] } ] }, "ViewGroup_Layout": { "name": "ViewGroup_Layout", "attrs": [ { "name": "layout_width", "format": [ "dimension", "enum" ], "enum": [ { "name": "fill_parent", "value": "-1" }, { "name": "match_parent", "value": "-1" }, { "name": "wrap_content", "value": "-2" } ] }, { "name": "layout_height", "format": [ "dimension", "enum" ], "enum": [ { "name": "fill_parent", "value": "-1" }, { "name": "match_parent", "value": "-1" }, { "name": "wrap_content", "value": "-2" } ] } ] }, "ViewGroup_MarginLayout": { "name": "ViewGroup_MarginLayout", "attrs": [ { "name": "layout_width", "format": [] }, { "name": "layout_height", "format": [] }, { "name": "layout_margin", "format": [ "dimension" ] }, { "name": "layout_marginLeft", "format": [ "dimension" ] }, { "name": "layout_marginTop", "format": [ "dimension" ] }, { "name": "layout_marginRight", "format": [ "dimension" ] }, { "name": "layout_marginBottom", "format": [ "dimension" ] }, { "name": "layout_marginStart", "format": [ "dimension" ] }, { "name": "layout_marginEnd", "format": [ "dimension" ] } ] }, "InputMethod": { "name": "InputMethod", "attrs": [ { "name": "settingsActivity", "format": [ "string" ] }, { "name": "isDefault", "format": [ "boolean" ] }, { "name": "supportsSwitchingToNextInputMethod", "format": [ "boolean" ] } ] }, "InputMethod_Subtype": { "name": "InputMethod_Subtype", "attrs": [ { "name": "label", "format": [] }, { "name": "icon", "format": [] }, { "name": "imeSubtypeLocale", "format": [ "string" ] }, { "name": "imeSubtypeMode", "format": [ "string" ] }, { "name": "isAuxiliary", "format": [ "boolean" ] }, { "name": "overridesImplicitlyEnabledSubtype", "format": [ "boolean" ] }, { "name": "imeSubtypeExtraValue", "format": [ "string" ] }, { "name": "subtypeId", "format": [ "integer" ] }, { "name": "isAsciiCapable", "format": [ "boolean" ] } ] }, "SpellChecker": { "name": "SpellChecker", "attrs": [ { "name": "label", "format": [] }, { "name": "settingsActivity", "format": [] } ] }, "SpellChecker_Subtype": { "name": "SpellChecker_Subtype", "attrs": [ { "name": "label", "format": [] }, { "name": "subtypeLocale", "format": [ "string" ] }, { "name": "subtypeExtraValue", "format": [ "string" ] } ] }, "AccessibilityService": { "name": "AccessibilityService", "attrs": [ { "name": "accessibilityEventTypes", "format": [ "flags" ], "flags": [ { "name": "typeViewClicked", "value": "0x00000001" }, { "name": "typeViewLongClicked", "value": "0x00000002" }, { "name": "typeViewSelected", "value": "0x00000004" }, { "name": "typeViewFocused", "value": "0x00000008" }, { "name": "typeViewTextChanged", "value": "0x00000010" }, { "name": "typeWindowStateChanged", "value": "0x00000020" }, { "name": "typeNotificationStateChanged", "value": "0x00000040" }, { "name": "typeViewHoverEnter", "value": "0x00000080" }, { "name": "typeViewHoverExit", "value": "0x00000100" }, { "name": "typeTouchExplorationGestureStart", "value": "0x00000200" }, { "name": "typeTouchExplorationGestureEnd", "value": "0x00000400" }, { "name": "typeWindowContentChanged", "value": "0x00000800" }, { "name": "typeViewScrolled", "value": "0x000001000" }, { "name": "typeViewTextSelectionChanged", "value": "0x000002000" }, { "name": "typeAllMask", "value": "0xffffffff" } ] }, { "name": "packageNames", "format": [ "string" ] }, { "name": "accessibilityFeedbackType", "format": [ "flags" ], "flags": [ { "name": "feedbackSpoken", "value": "0x00000001" }, { "name": "feedbackHaptic", "value": "0x00000002" }, { "name": "feedbackAudible", "value": "0x00000004" }, { "name": "feedbackVisual", "value": "0x00000008" }, { "name": "feedbackGeneric", "value": "0x00000010" }, { "name": "feedbackAllMask", "value": "0xffffffff" } ] }, { "name": "notificationTimeout", "format": [ "integer" ] }, { "name": "accessibilityFlags", "format": [ "flags" ], "flags": [ { "name": "flagDefault", "value": "0x00000001" }, { "name": "flagIncludeNotImportantViews", "value": "0x00000002" }, { "name": "flagRequestTouchExplorationMode", "value": "0x00000004" }, { "name": "flagRequestEnhancedWebAccessibility", "value": "0x00000008" }, { "name": "flagReportViewIds", "value": "0x00000010" }, { "name": "flagRequestFilterKeyEvents", "value": "0x00000020" } ] }, { "name": "settingsActivity", "format": [] }, { "name": "canRetrieveWindowContent", "format": [ "boolean" ] }, { "name": "canRequestTouchExplorationMode", "format": [ "boolean" ] }, { "name": "canRequestEnhancedWebAccessibility", "format": [ "boolean" ] }, { "name": "canRequestFilterKeyEvents", "format": [ "boolean" ] }, { "name": "description", "format": [] } ] }, "PrintService": { "name": "PrintService", "attrs": [ { "name": "settingsActivity", "format": [] }, { "name": "addPrintersActivity", "format": [ "string" ] }, { "name": "advancedPrintOptionsActivity", "format": [ "string" ] }, { "name": "vendor", "format": [ "string" ] } ] }, "HostApduService": { "name": "HostApduService", "attrs": [ { "name": "description", "format": [] }, { "name": "requireDeviceUnlock", "format": [ "boolean" ] }, { "name": "apduServiceBanner", "format": [ "reference" ] } ] }, "OffHostApduService": { "name": "OffHostApduService", "attrs": [ { "name": "description", "format": [] }, { "name": "apduServiceBanner", "format": [] } ] }, "AidGroup": { "name": "AidGroup", "attrs": [ { "name": "description", "format": [] }, { "name": "category", "format": [ "string" ] } ] }, "AidFilter": { "name": "AidFilter", "attrs": [ { "name": "name", "format": [] } ] }, "ActionMenuItemView": { "name": "ActionMenuItemView", "attrs": [ { "name": "minWidth", "format": [] } ] }, "AbsListView": { "name": "AbsListView", "attrs": [ { "name": "listSelector", "format": [ "color", "reference" ] }, { "name": "drawSelectorOnTop", "format": [ "boolean" ] }, { "name": "stackFromBottom", "format": [ "boolean" ] }, { "name": "scrollingCache", "format": [ "boolean" ] }, { "name": "textFilterEnabled", "format": [ "boolean" ] }, { "name": "transcriptMode", "format": [ "enum" ], "enum": [ { "name": "disabled", "value": "0" }, { "name": "normal", "value": "1" }, { "name": "alwaysScroll", "value": "2" } ] }, { "name": "cacheColorHint", "format": [ "color" ] }, { "name": "fastScrollEnabled", "format": [ "boolean" ] }, { "name": "smoothScrollbar", "format": [ "boolean" ] }, { "name": "choiceMode", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "singleChoice", "value": "1" }, { "name": "multipleChoice", "value": "2" }, { "name": "multipleChoiceModal", "value": "3" } ] }, { "name": "fastScrollAlwaysVisible", "format": [ "boolean" ] } ] }, "AbsSpinner": { "name": "AbsSpinner", "attrs": [ { "name": "entries", "format": [] } ] }, "AnalogClock": { "name": "AnalogClock", "attrs": [ { "name": "dial", "format": [ "reference" ] }, { "name": "hand_hour", "format": [ "reference" ] }, { "name": "hand_minute", "format": [ "reference" ] } ] }, "Button": { "name": "Button", "attrs": [] }, "Chronometer": { "name": "Chronometer", "attrs": [ { "name": "format", "format": [ "string" ] } ] }, "CompoundButton": { "name": "CompoundButton", "attrs": [ { "name": "checked", "format": [ "boolean" ] }, { "name": "button", "format": [ "reference" ] } ] }, "CheckedTextView": { "name": "CheckedTextView", "attrs": [ { "name": "checked", "format": [] }, { "name": "checkMark", "format": [ "reference" ] } ] }, "EditText": { "name": "EditText", "attrs": [] }, "FrameLayout": { "name": "FrameLayout", "attrs": [ { "name": "foreground", "format": [ "reference", "color" ] }, { "name": "foregroundGravity", "format": [ "flags" ], "flags": [ { "name": "top", "value": "0x30" }, { "name": "bottom", "value": "0x50" }, { "name": "left", "value": "0x03" }, { "name": "right", "value": "0x05" }, { "name": "center_vertical", "value": "0x10" }, { "name": "fill_vertical", "value": "0x70" }, { "name": "center_horizontal", "value": "0x01" }, { "name": "fill_horizontal", "value": "0x07" }, { "name": "center", "value": "0x11" }, { "name": "fill", "value": "0x77" }, { "name": "clip_vertical", "value": "0x80" }, { "name": "clip_horizontal", "value": "0x08" } ] }, { "name": "foregroundInsidePadding", "format": [ "boolean" ] }, { "name": "measureAllChildren", "format": [ "boolean" ] } ] }, "ExpandableListView": { "name": "ExpandableListView", "attrs": [ { "name": "groupIndicator", "format": [ "reference" ] }, { "name": "childIndicator", "format": [ "reference" ] }, { "name": "indicatorLeft", "format": [ "dimension" ] }, { "name": "indicatorRight", "format": [ "dimension" ] }, { "name": "childIndicatorLeft", "format": [ "dimension" ] }, { "name": "childIndicatorRight", "format": [ "dimension" ] }, { "name": "childDivider", "format": [ "reference", "color" ] }, { "name": "indicatorStart", "format": [ "dimension" ] }, { "name": "indicatorEnd", "format": [ "dimension" ] }, { "name": "childIndicatorStart", "format": [ "dimension" ] }, { "name": "childIndicatorEnd", "format": [ "dimension" ] } ] }, "Gallery": { "name": "Gallery", "attrs": [ { "name": "gravity", "format": [] }, { "name": "animationDuration", "format": [ "integer" ] }, { "name": "spacing", "format": [ "dimension" ] }, { "name": "unselectedAlpha", "format": [ "float" ] } ] }, "GridView": { "name": "GridView", "attrs": [ { "name": "horizontalSpacing", "format": [ "dimension" ] }, { "name": "verticalSpacing", "format": [ "dimension" ] }, { "name": "stretchMode", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "spacingWidth", "value": "1" }, { "name": "columnWidth", "value": "2" }, { "name": "spacingWidthUniform", "value": "3" } ] }, { "name": "columnWidth", "format": [ "dimension" ] }, { "name": "numColumns", "format": [ "integer", "enum" ], "enum": [ { "name": "auto_fit", "value": "-1" } ] }, { "name": "gravity", "format": [] } ] }, "ImageSwitcher": { "name": "ImageSwitcher", "attrs": [] }, "ImageView": { "name": "ImageView", "attrs": [ { "name": "src", "format": [ "reference", "color" ] }, { "name": "scaleType", "format": [ "enum" ], "enum": [ { "name": "matrix", "value": "0" }, { "name": "fitXY", "value": "1" }, { "name": "fitStart", "value": "2" }, { "name": "fitCenter", "value": "3" }, { "name": "fitEnd", "value": "4" }, { "name": "center", "value": "5" }, { "name": "centerCrop", "value": "6" }, { "name": "centerInside", "value": "7" } ] }, { "name": "adjustViewBounds", "format": [ "boolean" ] }, { "name": "maxWidth", "format": [ "dimension" ] }, { "name": "maxHeight", "format": [ "dimension" ] }, { "name": "tint", "format": [ "color" ] }, { "name": "baselineAlignBottom", "format": [ "boolean" ] }, { "name": "cropToPadding", "format": [ "boolean" ] }, { "name": "baseline", "format": [ "dimension" ] }, { "name": "drawableAlpha", "format": [ "integer" ] } ] }, "ToggleButton": { "name": "ToggleButton", "attrs": [ { "name": "textOn", "format": [ "string" ] }, { "name": "textOff", "format": [ "string" ] }, { "name": "disabledAlpha", "format": [] } ] }, "RelativeLayout": { "name": "RelativeLayout", "attrs": [ { "name": "gravity", "format": [] }, { "name": "ignoreGravity", "format": [ "reference" ] } ] }, "LinearLayout": { "name": "LinearLayout", "attrs": [ { "name": "orientation", "format": [] }, { "name": "gravity", "format": [] }, { "name": "baselineAligned", "format": [ "boolean" ] }, { "name": "baselineAlignedChildIndex", "format": [ "integer" ] }, { "name": "weightSum", "format": [ "float" ] }, { "name": "measureWithLargestChild", "format": [ "boolean" ] }, { "name": "divider", "format": [] }, { "name": "showDividers", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0" }, { "name": "beginning", "value": "1" }, { "name": "middle", "value": "2" }, { "name": "end", "value": "4" } ] }, { "name": "dividerPadding", "format": [ "dimension" ] } ] }, "GridLayout": { "name": "GridLayout", "attrs": [ { "name": "orientation", "format": [] }, { "name": "rowCount", "format": [ "integer" ] }, { "name": "columnCount", "format": [ "integer" ] }, { "name": "useDefaultMargins", "format": [ "boolean" ] }, { "name": "alignmentMode", "format": [] }, { "name": "rowOrderPreserved", "format": [ "boolean" ] }, { "name": "columnOrderPreserved", "format": [ "boolean" ] } ] }, "ListView": { "name": "ListView", "attrs": [ { "name": "entries", "format": [] }, { "name": "divider", "format": [ "reference", "color" ] }, { "name": "dividerHeight", "format": [ "dimension" ] }, { "name": "headerDividersEnabled", "format": [ "boolean" ] }, { "name": "footerDividersEnabled", "format": [ "boolean" ] }, { "name": "overScrollHeader", "format": [ "reference", "color" ] }, { "name": "overScrollFooter", "format": [ "reference", "color" ] } ] }, "PreferenceFrameLayout": { "name": "PreferenceFrameLayout", "attrs": [ { "name": "borderTop", "format": [ "dimension" ] }, { "name": "borderBottom", "format": [ "dimension" ] }, { "name": "borderLeft", "format": [ "dimension" ] }, { "name": "borderRight", "format": [ "dimension" ] } ] }, "PreferenceFrameLayout_Layout": { "name": "PreferenceFrameLayout_Layout", "attrs": [ { "name": "layout_removeBorders", "format": [ "boolean" ] } ] }, "MenuView": { "name": "MenuView", "attrs": [ { "name": "itemTextAppearance", "format": [ "reference" ] }, { "name": "horizontalDivider", "format": [ "reference" ] }, { "name": "verticalDivider", "format": [ "reference" ] }, { "name": "headerBackground", "format": [ "color", "reference" ] }, { "name": "itemBackground", "format": [ "color", "reference" ] }, { "name": "windowAnimationStyle", "format": [] }, { "name": "itemIconDisabledAlpha", "format": [ "float" ] }, { "name": "preserveIconSpacing", "format": [ "boolean" ] } ] }, "IconMenuView": { "name": "IconMenuView", "attrs": [ { "name": "rowHeight", "format": [ "dimension" ] }, { "name": "maxRows", "format": [ "integer" ] }, { "name": "maxItemsPerRow", "format": [ "integer" ] }, { "name": "maxItems", "format": [ "integer" ] }, { "name": "moreIcon", "format": [ "reference" ] } ] }, "ProgressBar": { "name": "ProgressBar", "attrs": [ { "name": "max", "format": [ "integer" ] }, { "name": "progress", "format": [ "integer" ] }, { "name": "secondaryProgress", "format": [ "integer" ] }, { "name": "indeterminate", "format": [ "boolean" ] }, { "name": "indeterminateOnly", "format": [ "boolean" ] }, { "name": "indeterminateDrawable", "format": [ "reference" ] }, { "name": "progressDrawable", "format": [ "reference" ] }, { "name": "indeterminateDuration", "format": [ "integer" ] }, { "name": "indeterminateBehavior", "format": [ "enum" ], "enum": [ { "name": "repeat", "value": "1" }, { "name": "cycle", "value": "2" } ] }, { "name": "minWidth", "format": [ "dimension" ] }, { "name": "maxWidth", "format": [] }, { "name": "minHeight", "format": [ "dimension" ] }, { "name": "maxHeight", "format": [] }, { "name": "interpolator", "format": [ "reference" ] }, { "name": "animationResolution", "format": [ "integer" ] }, { "name": "mirrorForRtl", "format": [ "boolean" ] } ] }, "SeekBar": { "name": "SeekBar", "attrs": [ { "name": "thumb", "format": [ "reference" ] }, { "name": "thumbOffset", "format": [ "dimension" ] } ] }, "StackView": { "name": "StackView", "attrs": [ { "name": "resOutColor", "format": [ "color" ] }, { "name": "clickColor", "format": [ "color" ] } ] }, "RatingBar": { "name": "RatingBar", "attrs": [ { "name": "numStars", "format": [ "integer" ] }, { "name": "rating", "format": [ "float" ] }, { "name": "stepSize", "format": [ "float" ] }, { "name": "isIndicator", "format": [ "boolean" ] } ] }, "RadioGroup": { "name": "RadioGroup", "attrs": [ { "name": "checkedButton", "format": [ "integer" ] }, { "name": "orientation", "format": [] } ] }, "TableLayout": { "name": "TableLayout", "attrs": [ { "name": "stretchColumns", "format": [ "string" ] }, { "name": "shrinkColumns", "format": [ "string" ] }, { "name": "collapseColumns", "format": [ "string" ] } ] }, "TableRow": { "name": "TableRow", "attrs": [] }, "TableRow_Cell": { "name": "TableRow_Cell", "attrs": [ { "name": "layout_column", "format": [ "integer" ] }, { "name": "layout_span", "format": [ "integer" ] } ] }, "TabWidget": { "name": "TabWidget", "attrs": [ { "name": "divider", "format": [] }, { "name": "tabStripEnabled", "format": [ "boolean" ] }, { "name": "tabStripLeft", "format": [ "reference" ] }, { "name": "tabStripRight", "format": [ "reference" ] }, { "name": "tabLayout", "format": [ "reference" ] } ] }, "TextAppearance": { "name": "TextAppearance", "attrs": [ { "name": "textColor", "format": [] }, { "name": "textSize", "format": [] }, { "name": "textStyle", "format": [] }, { "name": "typeface", "format": [] }, { "name": "fontFamily", "format": [] }, { "name": "textColorHighlight", "format": [] }, { "name": "textColorHint", "format": [] }, { "name": "textColorLink", "format": [] }, { "name": "textAllCaps", "format": [ "boolean" ] }, { "name": "shadowColor", "format": [ "color" ] }, { "name": "shadowDx", "format": [ "float" ] }, { "name": "shadowDy", "format": [ "float" ] }, { "name": "shadowRadius", "format": [ "float" ] } ] }, "TextClock": { "name": "TextClock", "attrs": [ { "name": "format12Hour", "format": [ "string" ] }, { "name": "format24Hour", "format": [ "string" ] }, { "name": "timeZone", "format": [ "string" ] } ] }, "TextSwitcher": { "name": "TextSwitcher", "attrs": [] }, "TextView": { "name": "TextView", "attrs": [ { "name": "bufferType", "format": [ "enum" ], "enum": [ { "name": "normal", "value": "0" }, { "name": "spannable", "value": "1" }, { "name": "editable", "value": "2" } ] }, { "name": "text", "format": [ "string" ] }, { "name": "hint", "format": [ "string" ] }, { "name": "textColor", "format": [] }, { "name": "textColorHighlight", "format": [] }, { "name": "textColorHint", "format": [] }, { "name": "textAppearance", "format": [] }, { "name": "textSize", "format": [] }, { "name": "textScaleX", "format": [ "float" ] }, { "name": "typeface", "format": [] }, { "name": "textStyle", "format": [] }, { "name": "fontFamily", "format": [] }, { "name": "textColorLink", "format": [] }, { "name": "cursorVisible", "format": [ "boolean" ] }, { "name": "maxLines", "format": [ "integer" ] }, { "name": "maxHeight", "format": [] }, { "name": "lines", "format": [ "integer" ] }, { "name": "height", "format": [ "dimension" ] }, { "name": "minLines", "format": [ "integer" ] }, { "name": "minHeight", "format": [] }, { "name": "maxEms", "format": [ "integer" ] }, { "name": "maxWidth", "format": [] }, { "name": "ems", "format": [ "integer" ] }, { "name": "width", "format": [ "dimension" ] }, { "name": "minEms", "format": [ "integer" ] }, { "name": "minWidth", "format": [] }, { "name": "gravity", "format": [] }, { "name": "scrollHorizontally", "format": [ "boolean" ] }, { "name": "password", "format": [ "boolean" ] }, { "name": "singleLine", "format": [ "boolean" ] }, { "name": "enabled", "format": [ "boolean" ] }, { "name": "selectAllOnFocus", "format": [ "boolean" ] }, { "name": "includeFontPadding", "format": [ "boolean" ] }, { "name": "maxLength", "format": [ "integer" ] }, { "name": "shadowColor", "format": [] }, { "name": "shadowDx", "format": [] }, { "name": "shadowDy", "format": [] }, { "name": "shadowRadius", "format": [] }, { "name": "autoLink", "format": [] }, { "name": "linksClickable", "format": [ "boolean" ] }, { "name": "numeric", "format": [ "flags" ], "flags": [ { "name": "integer", "value": "0x01" }, { "name": "signed", "value": "0x03" }, { "name": "decimal", "value": "0x05" } ] }, { "name": "digits", "format": [ "string" ] }, { "name": "phoneNumber", "format": [ "boolean" ] }, { "name": "inputMethod", "format": [ "string" ] }, { "name": "capitalize", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "sentences", "value": "1" }, { "name": "words", "value": "2" }, { "name": "characters", "value": "3" } ] }, { "name": "autoText", "format": [ "boolean" ] }, { "name": "editable", "format": [ "boolean" ] }, { "name": "freezesText", "format": [ "boolean" ] }, { "name": "ellipsize", "format": [] }, { "name": "drawableTop", "format": [ "reference", "color" ] }, { "name": "drawableBottom", "format": [ "reference", "color" ] }, { "name": "drawableLeft", "format": [ "reference", "color" ] }, { "name": "drawableRight", "format": [ "reference", "color" ] }, { "name": "drawableStart", "format": [ "reference", "color" ] }, { "name": "drawableEnd", "format": [ "reference", "color" ] }, { "name": "drawablePadding", "format": [ "dimension" ] }, { "name": "lineSpacingExtra", "format": [ "dimension" ] }, { "name": "lineSpacingMultiplier", "format": [ "float" ] }, { "name": "marqueeRepeatLimit", "format": [ "integer", "enum" ], "enum": [ { "name": "marquee_forever", "value": "-1" } ] }, { "name": "inputType", "format": [] }, { "name": "imeOptions", "format": [] }, { "name": "privateImeOptions", "format": [ "string" ] }, { "name": "imeActionLabel", "format": [ "string" ] }, { "name": "imeActionId", "format": [ "integer" ] }, { "name": "editorExtras", "format": [ "reference" ] }, { "name": "textSelectHandleLeft", "format": [] }, { "name": "textSelectHandleRight", "format": [] }, { "name": "textSelectHandle", "format": [] }, { "name": "textEditPasteWindowLayout", "format": [] }, { "name": "textEditNoPasteWindowLayout", "format": [] }, { "name": "textEditSidePasteWindowLayout", "format": [] }, { "name": "textEditSideNoPasteWindowLayout", "format": [] }, { "name": "textEditSuggestionItemLayout", "format": [] }, { "name": "textCursorDrawable", "format": [] }, { "name": "textIsSelectable", "format": [] }, { "name": "textAllCaps", "format": [] } ] }, "TextViewAppearance": { "name": "TextViewAppearance", "attrs": [ { "name": "textAppearance", "format": [] } ] }, "SelectionModeDrawables": { "name": "SelectionModeDrawables", "attrs": [ { "name": "actionModeSelectAllDrawable", "format": [] }, { "name": "actionModeCutDrawable", "format": [] }, { "name": "actionModeCopyDrawable", "format": [] }, { "name": "actionModePasteDrawable", "format": [] } ] }, "SuggestionSpan": { "name": "SuggestionSpan", "attrs": [ { "name": "textUnderlineColor", "format": [] }, { "name": "textUnderlineThickness", "format": [] } ] }, "InputExtras": { "name": "InputExtras", "attrs": [] }, "AutoCompleteTextView": { "name": "AutoCompleteTextView", "attrs": [ { "name": "completionHint", "format": [ "string" ] }, { "name": "completionHintView", "format": [ "reference" ] }, { "name": "completionThreshold", "format": [ "integer" ] }, { "name": "dropDownSelector", "format": [ "reference", "color" ] }, { "name": "dropDownVerticalOffset", "format": [ "dimension" ] }, { "name": "dropDownHorizontalOffset", "format": [ "dimension" ] }, { "name": "dropDownAnchor", "format": [ "reference" ] }, { "name": "dropDownWidth", "format": [ "dimension", "enum" ], "enum": [ { "name": "fill_parent", "value": "-1" }, { "name": "match_parent", "value": "-1" }, { "name": "wrap_content", "value": "-2" } ] }, { "name": "dropDownHeight", "format": [ "dimension", "enum" ], "enum": [ { "name": "fill_parent", "value": "-1" }, { "name": "match_parent", "value": "-1" }, { "name": "wrap_content", "value": "-2" } ] }, { "name": "inputType", "format": [] } ] }, "PopupWindow": { "name": "PopupWindow", "attrs": [ { "name": "popupBackground", "format": [ "reference", "color" ] }, { "name": "popupAnimationStyle", "format": [ "reference" ] } ] }, "ViewAnimator": { "name": "ViewAnimator", "attrs": [ { "name": "inAnimation", "format": [ "reference" ] }, { "name": "outAnimation", "format": [ "reference" ] }, { "name": "animateFirstView", "format": [ "boolean" ] } ] }, "ViewFlipper": { "name": "ViewFlipper", "attrs": [ { "name": "flipInterval", "format": [ "integer" ] }, { "name": "autoStart", "format": [ "boolean" ] } ] }, "AdapterViewAnimator": { "name": "AdapterViewAnimator", "attrs": [ { "name": "inAnimation", "format": [] }, { "name": "outAnimation", "format": [] }, { "name": "loopViews", "format": [ "boolean" ] }, { "name": "animateFirstView", "format": [] } ] }, "AdapterViewFlipper": { "name": "AdapterViewFlipper", "attrs": [ { "name": "flipInterval", "format": [] }, { "name": "autoStart", "format": [] } ] }, "ViewSwitcher": { "name": "ViewSwitcher", "attrs": [] }, "ScrollView": { "name": "ScrollView", "attrs": [ { "name": "fillViewport", "format": [ "boolean" ] } ] }, "HorizontalScrollView": { "name": "HorizontalScrollView", "attrs": [ { "name": "fillViewport", "format": [] } ] }, "Spinner": { "name": "Spinner", "attrs": [ { "name": "prompt", "format": [ "reference" ] }, { "name": "spinnerMode", "format": [ "enum" ], "enum": [ { "name": "dialog", "value": "0" }, { "name": "dropdown", "value": "1" } ] }, { "name": "dropDownSelector", "format": [] }, { "name": "popupBackground", "format": [] }, { "name": "dropDownVerticalOffset", "format": [] }, { "name": "dropDownHorizontalOffset", "format": [] }, { "name": "dropDownWidth", "format": [] }, { "name": "popupPromptView", "format": [ "reference" ] }, { "name": "gravity", "format": [] }, { "name": "disableChildrenWhenDisabled", "format": [ "boolean" ] } ] }, "DatePicker": { "name": "DatePicker", "attrs": [ { "name": "startYear", "format": [ "integer" ] }, { "name": "endYear", "format": [ "integer" ] }, { "name": "spinnersShown", "format": [ "boolean" ] }, { "name": "calendarViewShown", "format": [ "boolean" ] }, { "name": "minDate", "format": [ "string" ] }, { "name": "maxDate", "format": [ "string" ] }, { "name": "internalLayout", "format": [ "reference" ] } ] }, "TwoLineListItem": { "name": "TwoLineListItem", "attrs": [ { "name": "mode", "format": [ "enum" ], "enum": [ { "name": "oneLine", "value": "1" }, { "name": "collapsing", "value": "2" }, { "name": "twoLine", "value": "3" } ] } ] }, "SlidingDrawer": { "name": "SlidingDrawer", "attrs": [ { "name": "handle", "format": [ "reference" ] }, { "name": "content", "format": [ "reference" ] }, { "name": "orientation", "format": [] }, { "name": "bottomOffset", "format": [ "dimension" ] }, { "name": "topOffset", "format": [ "dimension" ] }, { "name": "allowSingleTap", "format": [ "boolean" ] }, { "name": "animateOnClick", "format": [ "boolean" ] } ] }, "GestureOverlayView": { "name": "GestureOverlayView", "attrs": [ { "name": "gestureStrokeWidth", "format": [ "float" ] }, { "name": "gestureColor", "format": [ "color" ] }, { "name": "uncertainGestureColor", "format": [ "color" ] }, { "name": "fadeOffset", "format": [ "integer" ] }, { "name": "fadeDuration", "format": [ "integer" ] }, { "name": "gestureStrokeType", "format": [ "enum" ], "enum": [ { "name": "single", "value": "0" }, { "name": "multiple", "value": "1" } ] }, { "name": "gestureStrokeLengthThreshold", "format": [ "float" ] }, { "name": "gestureStrokeSquarenessThreshold", "format": [ "float" ] }, { "name": "gestureStrokeAngleThreshold", "format": [ "float" ] }, { "name": "eventsInterceptionEnabled", "format": [ "boolean" ] }, { "name": "fadeEnabled", "format": [ "boolean" ] }, { "name": "orientation", "format": [] } ] }, "QuickContactBadge": { "name": "QuickContactBadge", "attrs": [ { "name": "quickContactWindowSize", "format": [ "enum" ], "enum": [ { "name": "modeSmall", "value": "1" }, { "name": "modeMedium", "value": "2" }, { "name": "modeLarge", "value": "3" } ] } ] }, "AbsoluteLayout_Layout": { "name": "AbsoluteLayout_Layout", "attrs": [ { "name": "layout_x", "format": [ "dimension" ] }, { "name": "layout_y", "format": [ "dimension" ] } ] }, "LinearLayout_Layout": { "name": "LinearLayout_Layout", "attrs": [ { "name": "layout_width", "format": [] }, { "name": "layout_height", "format": [] }, { "name": "layout_weight", "format": [ "float" ] }, { "name": "layout_gravity", "format": [] } ] }, "GridLayout_Layout": { "name": "GridLayout_Layout", "attrs": [ { "name": "layout_row", "format": [ "integer" ] }, { "name": "layout_rowSpan", "format": [ "integer" ] }, { "name": "layout_column", "format": [] }, { "name": "layout_columnSpan", "format": [ "integer" ] }, { "name": "layout_gravity", "format": [] } ] }, "FrameLayout_Layout": { "name": "FrameLayout_Layout", "attrs": [ { "name": "layout_gravity", "format": [] } ] }, "RelativeLayout_Layout": { "name": "RelativeLayout_Layout", "attrs": [ { "name": "layout_toLeftOf", "format": [ "reference" ] }, { "name": "layout_toRightOf", "format": [ "reference" ] }, { "name": "layout_above", "format": [ "reference" ] }, { "name": "layout_below", "format": [ "reference" ] }, { "name": "layout_alignBaseline", "format": [ "reference" ] }, { "name": "layout_alignLeft", "format": [ "reference" ] }, { "name": "layout_alignTop", "format": [ "reference" ] }, { "name": "layout_alignRight", "format": [ "reference" ] }, { "name": "layout_alignBottom", "format": [ "reference" ] }, { "name": "layout_alignParentLeft", "format": [ "boolean" ] }, { "name": "layout_alignParentTop", "format": [ "boolean" ] }, { "name": "layout_alignParentRight", "format": [ "boolean" ] }, { "name": "layout_alignParentBottom", "format": [ "boolean" ] }, { "name": "layout_centerInParent", "format": [ "boolean" ] }, { "name": "layout_centerHorizontal", "format": [ "boolean" ] }, { "name": "layout_centerVertical", "format": [ "boolean" ] }, { "name": "layout_alignWithParentIfMissing", "format": [ "boolean" ] }, { "name": "layout_toStartOf", "format": [ "reference" ] }, { "name": "layout_toEndOf", "format": [ "reference" ] }, { "name": "layout_alignStart", "format": [ "reference" ] }, { "name": "layout_alignEnd", "format": [ "reference" ] }, { "name": "layout_alignParentStart", "format": [ "boolean" ] }, { "name": "layout_alignParentEnd", "format": [ "boolean" ] } ] }, "VerticalSlider_Layout": { "name": "VerticalSlider_Layout", "attrs": [ { "name": "layout_scale", "format": [ "float" ] } ] }, "RotarySelector": { "name": "RotarySelector", "attrs": [ { "name": "orientation", "format": [] } ] }, "WeightedLinearLayout": { "name": "WeightedLinearLayout", "attrs": [ { "name": "majorWeightMin", "format": [ "float" ] }, { "name": "minorWeightMin", "format": [ "float" ] }, { "name": "majorWeightMax", "format": [ "float" ] }, { "name": "minorWeightMax", "format": [ "float" ] } ] }, "CalendarView": { "name": "CalendarView", "attrs": [ { "name": "firstDayOfWeek", "format": [ "integer" ] }, { "name": "showWeekNumber", "format": [ "boolean" ] }, { "name": "minDate", "format": [] }, { "name": "maxDate", "format": [] }, { "name": "shownWeekCount", "format": [ "integer" ] }, { "name": "selectedWeekBackgroundColor", "format": [ "color", "reference" ] }, { "name": "focusedMonthDateColor", "format": [ "color", "reference" ] }, { "name": "unfocusedMonthDateColor", "format": [ "color", "reference" ] }, { "name": "weekNumberColor", "format": [ "color", "reference" ] }, { "name": "weekSeparatorLineColor", "format": [ "color", "reference" ] }, { "name": "selectedDateVerticalBar", "format": [ "reference" ] }, { "name": "weekDayTextAppearance", "format": [ "reference" ] }, { "name": "dateTextAppearance", "format": [ "reference" ] } ] }, "NumberPicker": { "name": "NumberPicker", "attrs": [ { "name": "solidColor", "format": [ "color", "reference" ] }, { "name": "selectionDivider", "format": [ "reference" ] }, { "name": "selectionDividerHeight", "format": [ "dimension" ] }, { "name": "selectionDividersDistance", "format": [ "dimension" ] }, { "name": "internalMinHeight", "format": [ "dimension" ] }, { "name": "internalMaxHeight", "format": [ "dimension" ] }, { "name": "internalMinWidth", "format": [ "dimension" ] }, { "name": "internalMaxWidth", "format": [ "dimension" ] }, { "name": "internalLayout", "format": [] }, { "name": "virtualButtonPressedDrawable", "format": [ "reference" ] } ] }, "TimePicker": { "name": "TimePicker", "attrs": [ { "name": "internalLayout", "format": [] } ] }, "Drawable": { "name": "Drawable", "attrs": [ { "name": "visible", "format": [ "boolean" ] }, { "name": "autoMirrored", "format": [ "boolean" ] } ] }, "StateListDrawable": { "name": "StateListDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "variablePadding", "format": [ "boolean" ] }, { "name": "constantSize", "format": [ "boolean" ] }, { "name": "dither", "format": [ "boolean" ] }, { "name": "enterFadeDuration", "format": [ "integer" ] }, { "name": "exitFadeDuration", "format": [ "integer" ] }, { "name": "autoMirrored", "format": [] } ] }, "AnimationDrawable": { "name": "AnimationDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "variablePadding", "format": [] }, { "name": "oneshot", "format": [ "boolean" ] } ] }, "AnimationDrawableItem": { "name": "AnimationDrawableItem", "attrs": [ { "name": "duration", "format": [ "integer" ] }, { "name": "drawable", "format": [ "reference" ] } ] }, "GradientDrawable": { "name": "GradientDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "dither", "format": [] }, { "name": "shape", "format": [ "enum" ], "enum": [ { "name": "rectangle", "value": "0" }, { "name": "oval", "value": "1" }, { "name": "line", "value": "2" }, { "name": "ring", "value": "3" } ] }, { "name": "innerRadiusRatio", "format": [ "float" ] }, { "name": "thicknessRatio", "format": [ "float" ] }, { "name": "innerRadius", "format": [ "dimension" ] }, { "name": "thickness", "format": [ "dimension" ] }, { "name": "useLevel", "format": [] } ] }, "GradientDrawableSize": { "name": "GradientDrawableSize", "attrs": [ { "name": "width", "format": [] }, { "name": "height", "format": [] } ] }, "GradientDrawableGradient": { "name": "GradientDrawableGradient", "attrs": [ { "name": "startColor", "format": [ "color" ] }, { "name": "centerColor", "format": [ "color" ] }, { "name": "endColor", "format": [ "color" ] }, { "name": "useLevel", "format": [ "boolean" ] }, { "name": "angle", "format": [ "float" ] }, { "name": "type", "format": [ "enum" ], "enum": [ { "name": "linear", "value": "0" }, { "name": "radial", "value": "1" }, { "name": "sweep", "value": "2" } ] }, { "name": "centerX", "format": [ "float", "fraction" ] }, { "name": "centerY", "format": [ "float", "fraction" ] }, { "name": "gradientRadius", "format": [ "float", "fraction" ] } ] }, "GradientDrawableSolid": { "name": "GradientDrawableSolid", "attrs": [ { "name": "color", "format": [ "color" ] } ] }, "GradientDrawableStroke": { "name": "GradientDrawableStroke", "attrs": [ { "name": "width", "format": [] }, { "name": "color", "format": [] }, { "name": "dashWidth", "format": [ "dimension" ] }, { "name": "dashGap", "format": [ "dimension" ] } ] }, "DrawableCorners": { "name": "DrawableCorners", "attrs": [ { "name": "radius", "format": [ "dimension" ] }, { "name": "topLeftRadius", "format": [ "dimension" ] }, { "name": "topRightRadius", "format": [ "dimension" ] }, { "name": "bottomLeftRadius", "format": [ "dimension" ] }, { "name": "bottomRightRadius", "format": [ "dimension" ] } ] }, "GradientDrawablePadding": { "name": "GradientDrawablePadding", "attrs": [ { "name": "left", "format": [ "dimension" ] }, { "name": "top", "format": [ "dimension" ] }, { "name": "right", "format": [ "dimension" ] }, { "name": "bottom", "format": [ "dimension" ] } ] }, "LayerDrawable": { "name": "LayerDrawable", "attrs": [ { "name": "opacity", "format": [ "enum" ], "enum": [ { "name": "opaque", "value": "-1" }, { "name": "transparent", "value": "-2" }, { "name": "translucent", "value": "-3" } ] }, { "name": "autoMirrored", "format": [] } ] }, "LayerDrawableItem": { "name": "LayerDrawableItem", "attrs": [ { "name": "left", "format": [] }, { "name": "top", "format": [] }, { "name": "right", "format": [] }, { "name": "bottom", "format": [] }, { "name": "drawable", "format": [] }, { "name": "id", "format": [] } ] }, "LevelListDrawableItem": { "name": "LevelListDrawableItem", "attrs": [ { "name": "minLevel", "format": [ "integer" ] }, { "name": "maxLevel", "format": [ "integer" ] }, { "name": "drawable", "format": [] } ] }, "RotateDrawable": { "name": "RotateDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "fromDegrees", "format": [ "float" ] }, { "name": "toDegrees", "format": [ "float" ] }, { "name": "pivotX", "format": [ "float", "fraction" ] }, { "name": "pivotY", "format": [ "float", "fraction" ] }, { "name": "drawable", "format": [] } ] }, "AnimatedRotateDrawable": { "name": "AnimatedRotateDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "frameDuration", "format": [ "integer" ] }, { "name": "framesCount", "format": [ "integer" ] }, { "name": "pivotX", "format": [] }, { "name": "pivotY", "format": [] }, { "name": "drawable", "format": [] } ] }, "InsetDrawable": { "name": "InsetDrawable", "attrs": [ { "name": "visible", "format": [] }, { "name": "drawable", "format": [] }, { "name": "insetLeft", "format": [ "dimension" ] }, { "name": "insetRight", "format": [ "dimension" ] }, { "name": "insetTop", "format": [ "dimension" ] }, { "name": "insetBottom", "format": [ "dimension" ] } ] }, "BitmapDrawable": { "name": "BitmapDrawable", "attrs": [ { "name": "src", "format": [] }, { "name": "antialias", "format": [ "boolean" ] }, { "name": "filter", "format": [ "boolean" ] }, { "name": "dither", "format": [] }, { "name": "gravity", "format": [] }, { "name": "tileMode", "format": [ "enum" ], "enum": [ { "name": "disabled", "value": "-1" }, { "name": "clamp", "value": "0" }, { "name": "repeat", "value": "1" }, { "name": "mirror", "value": "2" } ] }, { "name": "mipMap", "format": [ "boolean" ] }, { "name": "autoMirrored", "format": [] } ] }, "NinePatchDrawable": { "name": "NinePatchDrawable", "attrs": [ { "name": "src", "format": [] }, { "name": "dither", "format": [] }, { "name": "autoMirrored", "format": [] } ] }, "ColorDrawable": { "name": "ColorDrawable", "attrs": [ { "name": "color", "format": [] } ] }, "ScaleDrawable": { "name": "ScaleDrawable", "attrs": [ { "name": "scaleWidth", "format": [ "string" ] }, { "name": "scaleHeight", "format": [ "string" ] }, { "name": "scaleGravity", "format": [ "flags" ], "flags": [ { "name": "top", "value": "0x30" }, { "name": "bottom", "value": "0x50" }, { "name": "left", "value": "0x03" }, { "name": "right", "value": "0x05" }, { "name": "center_vertical", "value": "0x10" }, { "name": "fill_vertical", "value": "0x70" }, { "name": "center_horizontal", "value": "0x01" }, { "name": "fill_horizontal", "value": "0x07" }, { "name": "center", "value": "0x11" }, { "name": "fill", "value": "0x77" }, { "name": "clip_vertical", "value": "0x80" }, { "name": "clip_horizontal", "value": "0x08" }, { "name": "start", "value": "0x00800003" }, { "name": "end", "value": "0x00800005" } ] }, { "name": "drawable", "format": [] }, { "name": "useIntrinsicSizeAsMinimum", "format": [ "boolean" ] } ] }, "ClipDrawable": { "name": "ClipDrawable", "attrs": [ { "name": "clipOrientation", "format": [ "flags" ], "flags": [ { "name": "horizontal", "value": "1" }, { "name": "vertical", "value": "2" } ] }, { "name": "gravity", "format": [] }, { "name": "drawable", "format": [] } ] }, "ShapeDrawablePadding": { "name": "ShapeDrawablePadding", "attrs": [ { "name": "left", "format": [] }, { "name": "top", "format": [] }, { "name": "right", "format": [] }, { "name": "bottom", "format": [] } ] }, "ShapeDrawable": { "name": "ShapeDrawable", "attrs": [ { "name": "color", "format": [] }, { "name": "width", "format": [] }, { "name": "height", "format": [] }, { "name": "dither", "format": [] } ] }, "Animation": { "name": "Animation", "attrs": [ { "name": "interpolator", "format": [] }, { "name": "fillEnabled", "format": [ "boolean" ] }, { "name": "fillBefore", "format": [ "boolean" ] }, { "name": "fillAfter", "format": [ "boolean" ] }, { "name": "duration", "format": [] }, { "name": "startOffset", "format": [ "integer" ] }, { "name": "repeatCount", "format": [ "integer", "enum" ], "enum": [ { "name": "infinite", "value": "-1" } ] }, { "name": "repeatMode", "format": [ "enum" ], "enum": [ { "name": "restart", "value": "1" }, { "name": "reverse", "value": "2" } ] }, { "name": "zAdjustment", "format": [ "enum" ], "enum": [ { "name": "normal", "value": "0" }, { "name": "top", "value": "1" }, { "name": "bottom", "value": "-1" } ] }, { "name": "background", "format": [] }, { "name": "detachWallpaper", "format": [ "boolean" ] } ] }, "AnimationSet": { "name": "AnimationSet", "attrs": [ { "name": "shareInterpolator", "format": [ "boolean" ] }, { "name": "fillBefore", "format": [] }, { "name": "fillAfter", "format": [] }, { "name": "duration", "format": [] }, { "name": "startOffset", "format": [] }, { "name": "repeatMode", "format": [] } ] }, "RotateAnimation": { "name": "RotateAnimation", "attrs": [ { "name": "fromDegrees", "format": [] }, { "name": "toDegrees", "format": [] }, { "name": "pivotX", "format": [] }, { "name": "pivotY", "format": [] } ] }, "ScaleAnimation": { "name": "ScaleAnimation", "attrs": [ { "name": "fromXScale", "format": [ "float", "fraction", "dimension" ] }, { "name": "toXScale", "format": [ "float", "fraction", "dimension" ] }, { "name": "fromYScale", "format": [ "float", "fraction", "dimension" ] }, { "name": "toYScale", "format": [ "float", "fraction", "dimension" ] }, { "name": "pivotX", "format": [] }, { "name": "pivotY", "format": [] } ] }, "TranslateAnimation": { "name": "TranslateAnimation", "attrs": [ { "name": "fromXDelta", "format": [ "float", "fraction" ] }, { "name": "toXDelta", "format": [ "float", "fraction" ] }, { "name": "fromYDelta", "format": [ "float", "fraction" ] }, { "name": "toYDelta", "format": [ "float", "fraction" ] } ] }, "AlphaAnimation": { "name": "AlphaAnimation", "attrs": [ { "name": "fromAlpha", "format": [ "float" ] }, { "name": "toAlpha", "format": [ "float" ] } ] }, "LayoutAnimation": { "name": "LayoutAnimation", "attrs": [ { "name": "delay", "format": [ "float", "fraction" ] }, { "name": "animation", "format": [ "reference" ] }, { "name": "animationOrder", "format": [ "enum" ], "enum": [ { "name": "normal", "value": "0" }, { "name": "reverse", "value": "1" }, { "name": "random", "value": "2" } ] }, { "name": "interpolator", "format": [] } ] }, "GridLayoutAnimation": { "name": "GridLayoutAnimation", "attrs": [ { "name": "columnDelay", "format": [ "float", "fraction" ] }, { "name": "rowDelay", "format": [ "float", "fraction" ] }, { "name": "direction", "format": [ "flags" ], "flags": [ { "name": "left_to_right", "value": "0x0" }, { "name": "right_to_left", "value": "0x1" }, { "name": "top_to_bottom", "value": "0x0" }, { "name": "bottom_to_top", "value": "0x2" } ] }, { "name": "directionPriority", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "column", "value": "1" }, { "name": "row", "value": "2" } ] } ] }, "AccelerateInterpolator": { "name": "AccelerateInterpolator", "attrs": [ { "name": "factor", "format": [ "float" ] } ] }, "DecelerateInterpolator": { "name": "DecelerateInterpolator", "attrs": [ { "name": "factor", "format": [] } ] }, "CycleInterpolator": { "name": "CycleInterpolator", "attrs": [ { "name": "cycles", "format": [ "float" ] } ] }, "AnticipateInterpolator": { "name": "AnticipateInterpolator", "attrs": [ { "name": "tension", "format": [ "float" ] } ] }, "OvershootInterpolator": { "name": "OvershootInterpolator", "attrs": [ { "name": "tension", "format": [] } ] }, "AnticipateOvershootInterpolator": { "name": "AnticipateOvershootInterpolator", "attrs": [ { "name": "tension", "format": [] }, { "name": "extraTension", "format": [ "float" ] } ] }, "Transition": { "name": "Transition", "attrs": [ { "name": "duration", "format": [] }, { "name": "startDelay", "format": [ "integer" ] }, { "name": "interpolator", "format": [] } ] }, "Fade": { "name": "Fade", "attrs": [ { "name": "fadingMode", "format": [ "enum" ], "enum": [ { "name": "fade_in", "value": "1" }, { "name": "fade_out", "value": "2" }, { "name": "fade_in_out", "value": "3" } ] } ] }, "TransitionTarget": { "name": "TransitionTarget", "attrs": [ { "name": "targetId", "format": [ "reference" ] } ] }, "TransitionSet": { "name": "TransitionSet", "attrs": [ { "name": "transitionOrdering", "format": [ "enum" ], "enum": [ { "name": "together", "value": "0" }, { "name": "sequential", "value": "1" } ] } ] }, "TransitionManager": { "name": "TransitionManager", "attrs": [ { "name": "transition", "format": [ "reference" ] }, { "name": "fromScene", "format": [ "reference" ] }, { "name": "toScene", "format": [ "reference" ] } ] }, "Animator": { "name": "Animator", "attrs": [ { "name": "interpolator", "format": [] }, { "name": "duration", "format": [] }, { "name": "startOffset", "format": [] }, { "name": "repeatCount", "format": [] }, { "name": "repeatMode", "format": [] }, { "name": "valueFrom", "format": [ "float", "integer", "color", "dimension" ] }, { "name": "valueTo", "format": [ "float", "integer", "color", "dimension" ] }, { "name": "valueType", "format": [ "enum" ], "enum": [ { "name": "floatType", "value": "0" }, { "name": "intType", "value": "1" } ] } ] }, "PropertyAnimator": { "name": "PropertyAnimator", "attrs": [ { "name": "propertyName", "format": [ "string" ] } ] }, "AnimatorSet": { "name": "AnimatorSet", "attrs": [ { "name": "ordering", "format": [ "enum" ], "enum": [ { "name": "together", "value": "0" }, { "name": "sequentially", "value": "1" } ] } ] }, "DrawableStates": { "name": "DrawableStates", "attrs": [ { "name": "state_focused", "format": [ "boolean" ] }, { "name": "state_window_focused", "format": [ "boolean" ] }, { "name": "state_enabled", "format": [ "boolean" ] }, { "name": "state_checkable", "format": [ "boolean" ] }, { "name": "state_checked", "format": [ "boolean" ] }, { "name": "state_selected", "format": [ "boolean" ] }, { "name": "state_pressed", "format": [ "boolean" ] }, { "name": "state_activated", "format": [ "boolean" ] }, { "name": "state_active", "format": [ "boolean" ] }, { "name": "state_single", "format": [ "boolean" ] }, { "name": "state_first", "format": [ "boolean" ] }, { "name": "state_middle", "format": [ "boolean" ] }, { "name": "state_last", "format": [ "boolean" ] }, { "name": "state_accelerated", "format": [ "boolean" ] }, { "name": "state_hovered", "format": [ "boolean" ] }, { "name": "state_drag_can_accept", "format": [ "boolean" ] }, { "name": "state_drag_hovered", "format": [ "boolean" ] }, { "name": "state_accessibility_focused", "format": [ "boolean" ] } ] }, "ViewDrawableStates": { "name": "ViewDrawableStates", "attrs": [ { "name": "state_pressed", "format": [] }, { "name": "state_focused", "format": [] }, { "name": "state_selected", "format": [] }, { "name": "state_window_focused", "format": [] }, { "name": "state_enabled", "format": [] }, { "name": "state_activated", "format": [] }, { "name": "state_accelerated", "format": [] }, { "name": "state_hovered", "format": [] }, { "name": "state_drag_can_accept", "format": [] }, { "name": "state_drag_hovered", "format": [] } ] }, "MenuItemCheckedState": { "name": "MenuItemCheckedState", "attrs": [ { "name": "state_checkable", "format": [] }, { "name": "state_checked", "format": [] } ] }, "MenuItemUncheckedState": { "name": "MenuItemUncheckedState", "attrs": [ { "name": "state_checkable", "format": [] } ] }, "MenuItemCheckedFocusedState": { "name": "MenuItemCheckedFocusedState", "attrs": [ { "name": "state_checkable", "format": [] }, { "name": "state_checked", "format": [] }, { "name": "state_focused", "format": [] } ] }, "MenuItemUncheckedFocusedState": { "name": "MenuItemUncheckedFocusedState", "attrs": [ { "name": "state_checkable", "format": [] }, { "name": "state_focused", "format": [] } ] }, "ExpandableListChildIndicatorState": { "name": "ExpandableListChildIndicatorState", "attrs": [ { "name": "state_last", "format": [] } ] }, "ExpandableListGroupIndicatorState": { "name": "ExpandableListGroupIndicatorState", "attrs": [ { "name": "state_expanded", "format": [ "boolean" ] }, { "name": "state_empty", "format": [ "boolean" ] } ] }, "PopupWindowBackgroundState": { "name": "PopupWindowBackgroundState", "attrs": [ { "name": "state_above_anchor", "format": [ "boolean" ] } ] }, "TextViewMultiLineBackgroundState": { "name": "TextViewMultiLineBackgroundState", "attrs": [ { "name": "state_multiline", "format": [ "boolean" ] } ] }, "Searchable": { "name": "Searchable", "attrs": [ { "name": "icon", "format": [] }, { "name": "label", "format": [] }, { "name": "hint", "format": [] }, { "name": "searchButtonText", "format": [ "string" ] }, { "name": "inputType", "format": [] }, { "name": "imeOptions", "format": [] }, { "name": "searchMode", "format": [ "flags" ], "flags": [ { "name": "showSearchLabelAsBadge", "value": "0x04" }, { "name": "showSearchIconAsBadge", "value": "0x08" }, { "name": "queryRewriteFromData", "value": "0x10" }, { "name": "queryRewriteFromText", "value": "0x20" } ] }, { "name": "voiceSearchMode", "format": [ "flags" ], "flags": [ { "name": "showVoiceSearchButton", "value": "0x01" }, { "name": "launchWebSearch", "value": "0x02" }, { "name": "launchRecognizer", "value": "0x04" } ] }, { "name": "voiceLanguageModel", "format": [ "string" ] }, { "name": "voicePromptText", "format": [ "string" ] }, { "name": "voiceLanguage", "format": [ "string" ] }, { "name": "voiceMaxResults", "format": [ "integer" ] }, { "name": "searchSuggestAuthority", "format": [ "string" ] }, { "name": "searchSuggestPath", "format": [ "string" ] }, { "name": "searchSuggestSelection", "format": [ "string" ] }, { "name": "searchSuggestIntentAction", "format": [ "string" ] }, { "name": "searchSuggestIntentData", "format": [ "string" ] }, { "name": "searchSuggestThreshold", "format": [ "integer" ] }, { "name": "includeInGlobalSearch", "format": [ "boolean" ] }, { "name": "queryAfterZeroResults", "format": [ "boolean" ] }, { "name": "searchSettingsDescription", "format": [ "string" ] }, { "name": "autoUrlDetect", "format": [ "boolean" ] } ] }, "SearchableActionKey": { "name": "SearchableActionKey", "attrs": [ { "name": "keycode", "format": [] }, { "name": "queryActionMsg", "format": [ "string" ] }, { "name": "suggestActionMsg", "format": [ "string" ] }, { "name": "suggestActionMsgColumn", "format": [ "string" ] } ] }, "MapView": { "name": "MapView", "attrs": [ { "name": "apiKey", "format": [ "string" ] } ] }, "Menu": { "name": "Menu", "attrs": [] }, "MenuGroup": { "name": "MenuGroup", "attrs": [ { "name": "id", "format": [] }, { "name": "menuCategory", "format": [ "enum" ], "enum": [ { "name": "container", "value": "0x00010000" }, { "name": "system", "value": "0x00020000" }, { "name": "secondary", "value": "0x00030000" }, { "name": "alternative", "value": "0x00040000" } ] }, { "name": "orderInCategory", "format": [ "integer" ] }, { "name": "checkableBehavior", "format": [ "enum" ], "enum": [ { "name": "none", "value": "0" }, { "name": "all", "value": "1" }, { "name": "single", "value": "2" } ] }, { "name": "visible", "format": [] }, { "name": "enabled", "format": [] } ] }, "MenuItem": { "name": "MenuItem", "attrs": [ { "name": "id", "format": [] }, { "name": "menuCategory", "format": [] }, { "name": "orderInCategory", "format": [] }, { "name": "title", "format": [ "string" ] }, { "name": "titleCondensed", "format": [ "string" ] }, { "name": "icon", "format": [] }, { "name": "alphabeticShortcut", "format": [ "string" ] }, { "name": "numericShortcut", "format": [ "string" ] }, { "name": "checkable", "format": [ "boolean" ] }, { "name": "checked", "format": [] }, { "name": "visible", "format": [] }, { "name": "enabled", "format": [] }, { "name": "onClick", "format": [] }, { "name": "showAsAction", "format": [ "flags" ], "flags": [ { "name": "never", "value": "0" }, { "name": "ifRoom", "value": "1" }, { "name": "always", "value": "2" }, { "name": "withText", "value": "4" }, { "name": "collapseActionView", "value": "8" } ] }, { "name": "actionLayout", "format": [ "reference" ] }, { "name": "actionViewClass", "format": [ "string" ] }, { "name": "actionProviderClass", "format": [ "string" ] } ] }, "ActivityChooserView": { "name": "ActivityChooserView", "attrs": [ { "name": "initialActivityCount", "format": [ "string" ] }, { "name": "expandActivityOverflowButtonDrawable", "format": [ "reference" ] } ] }, "PreferenceGroup": { "name": "PreferenceGroup", "attrs": [ { "name": "orderingFromXml", "format": [ "boolean" ] } ] }, "PreferenceHeader": { "name": "PreferenceHeader", "attrs": [ { "name": "id", "format": [] }, { "name": "title", "format": [] }, { "name": "summary", "format": [ "string" ] }, { "name": "breadCrumbTitle", "format": [ "string" ] }, { "name": "breadCrumbShortTitle", "format": [ "string" ] }, { "name": "icon", "format": [] }, { "name": "fragment", "format": [ "string" ] } ] }, "Preference": { "name": "Preference", "attrs": [ { "name": "icon", "format": [] }, { "name": "key", "format": [ "string" ] }, { "name": "title", "format": [] }, { "name": "summary", "format": [] }, { "name": "order", "format": [ "integer" ] }, { "name": "fragment", "format": [] }, { "name": "layout", "format": [] }, { "name": "widgetLayout", "format": [ "reference" ] }, { "name": "enabled", "format": [] }, { "name": "selectable", "format": [ "boolean" ] }, { "name": "dependency", "format": [ "string" ] }, { "name": "persistent", "format": [] }, { "name": "defaultValue", "format": [ "string", "boolean", "integer", "reference", "float" ] }, { "name": "shouldDisableView", "format": [ "boolean" ] } ] }, "CheckBoxPreference": { "name": "CheckBoxPreference", "attrs": [ { "name": "summaryOn", "format": [ "string" ] }, { "name": "summaryOff", "format": [ "string" ] }, { "name": "disableDependentsState", "format": [ "boolean" ] } ] }, "DialogPreference": { "name": "DialogPreference", "attrs": [ { "name": "dialogTitle", "format": [ "string" ] }, { "name": "dialogMessage", "format": [ "string" ] }, { "name": "dialogIcon", "format": [ "reference" ] }, { "name": "positiveButtonText", "format": [ "string" ] }, { "name": "negativeButtonText", "format": [ "string" ] }, { "name": "dialogLayout", "format": [ "reference" ] } ] }, "ListPreference": { "name": "ListPreference", "attrs": [ { "name": "entries", "format": [] }, { "name": "entryValues", "format": [ "reference" ] } ] }, "MultiSelectListPreference": { "name": "MultiSelectListPreference", "attrs": [ { "name": "entries", "format": [] }, { "name": "entryValues", "format": [] } ] }, "RingtonePreference": { "name": "RingtonePreference", "attrs": [ { "name": "ringtoneType", "format": [ "flags" ], "flags": [ { "name": "ringtone", "value": "1" }, { "name": "notification", "value": "2" }, { "name": "alarm", "value": "4" }, { "name": "all", "value": "7" } ] }, { "name": "showDefault", "format": [ "boolean" ] }, { "name": "showSilent", "format": [ "boolean" ] } ] }, "VolumePreference": { "name": "VolumePreference", "attrs": [ { "name": "streamType", "format": [ "enum" ], "enum": [ { "name": "voice", "value": "0" }, { "name": "system", "value": "1" }, { "name": "ring", "value": "2" }, { "name": "music", "value": "3" }, { "name": "alarm", "value": "4" } ] } ] }, "InputMethodService": { "name": "InputMethodService", "attrs": [ { "name": "imeFullscreenBackground", "format": [ "reference", "color" ] }, { "name": "imeExtractEnterAnimation", "format": [ "reference" ] }, { "name": "imeExtractExitAnimation", "format": [ "reference" ] } ] }, "KeyboardView": { "name": "KeyboardView", "attrs": [ { "name": "keyboardViewStyle", "format": [ "reference" ] }, { "name": "keyBackground", "format": [ "reference" ] }, { "name": "keyTextSize", "format": [ "dimension" ] }, { "name": "labelTextSize", "format": [ "dimension" ] }, { "name": "keyTextColor", "format": [ "color" ] }, { "name": "keyPreviewLayout", "format": [ "reference" ] }, { "name": "keyPreviewOffset", "format": [ "dimension" ] }, { "name": "keyPreviewHeight", "format": [ "dimension" ] }, { "name": "verticalCorrection", "format": [ "dimension" ] }, { "name": "popupLayout", "format": [ "reference" ] }, { "name": "shadowColor", "format": [] }, { "name": "shadowRadius", "format": [] } ] }, "KeyboardViewPreviewState": { "name": "KeyboardViewPreviewState", "attrs": [ { "name": "state_long_pressable", "format": [ "boolean" ] } ] }, "Keyboard": { "name": "Keyboard", "attrs": [ { "name": "keyWidth", "format": [ "dimension", "fraction" ] }, { "name": "keyHeight", "format": [ "dimension", "fraction" ] }, { "name": "horizontalGap", "format": [ "dimension", "fraction" ] }, { "name": "verticalGap", "format": [ "dimension", "fraction" ] } ] }, "Keyboard_Row": { "name": "Keyboard_Row", "attrs": [ { "name": "rowEdgeFlags", "format": [ "flags" ], "flags": [ { "name": "top", "value": "4" }, { "name": "bottom", "value": "8" } ] }, { "name": "keyboardMode", "format": [ "reference" ] } ] }, "Keyboard_Key": { "name": "Keyboard_Key", "attrs": [ { "name": "codes", "format": [ "integer", "string" ] }, { "name": "popupKeyboard", "format": [ "reference" ] }, { "name": "popupCharacters", "format": [ "string" ] }, { "name": "keyEdgeFlags", "format": [ "flags" ], "flags": [ { "name": "left", "value": "1" }, { "name": "right", "value": "2" } ] }, { "name": "isModifier", "format": [ "boolean" ] }, { "name": "isSticky", "format": [ "boolean" ] }, { "name": "isRepeatable", "format": [ "boolean" ] }, { "name": "iconPreview", "format": [ "reference" ] }, { "name": "keyOutputText", "format": [ "string" ] }, { "name": "keyLabel", "format": [ "string" ] }, { "name": "keyIcon", "format": [ "reference" ] }, { "name": "keyboardMode", "format": [] } ] }, "AppWidgetProviderInfo": { "name": "AppWidgetProviderInfo", "attrs": [ { "name": "minWidth", "format": [] }, { "name": "minHeight", "format": [] }, { "name": "minResizeWidth", "format": [ "dimension" ] }, { "name": "minResizeHeight", "format": [ "dimension" ] }, { "name": "updatePeriodMillis", "format": [ "integer" ] }, { "name": "initialLayout", "format": [ "reference" ] }, { "name": "initialKeyguardLayout", "format": [ "reference" ] }, { "name": "configure", "format": [ "string" ] }, { "name": "previewImage", "format": [ "reference" ] }, { "name": "autoAdvanceViewId", "format": [ "reference" ] }, { "name": "resizeMode", "format": [ "integer", "flags" ], "flags": [ { "name": "none", "value": "0x0" }, { "name": "horizontal", "value": "0x1" }, { "name": "vertical", "value": "0x2" } ] }, { "name": "widgetCategory", "format": [ "integer", "flags" ], "flags": [ { "name": "home_screen", "value": "0x1" }, { "name": "keyguard", "value": "0x2" } ] } ] }, "WallpaperPreviewInfo": { "name": "WallpaperPreviewInfo", "attrs": [ { "name": "staticWallpaperPreview", "format": [ "reference" ] } ] }, "Fragment": { "name": "Fragment", "attrs": [ { "name": "name", "format": [] }, { "name": "id", "format": [] }, { "name": "tag", "format": [] } ] }, "DeviceAdmin": { "name": "DeviceAdmin", "attrs": [ { "name": "visible", "format": [] } ] }, "Wallpaper": { "name": "Wallpaper", "attrs": [ { "name": "settingsActivity", "format": [] }, { "name": "thumbnail", "format": [ "reference" ] }, { "name": "author", "format": [ "reference" ] }, { "name": "description", "format": [] } ] }, "Dream": { "name": "Dream", "attrs": [ { "name": "settingsActivity", "format": [] } ] }, "AccountAuthenticator": { "name": "AccountAuthenticator", "attrs": [ { "name": "accountType", "format": [ "string" ] }, { "name": "label", "format": [] }, { "name": "icon", "format": [] }, { "name": "smallIcon", "format": [ "reference" ] }, { "name": "accountPreferences", "format": [ "reference" ] }, { "name": "customTokens", "format": [ "boolean" ] } ] }, "SyncAdapter": { "name": "SyncAdapter", "attrs": [ { "name": "contentAuthority", "format": [ "string" ] }, { "name": "accountType", "format": [] }, { "name": "userVisible", "format": [ "boolean" ] }, { "name": "supportsUploading", "format": [ "boolean" ] }, { "name": "allowParallelSyncs", "format": [ "boolean" ] }, { "name": "isAlwaysSyncable", "format": [ "boolean" ] }, { "name": "settingsActivity", "format": [] } ] }, "Icon": { "name": "Icon", "attrs": [ { "name": "icon", "format": [] }, { "name": "mimeType", "format": [] } ] }, "IconDefault": { "name": "IconDefault", "attrs": [ { "name": "icon", "format": [] } ] }, "ContactsDataKind": { "name": "ContactsDataKind", "attrs": [ { "name": "mimeType", "format": [] }, { "name": "icon", "format": [] }, { "name": "summaryColumn", "format": [ "string" ] }, { "name": "detailColumn", "format": [ "string" ] }, { "name": "detailSocialSummary", "format": [ "boolean" ] }, { "name": "allContactsName", "format": [ "string" ] } ] }, "SlidingTab": { "name": "SlidingTab", "attrs": [ { "name": "orientation", "format": [] } ] }, "GlowPadView": { "name": "GlowPadView", "attrs": [ { "name": "targetDrawables", "format": [] }, { "name": "targetDescriptions", "format": [] }, { "name": "directionDescriptions", "format": [] }, { "name": "handleDrawable", "format": [] }, { "name": "outerRingDrawable", "format": [ "reference" ] }, { "name": "pointDrawable", "format": [ "reference" ] }, { "name": "innerRadius", "format": [] }, { "name": "outerRadius", "format": [] }, { "name": "glowRadius", "format": [ "dimension" ] }, { "name": "vibrationDuration", "format": [] }, { "name": "snapMargin", "format": [] }, { "name": "feedbackCount", "format": [] }, { "name": "alwaysTrackFinger", "format": [] }, { "name": "firstItemOffset", "format": [ "float" ] }, { "name": "magneticTargets", "format": [ "boolean" ] }, { "name": "gravity", "format": [] }, { "name": "allowScaling", "format": [ "boolean" ] } ] }, "MultiWaveView": { "name": "MultiWaveView", "attrs": [ { "name": "targetDrawables", "format": [ "reference" ] }, { "name": "targetDescriptions", "format": [ "reference" ] }, { "name": "directionDescriptions", "format": [ "reference" ] }, { "name": "handleDrawable", "format": [ "reference" ] }, { "name": "chevronDrawables", "format": [ "reference" ] }, { "name": "waveDrawable", "format": [ "reference" ] }, { "name": "outerRadius", "format": [ "dimension" ] }, { "name": "vibrationDuration", "format": [ "integer" ] }, { "name": "snapMargin", "format": [ "dimension" ] }, { "name": "feedbackCount", "format": [ "integer" ] }, { "name": "alwaysTrackFinger", "format": [ "boolean" ] } ] }, "SizeAdaptiveLayout_Layout": { "name": "SizeAdaptiveLayout_Layout", "attrs": [ { "name": "layout_maxHeight", "format": [ "dimension", "enum" ], "enum": [ { "name": "unbounded", "value": "-1" } ] }, { "name": "layout_minHeight", "format": [ "dimension" ] } ] }, "SizeAdaptiveLayout": { "name": "SizeAdaptiveLayout", "attrs": [] }, "SettingInjectorService": { "name": "SettingInjectorService", "attrs": [ { "name": "title", "format": [] }, { "name": "icon", "format": [] }, { "name": "settingsActivity", "format": [] } ] }, "LockPatternView": { "name": "LockPatternView", "attrs": [ { "name": "aspect", "format": [ "string" ] } ] }, "RecognitionService": { "name": "RecognitionService", "attrs": [ { "name": "settingsActivity", "format": [] } ] }, "ActionBar": { "name": "ActionBar", "attrs": [ { "name": "navigationMode", "format": [ "enum" ], "enum": [ { "name": "normal", "value": "0" }, { "name": "listMode", "value": "1" }, { "name": "tabMode", "value": "2" } ] }, { "name": "displayOptions", "format": [ "flags" ], "flags": [ { "name": "none", "value": "0" }, { "name": "useLogo", "value": "0x1" }, { "name": "showHome", "value": "0x2" }, { "name": "homeAsUp", "value": "0x4" }, { "name": "showTitle", "value": "0x8" }, { "name": "showCustom", "value": "0x10" }, { "name": "disableHome", "value": "0x20" } ] }, { "name": "title", "format": [] }, { "name": "subtitle", "format": [ "string" ] }, { "name": "titleTextStyle", "format": [ "reference" ] }, { "name": "subtitleTextStyle", "format": [ "reference" ] }, { "name": "icon", "format": [] }, { "name": "logo", "format": [] }, { "name": "divider", "format": [] }, { "name": "background", "format": [] }, { "name": "backgroundStacked", "format": [ "reference", "color" ] }, { "name": "backgroundSplit", "format": [ "reference", "color" ] }, { "name": "customNavigationLayout", "format": [ "reference" ] }, { "name": "height", "format": [] }, { "name": "homeLayout", "format": [ "reference" ] }, { "name": "progressBarStyle", "format": [] }, { "name": "indeterminateProgressStyle", "format": [ "reference" ] }, { "name": "progressBarPadding", "format": [ "dimension" ] }, { "name": "itemPadding", "format": [ "dimension" ] } ] }, "ActionMode": { "name": "ActionMode", "attrs": [ { "name": "titleTextStyle", "format": [] }, { "name": "subtitleTextStyle", "format": [] }, { "name": "background", "format": [] }, { "name": "backgroundSplit", "format": [] }, { "name": "height", "format": [] } ] }, "SearchView": { "name": "SearchView", "attrs": [ { "name": "iconifiedByDefault", "format": [ "boolean" ] }, { "name": "maxWidth", "format": [] }, { "name": "queryHint", "format": [ "string" ] }, { "name": "imeOptions", "format": [] }, { "name": "inputType", "format": [] } ] }, "ActionBar_LayoutParams": { "name": "ActionBar_LayoutParams", "attrs": [ { "name": "layout_gravity", "format": [] } ] }, "Switch": { "name": "Switch", "attrs": [ { "name": "thumb", "format": [] }, { "name": "track", "format": [ "reference" ] }, { "name": "textOn", "format": [] }, { "name": "textOff", "format": [] }, { "name": "thumbTextPadding", "format": [ "dimension" ] }, { "name": "switchTextAppearance", "format": [ "reference" ] }, { "name": "switchMinWidth", "format": [ "dimension" ] }, { "name": "switchPadding", "format": [ "dimension" ] } ] }, "Pointer": { "name": "Pointer", "attrs": [ { "name": "pointerIconArrow", "format": [ "reference" ] }, { "name": "pointerIconSpotHover", "format": [ "reference" ] }, { "name": "pointerIconSpotTouch", "format": [ "reference" ] }, { "name": "pointerIconSpotAnchor", "format": [ "reference" ] } ] }, "PointerIcon": { "name": "PointerIcon", "attrs": [ { "name": "bitmap", "format": [ "reference" ] }, { "name": "hotSpotX", "format": [ "float" ] }, { "name": "hotSpotY", "format": [ "float" ] } ] }, "Storage": { "name": "Storage", "attrs": [ { "name": "mountPoint", "format": [ "string" ] }, { "name": "storageDescription", "format": [ "string" ] }, { "name": "primary", "format": [ "boolean" ] }, { "name": "removable", "format": [ "boolean" ] }, { "name": "emulated", "format": [ "boolean" ] }, { "name": "mtpReserve", "format": [ "integer" ] }, { "name": "allowMassStorage", "format": [ "boolean" ] }, { "name": "maxFileSize", "format": [ "integer" ] } ] }, "SwitchPreference": { "name": "SwitchPreference", "attrs": [ { "name": "summaryOn", "format": [] }, { "name": "summaryOff", "format": [] }, { "name": "switchTextOn", "format": [ "string" ] }, { "name": "switchTextOff", "format": [ "string" ] }, { "name": "disableDependentsState", "format": [] } ] }, "TextToSpeechEngine": { "name": "TextToSpeechEngine", "attrs": [ { "name": "settingsActivity", "format": [] } ] }, "KeyboardLayout": { "name": "KeyboardLayout", "attrs": [ { "name": "name", "format": [] }, { "name": "label", "format": [] }, { "name": "keyboardLayout", "format": [ "reference" ] } ] }, "MediaRouteButton": { "name": "MediaRouteButton", "attrs": [ { "name": "externalRouteEnabledDrawable", "format": [ "reference" ] }, { "name": "mediaRouteTypes", "format": [ "integer", "enum" ], "enum": [ { "name": "liveAudio", "value": "0x1" }, { "name": "user", "value": "0x800000" } ] }, { "name": "minWidth", "format": [] }, { "name": "minHeight", "format": [] } ] }, "PagedView": { "name": "PagedView", "attrs": [ { "name": "pageSpacing", "format": [ "dimension" ] }, { "name": "scrollIndicatorPaddingLeft", "format": [ "dimension" ] }, { "name": "scrollIndicatorPaddingRight", "format": [ "dimension" ] } ] }, "KeyguardGlowStripView": { "name": "KeyguardGlowStripView", "attrs": [ { "name": "dotSize", "format": [ "dimension" ] }, { "name": "numDots", "format": [ "integer" ] }, { "name": "glowDot", "format": [ "reference" ] }, { "name": "leftToRight", "format": [ "boolean" ] } ] }, "SlidingChallengeLayout_Layout": { "name": "SlidingChallengeLayout_Layout", "attrs": [ { "name": "layout_childType", "format": [] }, { "name": "layout_maxHeight", "format": [] } ] }, "FragmentBreadCrumbs": { "name": "FragmentBreadCrumbs", "attrs": [ { "name": "gravity", "format": [] } ] }, "MultiPaneChallengeLayout": { "name": "MultiPaneChallengeLayout", "attrs": [ { "name": "orientation", "format": [] } ] }, "MultiPaneChallengeLayout_Layout": { "name": "MultiPaneChallengeLayout_Layout", "attrs": [ { "name": "layout_centerWithinArea", "format": [ "float" ] }, { "name": "layout_childType", "format": [] }, { "name": "layout_gravity", "format": [] }, { "name": "layout_maxWidth", "format": [ "dimension" ] }, { "name": "layout_maxHeight", "format": [] } ] }, "KeyguardSecurityViewFlipper_Layout": { "name": "KeyguardSecurityViewFlipper_Layout", "attrs": [ { "name": "layout_maxWidth", "format": [] }, { "name": "layout_maxHeight", "format": [] } ] }, "NumPadKey": { "name": "NumPadKey", "attrs": [ { "name": "digit", "format": [ "integer" ] }, { "name": "textView", "format": [ "reference" ] } ] } } } ================================================ FILE: anko/idea-plugin/xml-converter/resources/views.json ================================================ {"DigitalClock":["TextView"],"Chronometer":["TextView"],"EditText":["TextView"],"Button":["TextView"],"CheckedTextView":["TextView"],"AbsSeekBar":["ProgressBar"],"ImageButton":["ImageView"],"QuickContactBadge":["ImageView"],"VideoView":["SurfaceView"],"GridLayout":["ViewGroup"],"SlidingDrawer":["ViewGroup"],"RelativeLayout":["ViewGroup"],"AbsoluteLayout":["ViewGroup"],"FrameLayout":["ViewGroup"],"LinearLayout":["ViewGroup"],"AdapterView":["ViewGroup"],"AutoCompleteTextView":["EditText","TextView"],"CompoundButton":["Button","TextView"],"SeekBar":["AbsSeekBar","ProgressBar"],"RatingBar":["AbsSeekBar","ProgressBar"],"ZoomButton":["ImageButton","ImageView"],"DialerFilter":["RelativeLayout","ViewGroup"],"TwoLineListItem":["RelativeLayout","ViewGroup"],"HorizontalScrollView":["FrameLayout","ViewGroup"],"TimePicker":["FrameLayout","ViewGroup"],"CalendarView":["FrameLayout","ViewGroup"],"ViewAnimator":["FrameLayout","ViewGroup"],"MediaController":["FrameLayout","ViewGroup"],"TabHost":["FrameLayout","ViewGroup"],"ScrollView":["FrameLayout","ViewGroup"],"DatePicker":["FrameLayout","ViewGroup"],"TableRow":["LinearLayout","ViewGroup"],"SearchView":["LinearLayout","ViewGroup"],"RadioGroup":["LinearLayout","ViewGroup"],"TableLayout":["LinearLayout","ViewGroup"],"ZoomControls":["LinearLayout","ViewGroup"],"NumberPicker":["LinearLayout","ViewGroup"],"TabWidget":["LinearLayout","ViewGroup"],"AbsSpinner":["AdapterView","ViewGroup"],"AdapterViewAnimator":["AdapterView","ViewGroup"],"AbsListView":["AdapterView","ViewGroup"],"MultiAutoCompleteTextView":["AutoCompleteTextView","EditText","TextView"],"CheckBox":["CompoundButton","Button","TextView"],"RadioButton":["CompoundButton","Button","TextView"],"Switch":["CompoundButton","Button","TextView"],"ToggleButton":["CompoundButton","Button","TextView"],"ViewSwitcher":["ViewAnimator","FrameLayout","ViewGroup"],"ViewFlipper":["ViewAnimator","FrameLayout","ViewGroup"],"Gallery":["AbsSpinner","AdapterView","ViewGroup"],"Spinner":["AbsSpinner","AdapterView","ViewGroup"],"AdapterViewFlipper":["AdapterViewAnimator","AdapterView","ViewGroup"],"StackView":["AdapterViewAnimator","AdapterView","ViewGroup"],"ListView":["AbsListView","AdapterView","ViewGroup"],"GridView":["AbsListView","AdapterView","ViewGroup"],"ImageSwitcher":["ViewSwitcher","ViewAnimator","FrameLayout","ViewGroup"],"TextSwitcher":["ViewSwitcher","ViewAnimator","FrameLayout","ViewGroup"],"ExpandableListView":["ListView","AbsListView","AdapterView","ViewGroup"]} ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/AttributeOptimizer.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import org.jetbrains.kotlin.android.attrs.NoAttr internal val attributeOptimizations = listOf( ::optimizeInclude, ::optimizeHelperConstructors ) internal fun optimizeInclude(name: String, attrs: List): Pair>? { val layout = attrs.firstOrNull { it.key == "layout" }?.value return if (name == "include" && layout != null) { val rendered = renderReference(NoAttr, "layout", layout) "$name(${rendered?.value ?: layout})" to attrs.filter { it.key != "layout" } } else null } internal fun optimizeHelperConstructors(name: String, attrs: List): Pair>? { val helpers = listOf( attrs.firstOrNull { it.key == "text" }, attrs.firstOrNull { it.key == "textResource" } ).filterNotNull() return if (helpers.isNotEmpty()) { val helper = helpers.first() "$name(${helper.value})" to attrs.filter { it.key != helper.key } } else null } ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/AttributeParser.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import org.jetbrains.kotlin.android.attrs.Attr import org.jetbrains.kotlin.android.attrs.NoAttr import java.util.regex.Pattern internal fun renderLayoutAttributes(attributes: List, parentName: String): String { val map = attributes.map { it.key.replace("android:layout_", "") to it.value }.toMap() fun renderLayoutDimension(s: String) = when { s == "wrap_content" -> "wrapContent" s == "match_parent" || s == "fill_parent" -> "matchParent" s.isDimension() -> { val dimension = s.parseDimension() "${dimension.second}(${dimension.first})" } else -> s } val width = renderLayoutDimension(map["width"] ?: "wrap_content") val height = renderLayoutDimension(map["height"] ?: "wrap_content") val options = (layoutAttributeRenderers.findFirst { it(parentName, map) } ?: emptyList()).filterNotNull() val optionsString = if (options.isNotEmpty()) { options.map { it.toString().indent(1) }.joinToString("\n", " {\n", "\n}") } else "" return ".lparams(width = $width, height = $height)$optionsString" } internal fun transformAttribute(widgetName: String, name: String, value: String): KeyValuePair? { return when { name.startsWith("xmlns:") -> null name.startsWith("tools:") -> null name == "style" -> null name.startsWith("android:") -> { val shortName = name.substring("android:".length) // Search for attribute in `widgetName` styleable, then in superclass styleables, // then in `View` styleable, then in free attributes val attr = attrs.free.firstOrNull { it.name == shortName } ?: attrs.styleables[widgetName]?.attrs?.firstOrNull { it.name == shortName } ?: viewHierarchy[widgetName]?.findFirst { attrs.styleables[it]?.attrs?.firstOrNull { it.name == shortName } } attrs.styleables["View"]?.attrs?.firstOrNull { it.name == shortName } return if (attr != null) { renderAttribute(attr, shortName, value) } else renderAttribute(NoAttr, shortName, value) } else -> name * value } } internal fun renderAttribute(attr: Attr, p: KeyValuePair) = renderAttribute(attr, p.key, p.value) private fun renderAttribute(attr: Attr, key: String, value: String): KeyValuePair? { for (renderer in viewAttributeRenderers) { val v = renderer(attr, key, value) if (v != null) return v } return null } fun String.parseReference(): XmlReference? { val matcher = Pattern.compile("@((([A-Za-z0-9._]+)\\:)?)([+A-Za-z0-9_]+)\\/([A-Za-z0-9_]+)").matcher(this) if (!matcher.matches()) { return null } return XmlReference(matcher.group(3) ?: "", matcher.group(4), matcher.group(5)) } fun String.parseFlagValue(): Int { return if (startsWith("0x")) Integer.parseInt(this.substring(2), 16) else this.toInt() } fun String.isReference(): Boolean { return startsWith("@") } fun String.isSpecialReferenceAttribute() = when (this) { "text" -> true "background" -> true else -> false } fun String.isDimension(): Boolean { return endsWith("sp") || endsWith("dp") || endsWith("px") || endsWith("dip") } fun String.isColor(): Boolean { return toLowerCase().matches("#[0-9a-f]+".toRegex()) } fun String.parseDimension(): Pair { val matcher = Pattern.compile("([0-9\\.]+)(dip|dp|px|sp)").matcher(this) if (!matcher.matches()) { throw RuntimeException("Invalid dimension: $this") } val numericValue = matcher.group(1) val dimensionUnit = matcher.group(2).let { if (it == "dp") "dip" else it } return (if ("." in numericValue) "${numericValue}f" else numericValue) to dimensionUnit } ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/ConvertAction.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import com.intellij.facet.FacetManager import com.intellij.ide.highlighter.XmlFileType import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.ui.ex.MessagesEx import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileVisitor import org.jetbrains.android.facet.AndroidFacet import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import java.io.File import java.io.IOException class ConvertAction : AnAction() { private class FileToConvert(val xmlFile: VirtualFile, val ktFile: File) override fun actionPerformed(e: AnActionEvent) { val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return val project = CommonDataKeys.PROJECT.getData(e.dataContext) ?: return val files = allFilesToConvert(virtualFiles, project) if (files.isEmpty()) return ApplicationManager.getApplication().runWriteAction { var lastConvertedFile: VirtualFile? = null for (file in files) { System.err.println("Converting file " + file.xmlFile.path) file.convert(project) lastConvertedFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file.ktFile) } if (lastConvertedFile != null) { FileEditorManager.getInstance(project).openFile(lastConvertedFile, true) } } } private fun VirtualFile.getFileToConvert(project: Project): FileToConvert? { if (fileType !is XmlFileType) return null if (!parent.name.startsWith("layout")) return null val androidFacet = resolveAndroidFacet(project) ?: return null val probResourceDirectory = parent?.parent?.path val resourceDirectories = androidFacet.allResourceDirectories if (!resourceDirectories.any { it.canonicalPath == probResourceDirectory }) return null val targetDirectory = getActivityDirectory(androidFacet) ?: getMainAndroidSourceRoot(androidFacet) val ktFileNameBase = nameWithoutExtension.firstCapital() var candidateKtFile = File(targetDirectory, ktFileNameBase + "LayoutActivity.kt") var counter = 0 while (candidateKtFile.exists()) { candidateKtFile = File(targetDirectory, ktFileNameBase + "LayoutActivity$counter.kt") counter++ } return FileToConvert(this, candidateKtFile) } private fun getActivityDirectory(androidFacet: AndroidFacet): String? { val manifest = androidFacet.manifest val appPackage = manifest?.`package`?.value val activities = manifest?.application?.activities if (appPackage == null || activities == null) return null val activityClasses = activities.map { it.activityClass.value } val activity = activityClasses .filter { it?.getKotlinFqName()?.asString()?.startsWith(appPackage) ?: false } .firstOrNull() return activity?.containingFile?.containingDirectory?.virtualFile?.canonicalPath } private fun getMainAndroidSourceRoot(androidFacet: AndroidFacet): String? { return ModuleRootManager.getInstance(androidFacet.module) .contentRoots.filter { !it.canonicalPath!!.endsWith("/gen") }.first().canonicalPath } override fun update(e: AnActionEvent) { e.presentation.isEnabled = selectedLayoutFiles(e).any() } private fun selectedLayoutFiles(e: AnActionEvent): List { val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return emptyList() val project = CommonDataKeys.PROJECT.getData(e.dataContext) ?: return emptyList() return allFilesToConvert(virtualFiles, project) } private fun allFilesToConvert(filesOrDirs: Array, project: Project): List { val result = arrayListOf() for (file in filesOrDirs) { VfsUtilCore.visitChildrenRecursively(file, object : VirtualFileVisitor() { override fun visitFile(file: VirtualFile): Boolean { val fileToConvert = file.getFileToConvert(project) if (fileToConvert != null) result.add(fileToConvert) return true } }) } return result } private fun VirtualFile.resolveAndroidFacet(project: Project): AndroidFacet? { return ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(this)?.resolveAndroidFacet() } private fun Module.resolveAndroidFacet(): AndroidFacet? { val facetManager = FacetManager.getInstance(this) for (facet in facetManager.allFacets) { if (facet is AndroidFacet) { return facet } } return null } private fun FileToConvert.convert(project: Project) { try { ktFile.writeText(XmlConverter.convert(xmlFile.contentsToByteArray().toString(charset("UTF-8")))) } catch (e: IOException) { MessagesEx.error(project, e.message).showLater() } } private fun String.firstCapital() = if (isEmpty()) "" else Character.toUpperCase(this[0]) + substring(1) } ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/LayoutAttributeRenderer.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import org.jetbrains.kotlin.android.attrs.NoAttr internal val layoutAttributeRenderers = listOf( ::linearLayoutRenderer, ::relativeLayoutRenderer ) internal fun linearLayoutRenderer(parentName: String, attrs: Map) = if (parentName == "LinearLayout") listOf( attrs.prop("gravity") { renderAttribute(NoAttr, it) }, attrs.prop("weight") ) + marginLayoutRenderer(parentName, attrs) else null internal fun relativeLayoutRenderer(parentName: String, attrs: Map) = if (parentName == "RelativeLayout") listOf( attrs.func("above") { renderReference(NoAttr, it.key, it.value) }, attrs.func("below") { renderReference(NoAttr, it.key, it.value) }, attrs.func("toRightOf") { renderReference(NoAttr, "toRightOf", it.value) }, attrs.func("toLeftOf") { renderReference(NoAttr, "toLeftOf", it.value) }, attrs.func("alignLeft") { renderReference(NoAttr, "sameLeft", it.value) }, attrs.func("alignTop") { renderReference(NoAttr, "sameTop", it.value) }, attrs.func("alignRight") { renderReference(NoAttr, "sameRight", it.value) }, attrs.func("alignBottom") { renderReference(NoAttr, "sameBottom", it.value) }, attrs.func("alignParentLeft") { "alignParentLeft" * "" }, attrs.func("alignParentTop") { "alignParentTop" * "" }, attrs.func("alignParentRight") { "alignParentRight" * "" }, attrs.func("alignParentBottom") { "alignParentBottom" * "" }, attrs.func("alignParentStart") { "alignParentStart" * "" }, attrs.func("alignParentEnd") { "alignParentEnd" * "" }, attrs.func("centerInParent") { "centerInParent" * "" }, attrs.func("centerHorizontal") { "centerHorizontally" * "" }, attrs.func("centerVertical") { "centerVertically" * "" } ) + marginLayoutRenderer(parentName, attrs) else null @Suppress("UNUSED_PARAMETER") internal fun marginLayoutRenderer(parentName: String, attrs: Map) = listOf("margin", "marginLeft", "marginTop", "marginRight", "marginBottom").map { attrs.prop(it) { renderDimension(NoAttr, it.key.swapCamelCase(), it.value) } } private fun Map.func(key: String, transformer: ((KeyValuePair) -> KeyValuePair?)? = null): KeyValuePair? { val value = get(key) return if (value != null) { if (transformer != null) { val result = transformer(key * value) return if (result != null) (result.key + "(" + result.value + ")") * "" else null } else "$key($value)" * "" } else null } private fun Map.prop(key: String, transformer: ((KeyValuePair) -> KeyValuePair?)? = null): KeyValuePair? { val value = get(key) return if (value != null) { if (transformer != null) transformer(key * value) else key * value } else null } ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/Util.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import com.google.gson.Gson import com.google.gson.reflect.TypeToken import org.jetbrains.kotlin.android.attrs.Attrs import org.jetbrains.kotlin.android.attrs.readResource private val INTENT = " " internal val attrs = Gson().fromJson(readResource("attrs.json"), Attrs::class.java) internal val viewHierarchy = Gson().fromJson>>(readResource("views.json"), (object : TypeToken>>() {}).type) internal data class KeyValuePair(val key: String, val value: String) { override fun toString() = if (value.isNotEmpty()) "$key = $value" else key } internal operator fun String.times(value: String) = KeyValuePair(this, value) internal fun List.findFirst(transformer: (T) -> R?): R? { for (item in this) { val r = transformer(item) if (r != null) return r } return null } internal fun String.indent(width: Int): String { if (isEmpty()) return this val intent = INTENT.repeat(width) return split('\n').map { intent + it }.joinToString("\n") } internal fun String.swapCamelCase(): String { val ch = withIndex().firstOrNull { Character.isUpperCase(it.value) } return if (ch == null) this else substring(ch.index).toLowerCase() + substring(0, ch.index).firstCapital() } internal fun String.firstCapital(): String = if (isEmpty()) this else Character.toUpperCase(this[0]) + substring(1) ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/ViewAttributeRenderer.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import org.jetbrains.kotlin.android.attrs.Attr import org.jetbrains.kotlin.android.attrs.NoAttr internal val viewAttributeRenderers = listOf( ::renderGravity, ::renderBackground, ::renderLinearLayoutOrientation, ::renderTextSize, ::renderTag, ::renderVisibility, ::renderSingleLine, ::renderOrientation, ::renderColor, ::renderReference, ::renderDimension, ::renderString, ::renderBoolean, ::renderInteger, ::renderFloat, ::renderEnum, ::renderFlags ) @Suppress("UNUSED_PARAMETER") internal fun renderGravity(attr: Attr, key: String, value: String) = if (key == "gravity") { val values = value.split('|').map { "Gravity.${it.toUpperCase()}" } key * values.joinToString(" or ") } else null @Suppress("UNUSED_PARAMETER") internal fun renderBackground(attr: Attr, key: String, value: String) = if (key == "background") { if (value.isReference()) renderReference(NoAttr, "${key}Resource", value) else if (value.isColor()) renderColor(NoAttr, "${key}Color", value) else null } else null internal fun renderLinearLayoutOrientation(attr: Attr, key: String, value: String) = if (key == "orientation" && attr.name == "LinearLayout") key * "android.widget.LinearLayout.${value.toUpperCase()}" else null @Suppress("UNUSED_PARAMETER") internal fun renderTextSize(attr: Attr, key: String, value: String) = if (key == "textSize") { val dimension = value.parseDimension() key * "${dimension.first}f" } else null @Suppress("UNUSED_PARAMETER") internal fun renderTag(attr: Attr, key: String, value: String) = if (key == "tag") { renderString(NoAttr, key, value) } else null @Suppress("UNUSED_PARAMETER") internal fun renderVisibility(attr: Attr, key: String, value: String) = if (key == "visibility") { "visibility" * "View.${value.toUpperCase()}" } else null @Suppress("UNUSED_PARAMETER") internal fun renderSingleLine(attr: Attr, key: String, value: String) = if (key == "singleLine") { "setSingleLine($value)" * "" } else null @Suppress("UNUSED_PARAMETER") internal fun renderOrientation(attr: Attr, key: String, value: String) = if (key == "orientation") { "orientation" * "LinearLayout.${value.toUpperCase()}" } else null internal fun renderBoolean(attr: Attr, key: String, value: String) = if (attr accepts "boolean" && (value == "true" || value == "false")) key * value else null internal fun renderInteger(attr: Attr, key: String, value: String) = if (attr accepts "integer" && value.matches("\\-?[0-9]+".toRegex())) key * value else null internal fun renderFloat(attr: Attr, key: String, value: String) = if (attr accepts "float") key * "${value}f" else null internal fun renderString(attr: Attr, key: String, value: String) = if (attr accepts "string") { if (value.isReference() && key.isSpecialReferenceAttribute()) renderReference(NoAttr, key + "Resource", value) else key * ("\"" + value.replace("\"", "\\\"") + "\"") } else null internal fun renderColor(attr: Attr, key: String, value: String) = if (attr accepts "color" && value.isColor()) { val color = value.replace("#", "").toLowerCase() val displayColor = if (color.length > 6 && !color.startsWith("ff")) "0x$color.toInt()" else "0x${color}.opaque" key * displayColor } else null internal fun renderReference(attr: Attr, key: String, value: String): KeyValuePair? { if (attr accepts "reference" && value.isReference()) { val reference = value.parseReference() ?: return null val packageName = if (reference.packageName.isNotEmpty()) "${reference.packageName}." else "" return when (reference.type) { "+id" -> key * "${packageName}Ids.${reference.value}" else -> key * "${packageName}R.${reference.type}.${reference.value}" } } else return null } internal fun renderEnum(attr: Attr, key: String, value: String) = if (attr accepts "enum" && attr.enum != null) { val enumEntry = attr.enum?.firstOrNull { it.name == value } if (enumEntry != null) key * enumEntry.value else key * value } else null internal fun renderFlags(attr: Attr, key: String, value: String) = if (attr accepts "flags" && attr.flags != null) { val sum = value.split('|').fold(0) { sum, flag -> val entry = attr.flags?.firstOrNull { it.name == flag } sum + (entry?.value?.parseFlagValue() ?: 0) } key * sum.toString() } else null internal fun renderDimension(attr: Attr, key: String, value: String) = if (attr accepts "dimension" && value.isDimension()) { val dimension = value.parseDimension() key * "${dimension.second}(${dimension.first})" } else null private infix fun Attr.accepts(f: String) = this == NoAttr || f in this.format ================================================ FILE: anko/idea-plugin/xml-converter/src/org/jetbrains/kotlin/android/xmlconverter/XmlConverter.kt ================================================ /* * Copyright 2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.kotlin.android.xmlconverter import org.w3c.dom.Document import org.w3c.dom.Element import org.xml.sax.InputSource import java.io.File import java.io.StringReader import java.util.* import javax.xml.parsers.DocumentBuilderFactory import kotlinx.dom.childElements private class Widget(val name: String, val attrs: List, val layoutParams: String, val children: List) { override fun toString(): String { fun KeyValuePair.render() = if (value.isNotEmpty()) "$key = $value" else key val attributes = attrs.map { it.render() }.joinToString("\n").indent(1) val childrenRendered = children.map { it.toString() }.joinToString("\n").indent(1) return if (attributes.isEmpty() && childrenRendered.isEmpty()) { "$name$layoutParams" } else { val beforeChildren = if (attributes.isNotEmpty() && childrenRendered.isNotEmpty()) "\n\n" else "" "$name {\n$attributes$beforeChildren$childrenRendered\n}$layoutParams" } } } class XmlReference(val packageName: String, val type: String, val value: String) object XmlConverter { fun convert(xml: String, options: Set = emptySet()): String { val layout = xml.parseXml() val root = layout.documentElement val ids = TreeSet() val widget = parseView(root, null, ids) if ("raw" in options) return widget.toString() val imports = listOf( "android.app.*", "android.view.*", "android.widget.*", "org.jetbrains.anko.*", "android.os.Bundle" ) val idsToProcess = ids.filter { it.startsWith("Ids.") } val idsObject = if (idsToProcess.isNotEmpty()) { "private object Ids {\n" + idsToProcess.withIndex().map { "val " + it.value.replace("Ids.", "") + " = " + (it.index + 1) }.joinToString("\n").indent(1) + "\n}" } else "" return imports.map { "import $it" }.joinToString("\n", postfix = "\n\n") + "class SomeActivity : Activity() {\n" + " override fun onCreate(savedInstanceState: Bundle?) {\n" + " super.onCreate(savedInstanceState)\n\n" + widget.toString().indent(2) + "\n }\n\n" + idsObject.indent(1) + "\n}" } private fun parseView(widget: Element, parentName: String?, idsCollector: SortedSet): Widget { val name = widget.tagName val displayName = Character.toLowerCase(name[0]) + name.substring(1) val (attributes, layoutParams) = widget.getWidgetAttributes(name, parentName) val children = widget.childElements().map { parseView(it, name, idsCollector) } val (optimizedName, optimizedAttributes) = applyAttributeOptimizations(displayName, attributes) optimizedAttributes.firstOrNull { it.key == "id" }?.let { idsCollector.add(it.value) } return Widget(optimizedName, optimizedAttributes, layoutParams, children) } private fun applyAttributeOptimizations(displayName: String, attributes: List): Pair> { var last = displayName to attributes for (optimization in attributeOptimizations) { val f = optimization(last.first, last.second) if (f != null) last = f } return last } private fun Element.getWidgetAttributes(name: String, parentName: String?): Pair, String> { val original = arrayListOf() val attributesNodeMap = attributes for (i in 0..(attributesNodeMap.length - 1)) { val attribute = attributesNodeMap.item(i) original.add(attribute.nodeName * attribute.nodeValue) } val (layoutAttributes, ordinaryAttributes) = original.partition { it.key.startsWith("android:layout_") } val layoutParams = if (parentName != null) renderLayoutAttributes(layoutAttributes, parentName) else "" return ordinaryAttributes.map { transformAttribute(name, it.key, it.value) }.filterNotNull() to layoutParams } } fun main(args: Array) { if (args.size < 2) { println("Usage: ") return } val xmlFile = File(args[0]) val ktFile = File(args[1]) val options = if (args.size > 2) args[2].split(',').toSet() else emptySet() if (!xmlFile.exists()) { println("$xmlFile does not exist. Aborting") return } val kt = XmlConverter.convert(xmlFile.readText(), options) ktFile.writeText(kt) println(kt) } private fun String.parseXml(): Document { val factory = DocumentBuilderFactory.newInstance() val builder = factory.newDocumentBuilder() val inputSource = InputSource(StringReader(this)) return builder.parse(inputSource) } ================================================ FILE: anko/idea-plugin/xml-converter/test/org/jetbrains/kotlin/android/xmlconverter/BaseXmlConverterTest.java ================================================ package org.jetbrains.kotlin.android.xmlconverter; import static kotlin.collections.SetsKt.setOf; import static kotlin.io.FilesKt.readText; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import kotlin.text.Charsets; import org.junit.Rule; import org.junit.rules.TestName; public class BaseXmlConverterTest { @Rule public TestName name = new TestName(); protected void doLayoutTest() { File testDataDir = new File("testData"); String testName = name.getMethodName(); if (!testName.startsWith("test")) { throw new IllegalStateException("Test name must start with a 'test' preffix"); } File testDir = new File(testDataDir, decapitalize(testName.substring("test".length()))); File inputFile = new File(testDir, "layout.xml"); File outputFile = new File(testDir, "layout.kt"); assertTrue(inputFile + " does not exist", inputFile.exists()); assertTrue(outputFile + " does not exist", outputFile.exists()); String actual = XmlConverter.INSTANCE.convert(readText(inputFile, Charsets.UTF_8), setOf("raw")); String expected = readText(outputFile, Charsets.UTF_8); assertEquals(expected, actual); } private String decapitalize(String original) { if (original.isEmpty()) return original; return Character.toLowerCase(original.charAt(0)) + original.substring(1); } } ================================================ FILE: anko/idea-plugin/xml-converter/test/org/jetbrains/kotlin/android/xmlconverter/XmlConverterTest.kt ================================================ package org.jetbrains.kotlin.android.xmlconverter import org.junit.Test class XmlConverterTest : BaseXmlConverterTest() { @Test fun testSimple() = doLayoutTest() @Test fun testLinearLayout() = doLayoutTest() @Test fun testRelativeLayout() = doLayoutTest() @Test fun testDimensions() = doLayoutTest() @Test fun testAttributes() = doLayoutTest() } ================================================ FILE: anko/idea-plugin/xml-converter/testData/attributes/layout.kt ================================================ frameLayout { textView("Text") { backgroundColor = 0xff0000.opaque enabled = false hint = "Hint" id = Ids.textView1 lines = 5 paddingBottom = dip(4) paddingLeft = dip(1) paddingRight = dip(3) paddingTop = dip(2) tag = "Tag" textColor = 0x00ff00.opaque textSize = 17f visibility = View.INVISIBLE }.lparams(width = wrapContent, height = wrapContent) textView { backgroundColor = 0xeeffff00.toInt() textSize = 17f }.lparams(width = wrapContent, height = wrapContent) textView { backgroundResource = android.R.color.background_light textSize = 17f }.lparams(width = wrapContent, height = wrapContent) } ================================================ FILE: anko/idea-plugin/xml-converter/testData/attributes/layout.xml ================================================ ================================================ FILE: anko/idea-plugin/xml-converter/testData/dimensions/layout.kt ================================================ linearLayout { button.lparams(width = wrapContent, height = wrapContent) { leftMargin = dip(0.5f) topMargin = dip(1) rightMargin = sp(2) bottomMargin = px(3) } button.lparams(width = wrapContent, height = wrapContent) } ================================================ FILE: anko/idea-plugin/xml-converter/testData/dimensions/layout.xml ================================================